Merge pull request #14 from advanced-security/multi-module

Multi module support, maven wrapper support, improvements in matching and reporting the source file for the dependencies in the repository and dependency graph
This commit is contained in:
Peter Murray
2023-02-22 17:26:14 +00:00
committed by GitHub
41 changed files with 4258 additions and 3995 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ echo -x
JDK_VERSION="18.0.2.1"
JDK_INSTALLER="/tmp/openjdk.tar.gz"
MVN_VERSION="3.8.6"
MVN_VERSION="3.9.0"
MVN_INSTALLER="/tmp/mvn.tar.gz"
wget https://download.java.net/java/GA/jdk${JDK_VERSION}/db379da656dc47308e138f21b33976fa/1/GPL/openjdk-${JDK_VERSION}_linux-x64_bin.tar.gz -O ${JDK_INSTALLER}
+24
View File
@@ -0,0 +1,24 @@
name: Publish Executables
on:
workflow_dispatch:
push:
jobs:
publish:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Build executables
run: |
npm run base-build
npm run build-exe
- name: Attach artifacts
uses: actions/upload-artifact@v3
with:
name: executables
path: cli/*
+2 -1
View File
@@ -3,4 +3,5 @@ lib
node_modules
target
runtime
runtime
cli
-18
View File
@@ -4,23 +4,5 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
<<<<<<< HEAD
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/node_modules/.bin/mocha",
"args": [
"-r",
"ts-node/register",
"--colors",
"${workspaceFolder}/src/depgraph.test.ts"
],
}
=======
>>>>>>> 4b5ca60 (Initial commit)
]
}
+2 -26
View File
@@ -1,26 +1,4 @@
{
<<<<<<< HEAD
"debug.onTaskErrors": "showErrors",
"files.trimTrailingWhitespace": true,
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.detectIndentation": false,
"[javascript]": {
"editor.tabSize": 2
},
"[json]": {
"editor.tabSize": 2
},
"[yaml]": {
"editor.tabSize": 2
},
"[html]": {
"editor.tabSize": 2
},
// GitHub Codespace Theme
"workbench.colorTheme": "GitHub Dark Dimmed"
}
=======
"debug.onTaskErrors": "showErrors",
"files.trimTrailingWhitespace": true,
"editor.tabSize": 2,
@@ -41,8 +19,6 @@
// GitHub Codespace Theme
"workbench.colorTheme": "GitHub Dark Dimmed",
"jest.autoRun": {
"watch": false,
"onSave": "test-file"
"watch": false
}
}
>>>>>>> 4b5ca60 (Initial commit)
}
+21 -9
View File
@@ -2,15 +2,21 @@
This is a GitHub Action that will generate a complete dependency graph for a Maven project and submit the graph to the GitHub repository so that the graph is complete and includes all the transitive dependencies.
The action will invoke maven using the `com.github.ferstl:depgraph-maven-plugin:4.0.1` plugin to generate JSON output of the complete dependency graph, which is then processed and submitted using the [Dependency Submission Toolkit](https://github.com/github/dependency-submission-toolkit) to the GitHub repository.
The action will invoke maven using the `com.github.ferstl:depgraph-maven-plugin:4.0.2` plugin to generate JSON output of the complete dependency graph, which is then processed and submitted using the [Dependency Submission Toolkit](https://github.com/github/dependency-submission-toolkit) to the GitHub repository.
> **Warning** The dependency submission APIs and toolkit are still currently in beta and as such subject to changes in future releases.
## Usage
As of version `3.0.0` this action now support Maven multi-module projects as well as additional Maven configuration parameters.
### Pre-requisites
For this action to work properly, you must have the Maven available on PATH (`mvn`) and configured to be able to access and pull your dependencies from whatever sources you have defined (i.e. a properly configured settings.xml or all details provided in the POM).
For this action to work properly, you must have the Maven available on PATH (`mvn`) or using a `mvnw` Maven wrapper in your maven project directory. Maven will need to be configured to be able to access and pull your dependencies from whatever sources you have defined (i.e. a properly configured `settings.xml` or all details provided in the POM).
Custom maven `settings.xml` can now be specified as an input parameter to the action.
### Inputs
@@ -18,6 +24,16 @@ For this action to work properly, you must have the Maven available on PATH (`mv
* `token` - The GitHub token that will be used to submit the generated dependency snapshot to the repository. Defaults to the `github.token` from the actions environment.
* `settings-file` - An optional path to a Maven settings.xml file that you want to use to provide additional configuration to Maven.
* `ingore-maven-wrapper` - An optional `true`/`false` flag parameter to ignore the Maven wrapper (if present) in the maven project directory and instead use the version of Maven from the `PATH`. This is set to `false` by default to use the wrapper if one is present.
* `maven-args` - An optional string value (space separated) options to pass to the maven command line when generating the dependency snapshot. This is empty by default.
* `snapshot-include-file-name`: Optional flag to control whether or no the path and file name of the pom.xml is provided with the snapshot submission. Defaults to `true` so as to create a link to the repository file from the dependency tree view, but at the cost of losing the POM `artifactId` when it renders.
* `snapshot-dependency-file-name`: An optional user control file path to the POM file, requires `snapshot-include-file-name` to be `true` for the value to be submitted.
## Examples
@@ -25,23 +41,19 @@ Generating and submitting a dependency snapshot using the defaults:
```
- name: Submit Dependency Snapshot
uses: advanced-security/maven-dependency-submission-action@v1
uses: advanced-security/maven-dependency-submission-action@v3
```
Upon success it will generate a snapshot captured from Maven POM like;
![Screenshot 2022-08-15 at 09 33 47](https://user-images.githubusercontent.com/681306/184603264-3cd69fda-75ff-4a46-b014-630acab60fab.png)
## Limitations
Currently the action is limited to single module Maven projects, with a future update that will add support for multi-module based projects.
## Command Line Usage
There are experimental command line clients, Linux only for now that will provide the same functionality as the GitHub Action but can be embedded into your existing CI tooling and invoked from the commandline to upload a dpendency snapshot.
There are experimental command line clients, Linux only for now that will provide the same functionality as the GitHub Action but can be embedded into your existing CI tooling and invoked from the commandline to upload a dependency snapshot.
You can obtain the executables from the [cli](./cli) directory of the repository for now.
You can obtain the executables from the latest actions workflow run https://github.com/advanced-security/maven-dependency-submission-action/actions/workflows/publish_executables.yml.
### Parameters
+24
View File
@@ -11,6 +11,30 @@ inputs:
type: string
default: ${{ github.workspace }}
settings-file:
description: Optional path to a Maven settings.xml file for the dependencies to be resolved
type: string
ignore-maven-wrapper:
description: Flag for optionally ignoring any maven wrapper files (mvnw) and instead rely on the PATH provided mvn
type: boolean
default: false
maven-args:
description: Additional maven arguments to add to the command line invocation of maven when it generates the dependency snapshot
type: string
default: ''
snapshot-include-file-name:
description: Optionally include the file name in the dependency snapshot report to GitHub. This is required to be true if you want the results in the dependency tree to have a working link.
type: boolean
default: true
snapshot-dependency-file-name:
description: An optional override to specify the path to the file in the repository that the snapshot should be associated with.
type: string
required: false
token:
description: The GitHub token to use to submit the depedency snapshot to the repository
type: string
Binary file not shown.
+424 -111
View File
@@ -2,41 +2,16 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 8047:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.artifactToPackageURL = exports.parseDependencyJson = exports.MavenDependencyGraph = void 0;
const fs = __importStar(__nccwpck_require__(7147));
const packageurl_js_1 = __nccwpck_require__(8915);
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
const file_utils_1 = __nccwpck_require__(799);
class MavenDependencyGraph {
// //@ ts-ignore
// private rootPackage: DepgraphArtifact;
constructor(graph) {
this.depGraph = graph;
this.cache = new dependency_submission_toolkit_1.PackageCache();
@@ -60,9 +35,13 @@ class MavenDependencyGraph {
return this.cache.countPackages();
}
createManifest(filePath) {
// The project name is not shown in the UI when you utilize a file path currently, but the file path is required to link up to the repository file
// which is more beneficial at this point.
const manifest = new dependency_submission_toolkit_1.Manifest(this.getProjectName(), filePath);
let manifest;
if (filePath) {
manifest = new dependency_submission_toolkit_1.Manifest(this.getProjectName(), filePath);
}
else {
manifest = new dependency_submission_toolkit_1.Manifest(this.getProjectName());
}
const packageUrlToArtifact = this.packageUrlToArtifact;
this.directDependencies.forEach(depPackage => {
const artifact = this.packageUrlToArtifact[depPackage.packageURL.toString()];
@@ -85,9 +64,10 @@ class MavenDependencyGraph {
parseDependencies() {
const graph = this.depGraph;
const cache = this.cache;
const rootPackageArtifactId = graph.graphName;
let rootPackageNumericId = 0;
const dependencyIdMap = dependencyMap(graph.dependencies);
const dependencies = graph.dependencies || [];
const rootArtifactIds = [];
const dependencyIdMap = dependencyMap(dependencies);
const dependencyArtifactIdsWithParents = extractDependencyArtifactIdsWithParents(dependencies);
const idToPackageCachePackage = new Map();
// Create the packages for all known artifacts
graph.artifacts.forEach((artifact) => {
@@ -96,8 +76,8 @@ class MavenDependencyGraph {
idToPackageCachePackage[artifact.id] = pkg;
// Store a reference from the package URL to the original artifact as the artifact has extra metadata we need later for scopes and optionality
this.packageUrlToArtifact[artifactUrl.toString()] = artifact;
if (artifact.artifactId === rootPackageArtifactId) {
rootPackageNumericId = artifact.numericId - 1;
if (dependencyArtifactIdsWithParents.indexOf(artifact.id) === -1) {
rootArtifactIds.push(artifact.id);
}
});
// Now that all packages are known, process the dependencies for each and link them
@@ -118,30 +98,62 @@ class MavenDependencyGraph {
});
}
});
this.directDependencies = getDirectDependencies(rootPackageNumericId, graph.dependencies).map(id => { return idToPackageCachePackage[id]; });
const uniqueRootArtifactDependencies = [];
rootArtifactIds.forEach(rootArtifactId => {
const dependencyIds = getDirectDependencies(rootArtifactId, dependencies);
if (dependencyIds) {
dependencyIds.forEach(dependencyId => {
if (uniqueRootArtifactDependencies.indexOf(dependencyId) === -1) {
uniqueRootArtifactDependencies.push(dependencyId);
}
});
}
});
this.directDependencies = uniqueRootArtifactDependencies.map(depId => idToPackageCachePackage[depId]);
}
}
exports.MavenDependencyGraph = MavenDependencyGraph;
function parseDependencyJson(file) {
function parseDependencyJson(file, isMultiModule = false) {
const data = (0, file_utils_1.loadFileContents)(file);
if (!data) {
return {
graphName: 'empty',
artifacts: [],
dependencies: [],
isMultiModule: isMultiModule
};
}
try {
const data = fs.readFileSync(file);
try {
const depGraph = JSON.parse(data.toString('utf-8'));
return depGraph;
}
catch (err) {
throw new Error(`Failed to parse JSON payload: ${err.message}`);
}
const depGraph = JSON.parse(data);
depGraph.isMultiModule = isMultiModule;
return depGraph;
}
catch (err) {
throw new Error(`Failed to load file ${file}: ${err}`);
throw new Error(`Failed to parse JSON dependency data: ${err.message}`);
}
}
exports.parseDependencyJson = parseDependencyJson;
function artifactToPackageURL(artifact) {
return new packageurl_js_1.PackageURL('maven', artifact.groupId, artifact.artifactId, artifact.version, undefined, undefined);
const qualifiers = getArtifactQualifiers(artifact);
return new packageurl_js_1.PackageURL('maven', artifact.groupId, artifact.artifactId, artifact.version, qualifiers, undefined);
}
exports.artifactToPackageURL = artifactToPackageURL;
function getArtifactQualifiers(artifact) {
let qualifiers = undefined;
if (artifact.types && artifact.types.length > 0) {
if (!qualifiers) {
qualifiers = {};
}
qualifiers['type'] = artifact.types[0];
}
if (artifact.classifiers && artifact.classifiers.length > 0) {
if (!qualifiers) {
qualifiers = {};
}
qualifiers['classifier'] = artifact.classifiers[0];
}
return qualifiers;
}
function getDependencyScopeForMavenScope(mavenScopes) {
// Once the API scopes are improved and expanded we should be able to perform better mapping here from Maven to cater for
// provided, runtime, compile, test, system, etc... in the future.
@@ -153,21 +165,29 @@ function getDependencyScopeForMavenScope(mavenScopes) {
// The default scope for now as we only have runtime and development currently
return 'runtime';
}
function extractDependencyArtifactIdsWithParents(dependencies) {
if (dependencies) {
return dependencies.map(dependency => { return dependency.to; });
}
return [];
}
function dependencyMap(dependencies) {
const map = new Map();
dependencies.forEach(dependency => {
const fromUrl = dependency.from;
let deps = map[fromUrl];
if (!deps) {
deps = [];
map[fromUrl] = deps;
}
deps.push(dependency.to);
});
if (dependencies) {
dependencies.forEach(dependency => {
const fromUrl = dependency.from;
let deps = map[fromUrl];
if (!deps) {
deps = [];
map[fromUrl] = deps;
}
deps.push(dependency.to);
});
}
return map;
}
function getDirectDependencies(rootPackageNumericId, dependencies) {
const topLevel = dependencies.filter(dependency => { return dependency.numericFrom === rootPackageNumericId; });
function getDirectDependencies(artifactId, dependencies) {
const topLevel = dependencies.filter(dependency => { return dependency.from === artifactId; });
return topLevel.map(dep => { return dep.to; });
}
//# sourceMappingURL=depgraph.js.map
@@ -220,7 +240,14 @@ function run() {
let snapshot;
try {
const directory = core.getInput('directory', { required: true });
snapshot = yield (0, snapshot_generator_1.generateSnapshot)(directory);
const mavenConfig = {
ignoreMavenWrapper: core.getBooleanInput('ignore-maven-wrapper'),
settingsFile: core.getInput('settings-file'),
mavenArgs: core.getInput('maven-args') || '',
};
const includeFilename = core.getBooleanInput('snapshot-include-file-name');
const manifestFilename = core.getInput('snapshot-dependency-file-name');
snapshot = yield (0, snapshot_generator_1.generateSnapshot)(directory, mavenConfig, { includeManifestFile: includeFilename, manifestFile: manifestFilename });
}
catch (err) {
core.error(err);
@@ -241,6 +268,160 @@ run();
/***/ }),
/***/ 7433:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.MavenRunner = void 0;
const exec = __importStar(__nccwpck_require__(1514));
const core = __importStar(__nccwpck_require__(2186));
const path = __importStar(__nccwpck_require__(1017));
const file_utils_1 = __nccwpck_require__(799);
class MavenRunner {
constructor(directory, settingsFile, ingoreWrapper = false, mavenArguments = '') {
this.mavenExecutable = resolveMavenExecutable(directory, ingoreWrapper);
if (settingsFile) {
if ((0, file_utils_1.fileExists)(settingsFile)) {
this.settings = settingsFile;
}
else {
throw new Error(`The specified settings file '${settingsFile}' does not exist`);
}
}
this.additionalArguments = [];
if (mavenArguments.trim().length > 0) {
this.additionalArguments = mavenArguments.trim().split(' ');
}
}
get configuration() {
return {
executable: this.mavenExecutable,
settingsFile: this.settings
};
}
exec(cwd, parameters) {
return __awaiter(this, void 0, void 0, function* () {
const commandArgs = [];
// implictly run in batch mode, might need to make this configurable in the future
commandArgs.push('-B');
if (this.settings) {
commandArgs.push('--settings');
commandArgs.push(this.settings);
}
// Only append the additional arguments they are not empty values
if (this.additionalArguments && this.additionalArguments.length > 0) {
this.additionalArguments.forEach(arg => {
if (arg.trim().length > 0) {
commandArgs.push(arg);
}
});
}
Array.prototype.push.apply(commandArgs, parameters);
let executionOutput = '';
let executionErrors = '';
const options = {
cwd: cwd,
listeners: {
stdout: (data) => {
executionOutput += data.toString();
},
stderr: (data) => {
executionErrors += data.toString();
}
}
};
try {
const exitCode = yield exec.exec(this.mavenExecutable, commandArgs, options);
return {
stdout: executionOutput,
stderr: executionErrors,
exitCode: exitCode
};
}
catch (err) {
//TODO possibly throw a wrapped error here
core.warning(`Error encountered executing maven: ${err.message}`);
return {
stdout: executionOutput,
stderr: executionErrors,
exitCode: -1
};
}
});
}
}
exports.MavenRunner = MavenRunner;
function resolveMavenExecutable(directory, ignoreWrapper = false) {
if (ignoreWrapper) {
return getMavenExecutable();
}
const wrapper = getMavenWrapper(directory);
// Return the matche maven wrapper script or otherwise fall back to mvn on the path
return wrapper || getMavenExecutable();
}
function getMavenWrapper(directory) {
if (!directory) {
return undefined;
}
const mavenWrapperFilename = path.join(directory, getMavenWrapperExecutable());
if ((0, file_utils_1.fileExists)(mavenWrapperFilename)) {
return mavenWrapperFilename;
}
return undefined;
}
function getMavenWrapperExecutable() {
if (isWindows()) {
return 'mvnw.cmd';
}
return 'mvnw';
}
function getMavenExecutable() {
if (isWindows()) {
return 'mvn.cmd';
}
return 'mvn';
}
function isWindows() {
return process.platform === 'win32';
}
//# sourceMappingURL=maven-runner.js.map
/***/ }),
/***/ 2963:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@@ -280,19 +461,35 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.generateDependencyGraph = exports.generateSnapshot = void 0;
const exec = __importStar(__nccwpck_require__(1514));
const core = __importStar(__nccwpck_require__(2186));
const path = __importStar(__nccwpck_require__(1017));
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
const depgraph_1 = __nccwpck_require__(8047);
const maven_runner_1 = __nccwpck_require__(7433);
const file_utils_1 = __nccwpck_require__(799);
const version = (__nccwpck_require__(2876)/* .version */ .i8);
function generateSnapshot(directory, context, job) {
const DEPGRAPH_MAVEN_PLUGIN_VERSION = '4.0.2';
function generateSnapshot(directory, mvnConfig, snapshotConfig) {
return __awaiter(this, void 0, void 0, function* () {
const depgraph = yield generateDependencyGraph(directory);
const depgraph = yield generateDependencyGraph(directory, mvnConfig);
try {
const mavenDependencies = new depgraph_1.MavenDependencyGraph(depgraph);
const manifest = mavenDependencies.createManifest(path.join(directory, 'pom.xml'));
const snapshot = new dependency_submission_toolkit_1.Snapshot(getDetector(), context, job);
let manifest;
if (snapshotConfig === null || snapshotConfig === void 0 ? void 0 : snapshotConfig.includeManifestFile) {
let pomFile;
if (snapshotConfig === null || snapshotConfig === void 0 ? void 0 : snapshotConfig.manifestFile) {
pomFile = snapshotConfig.manifestFile;
}
else {
// The filepath to the POM needs to be relative to the root of the GitHub repository for the links to work once uploaded
pomFile = getRepositoryRelativePath(path.join(directory, 'pom.xml'));
}
manifest = mavenDependencies.createManifest(pomFile);
}
else {
manifest = mavenDependencies.createManifest();
}
const snapshot = new dependency_submission_toolkit_1.Snapshot(getDetector(), snapshotConfig === null || snapshotConfig === void 0 ? void 0 : snapshotConfig.context, snapshotConfig === null || snapshotConfig === void 0 ? void 0 : snapshotConfig.job);
snapshot.addManifest(manifest);
return snapshot;
}
@@ -310,53 +507,154 @@ function getDetector() {
version: version
};
}
function generateDependencyGraph(directory) {
function generateDependencyGraph(directory, config) {
return __awaiter(this, void 0, void 0, function* () {
try {
let executionOutput = '';
let errors = '';
const options = {
cwd: directory,
listeners: {
stdout: (data) => {
executionOutput += data.toString();
},
stderr: (data) => {
errors += data.toString();
}
}
};
const mavenArguments = [
'com.github.ferstl:depgraph-maven-plugin:4.0.1:graph',
const mvn = new maven_runner_1.MavenRunner(directory, config === null || config === void 0 ? void 0 : config.settingsFile, config === null || config === void 0 ? void 0 : config.ignoreMavenWrapper);
core.startGroup('depgraph-maven-plugin:reactor');
const mavenReactorArguments = [
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:reactor`,
'-DgraphFormat=json',
'-DoutputFileName=reactor.json'
];
core.startGroup('depgraph-maven-plugin');
yield exec.exec('mvn', mavenArguments, options);
core.info(executionOutput);
core.info(errors);
const reactorResults = yield mvn.exec(directory, mavenReactorArguments);
core.info(reactorResults.stdout);
core.info(reactorResults.stderr);
core.endGroup();
if (reactorResults.exitCode !== 0) {
throw new Error(`Failed to successfully generate reactor results with Maven, exit code: ${reactorResults.exitCode}`);
}
core.startGroup('depgraph-maven-plugin:aggregate');
const mavenAggregateArguments = [
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:aggregate`,
'-DgraphFormat=json',
'-DoutputFileName=aggregate-depgraph.json'
];
const aggregateResults = yield mvn.exec(directory, mavenAggregateArguments);
core.info(aggregateResults.stdout);
core.info(aggregateResults.stderr);
core.endGroup();
if (aggregateResults.exitCode !== 0) {
throw new Error(`Failed to successfully dependency results with Maven, exit code: ${aggregateResults.exitCode}`);
}
}
catch (err) {
core.error(err);
throw new Error(`A problem was encountered generating dependency files, please check execution logs for details; ${err.message}`);
}
//TODO need to account for multi module projects
// Now we have the target/dependency-graph.json file to process
const file = path.join(directory, 'target', 'dependency-graph.json');
const targetPath = path.join(directory, 'target');
const isMultiModule = checkForMultiModule(path.join(targetPath, 'reactor.json'));
// Now we have the aggregate dependency graph file to process
const aggregateGraphFile = path.join(targetPath, 'aggregate-depgraph.json');
try {
return (0, depgraph_1.parseDependencyJson)(file);
return (0, depgraph_1.parseDependencyJson)(aggregateGraphFile, isMultiModule);
}
catch (err) {
core.error(err);
throw new Error(`Could not parse maven dependency file, '${file}': ${err.message}`);
throw new Error(`Could not parse maven dependency file, '${aggregateGraphFile}': ${err.message}`);
}
});
}
exports.generateDependencyGraph = generateDependencyGraph;
function checkForMultiModule(reactorJsonFile) {
const data = (0, file_utils_1.loadFileContents)(reactorJsonFile);
if (data) {
try {
const reactor = JSON.parse(data);
// The reactor file will have an array of artifacts making up the parent and child modules if it is a multi module project
return reactor.artifacts && reactor.artifacts.length > 0;
}
catch (err) {
throw new Error(`Failed to parse reactor JSON payload: ${err.message}`);
}
}
// If no data report that it is not a multi module project
return false;
}
// TODO this is assuming the checkout was made into the base path of the workspace...
function getRepositoryRelativePath(file) {
const workspaceDirectory = path.resolve(process.env.GITHUB_WORKSPACE || '.');
const fileResolved = path.resolve(file);
const fileDirectory = path.dirname(fileResolved);
core.debug(`Workspace directory = ${workspaceDirectory}`);
core.debug(`Snapshot file = ${fileResolved}`);
core.debug(`Snapshot directory = ${fileDirectory}`);
let result = fileResolved;
if (fileDirectory.startsWith(workspaceDirectory)) {
result = fileResolved.substring(workspaceDirectory.length + path.sep.length);
}
core.debug(`Snapshot relative file = ${result}`);
return result;
}
//# sourceMappingURL=snapshot-generator.js.map
/***/ }),
/***/ 799:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fileExists = exports.loadFileContents = void 0;
const fs = __importStar(__nccwpck_require__(7147));
function loadFileContents(file) {
if (!fileExists(file)) {
return undefined;
}
try {
const data = fs.readFileSync(file);
return data.toString('utf8');
}
catch (err) {
throw new Error(`Failed to load file contents ${file}: ${err}`);
}
}
exports.loadFileContents = loadFileContents;
function fileExists(file) {
if (!file) {
return false;
}
try {
const wrapperFileStats = fs.statSync(file);
// TODO might need to deal with a linked file, but ingoring that for now
return wrapperFileStats && wrapperFileStats.isFile();
}
catch (err) {
if (err.code == 'ENOENT') {
return false;
}
throw err;
}
}
exports.fileExists = fileExists;
//# sourceMappingURL=file-utils.js.map
/***/ }),
/***/ 7351:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
@@ -4031,7 +4329,6 @@ const file_command_1 = __nccwpck_require2_(717);
const utils_1 = __nccwpck_require2_(5278);
const os = __importStar(__nccwpck_require2_(2087));
const path = __importStar(__nccwpck_require2_(5622));
const uuid_1 = __nccwpck_require2_(5840);
const oidc_utils_1 = __nccwpck_require2_(8041);
/**
* The code to exit an action
@@ -4061,20 +4358,9 @@ function exportVariable(name, val) {
process.env[name] = convertedVal;
const filePath = process.env['GITHUB_ENV'] || '';
if (filePath) {
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
// These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter.
if (name.includes(delimiter)) {
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
}
if (convertedVal.includes(delimiter)) {
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
}
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
file_command_1.issueCommand('ENV', commandValue);
}
else {
command_1.issueCommand('set-env', { name }, convertedVal);
return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val));
}
command_1.issueCommand('set-env', { name }, convertedVal);
}
exports.exportVariable = exportVariable;
/**
@@ -4092,7 +4378,7 @@ exports.setSecret = setSecret;
function addPath(inputPath) {
const filePath = process.env['GITHUB_PATH'] || '';
if (filePath) {
file_command_1.issueCommand('PATH', inputPath);
file_command_1.issueFileCommand('PATH', inputPath);
}
else {
command_1.issueCommand('add-path', {}, inputPath);
@@ -4132,7 +4418,10 @@ function getMultilineInput(name, options) {
const inputs = getInput(name, options)
.split('\n')
.filter(x => x !== '');
return inputs;
if (options && options.trimWhitespace === false) {
return inputs;
}
return inputs.map(input => input.trim());
}
exports.getMultilineInput = getMultilineInput;
/**
@@ -4165,8 +4454,12 @@ exports.getBooleanInput = getBooleanInput;
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setOutput(name, value) {
const filePath = process.env['GITHUB_OUTPUT'] || '';
if (filePath) {
return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value));
}
process.stdout.write(os.EOL);
command_1.issueCommand('set-output', { name }, value);
command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value));
}
exports.setOutput = setOutput;
/**
@@ -4295,7 +4588,11 @@ exports.group = group;
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function saveState(name, value) {
command_1.issueCommand('save-state', { name }, value);
const filePath = process.env['GITHUB_STATE'] || '';
if (filePath) {
return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value));
}
command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value));
}
exports.saveState = saveState;
/**
@@ -4361,13 +4658,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.issueCommand = void 0;
exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
// We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */
const fs = __importStar(__nccwpck_require2_(5747));
const os = __importStar(__nccwpck_require2_(2087));
const uuid_1 = __nccwpck_require2_(5840);
const utils_1 = __nccwpck_require2_(5278);
function issueCommand(command, message) {
function issueFileCommand(command, message) {
const filePath = process.env[`GITHUB_${command}`];
if (!filePath) {
throw new Error(`Unable to find environment variable for file command ${command}`);
@@ -4379,7 +4677,22 @@ function issueCommand(command, message) {
encoding: 'utf8'
});
}
exports.issueCommand = issueCommand;
exports.issueFileCommand = issueFileCommand;
function prepareKeyValueMessage(key, value) {
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
const convertedValue = utils_1.toCommandValue(value);
// These should realistically never happen, but just in case someone finds a
// way to exploit uuid generation let's not allow keys or values that contain
// the delimiter.
if (key.includes(delimiter)) {
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
}
if (convertedValue.includes(delimiter)) {
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
}
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
}
exports.prepareKeyValueMessage = prepareKeyValueMessage;
//# sourceMappingURL=file-command.js.map
/***/ }),
@@ -15647,7 +15960,7 @@ module.exports = require("zlib");
/***/ ((module) => {
"use strict";
module.exports = {"i8":"2.0.1"};
module.exports = {"i8":"3.0.0"};
/***/ })
+1 -1
View File
File diff suppressed because one or more lines are too long
+1739 -3602
View File
File diff suppressed because it is too large Load Diff
+21 -7
View File
@@ -1,13 +1,12 @@
{
"name": "maven-dependency-tree-action",
"version": "2.0.1",
"name": "maven-dependency-tree-submission",
"version": "3.0.0",
"description": "",
"main": "index.js",
"scripts": {
"base-build": "npm ci && tsc",
"build": "npm run base-build && npm exec -- @vercel/ncc build --source-map lib/src/index.js",
"pre-build-exe": "npm run base-build && npm exec -- @vercel/ncc build lib/src/executable/cli.js -o runtime",
"build-exe-linux-x64": "npm run pre-build-exe && nexe -i runtime/index.js -t linux-x64-14.15.3 -o cli/maven-dependency-submission-linux-x64",
"build-exe": "pkg package.json --compress Gzip",
"test": "jest"
},
"repository": {
@@ -23,7 +22,7 @@
"homepage": "https://github.com/advanced-security/maven-dependency-tree-action#readme",
"dependencies": {
"@actions/core": "^1.10.0",
"@github/dependency-submission-toolkit": "^1.2.6",
"@github/dependency-submission-toolkit": "^1.2.8",
"commander": "^9.4.0",
"packageurl-js": "^0.0.7"
},
@@ -33,9 +32,24 @@
"@vercel/ncc": "^0.34.0",
"chai": "^4.3.6",
"jest": "^28.1.3",
"nexe": "^4.0.0-rc.1",
"pkg": "^5.8.0",
"ts-jest": "^28.0.7",
"ts-node": "^10.8.2",
"typescript": "^4.7.4"
},
"bin": {
"cli": "lib/src/executable/cli.js"
},
"pkg": {
"targets": [
"node16-linux-x64",
"node16-win-x64",
"node16-macos-x64"
],
"assets": [
"package.json"
],
"publicPackages": "*",
"outputPath": "cli"
}
}
}
+68 -44
View File
@@ -30,7 +30,7 @@ describe('depgraph', () => {
beforeAll(() => {
depGraph = parseDependencyJson(getTestDataFile('maven-plugin'));
})
});
it('should parse out the top level dependencies', () => {
const mavenDependencies = new MavenDependencyGraph(depGraph);
@@ -40,41 +40,41 @@ describe('depgraph', () => {
const names = topLevelDependencies.map(pkg => pkg.packageID());
expect(names).to.have.members([
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.apache.maven.reporting/[email protected]",
"pkg:maven/commons-io/[email protected]",
"pkg:maven/org.codehaus.plexus/[email protected]",
"pkg:maven/org.codehaus.plexus/[email protected]",
"pkg:maven/org.codehaus.plexus/[email protected]",
"pkg:maven/org.apache.maven.shared/[email protected]",
"pkg:maven/org.apache.maven.shared/[email protected]",
"pkg:maven/org.apache.maven.shared/[email protected]",
"pkg:maven/org.apache.maven.shared/[email protected]",
"pkg:maven/org.apache.maven.shared/[email protected]",
"pkg:maven/org.apache.commons/[email protected]",
"pkg:maven/org.apache.commons/[email protected]",
"pkg:maven/org.apache.maven.plugin-tools/[email protected]",
"pkg:maven/org.eclipse.aether/[email protected]",
"pkg:maven/org.eclipse.aether/[email protected]",
"pkg:maven/org.eclipse.aether/[email protected]",
"pkg:maven/org.apache.maven.wagon/[email protected]",
"pkg:maven/junit/[email protected]",
"pkg:maven/org.apache.maven.plugin-testing/[email protected]",
"pkg:maven/org.apache.maven.plugin-testing/[email protected]",
"pkg:maven/org.mockito/[email protected]",
"pkg:maven/org.codehaus.plexus/[email protected]",
"pkg:maven/org.apache.maven/[email protected]",
"pkg:maven/org.eclipse.jetty/[email protected]",
"pkg:maven/org.eclipse.jetty/[email protected]",
"pkg:maven/org.eclipse.jetty/[email protected]",
"pkg:maven/org.slf4j/[email protected]",
"pkg:maven/commons-beanutils/[email protected]"
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.apache.maven.reporting/[email protected]?type=jar",
"pkg:maven/commons-io/[email protected]?type=jar",
"pkg:maven/org.codehaus.plexus/[email protected]?type=jar",
"pkg:maven/org.codehaus.plexus/[email protected]?type=jar",
"pkg:maven/org.codehaus.plexus/[email protected]?type=jar",
"pkg:maven/org.apache.maven.shared/[email protected]?type=jar",
"pkg:maven/org.apache.maven.shared/[email protected]?type=jar",
"pkg:maven/org.apache.maven.shared/[email protected]?type=jar",
"pkg:maven/org.apache.maven.shared/[email protected]?type=jar",
"pkg:maven/org.apache.maven.shared/[email protected]?type=jar",
"pkg:maven/org.apache.commons/[email protected]?type=jar",
"pkg:maven/org.apache.commons/[email protected]?type=jar",
"pkg:maven/org.apache.maven.plugin-tools/[email protected]?type=jar",
"pkg:maven/org.eclipse.aether/[email protected]?type=jar",
"pkg:maven/org.eclipse.aether/[email protected]?type=jar",
"pkg:maven/org.eclipse.aether/[email protected]?type=jar",
"pkg:maven/org.apache.maven.wagon/[email protected]?type=jar",
"pkg:maven/junit/[email protected]?type=jar",
"pkg:maven/org.apache.maven.plugin-testing/[email protected]?type=jar",
"pkg:maven/org.apache.maven.plugin-testing/[email protected]?type=jar",
"pkg:maven/org.mockito/[email protected]?type=jar",
"pkg:maven/org.codehaus.plexus/[email protected]?type=jar",
"pkg:maven/org.apache.maven/[email protected]?type=jar",
"pkg:maven/org.eclipse.jetty/[email protected]?type=jar",
"pkg:maven/org.eclipse.jetty/[email protected]?type=jar",
"pkg:maven/org.eclipse.jetty/[email protected]?type=jar",
"pkg:maven/org.slf4j/[email protected]?type=jar",
"pkg:maven/commons-beanutils/[email protected]?type=jar"
]);
});
@@ -94,7 +94,7 @@ describe('depgraph', () => {
beforeAll(() => {
depGraph = parseDependencyJson(getTestDataFile('bookstore-v3'));
})
});
it('should parse out the top level dependencies', () => {
const mavenDependencies = new MavenDependencyGraph(depGraph);
@@ -104,13 +104,37 @@ describe('depgraph', () => {
const names = topLevelDependencies.map(pkg => pkg.packageID());
expect(names).to.have.members([
"pkg:maven/org.eclipse.jetty/[email protected]",
"pkg:maven/org.eclipse.jetty/[email protected]",
"pkg:maven/org.thymeleaf/[email protected]",
"pkg:maven/org.json/json@20210307",
"pkg:maven/org.xerial/[email protected]",
"pkg:maven/org.apache.logging.log4j/[email protected]",
"pkg:maven/junit/[email protected]"
"pkg:maven/org.eclipse.jetty/[email protected]?type=jar",
"pkg:maven/org.eclipse.jetty/[email protected]?type=jar",
"pkg:maven/org.thymeleaf/[email protected]?type=jar",
"pkg:maven/org.json/json@20210307?type=jar",
"pkg:maven/org.xerial/[email protected]?type=jar",
"pkg:maven/org.apache.logging.log4j/[email protected]?type=jar",
"pkg:maven/junit/[email protected]?type=jar"
]);
});
});
describe('bs-parent-dep-tree', () => {
let depGraph;
beforeAll(() => {
depGraph = parseDependencyJson(getTestDataFile('bs-parent-dep-tree'));
});
it('should parse out the top level dependencies', () => {
const mavenDependencies = new MavenDependencyGraph(depGraph);
const topLevelDependencies = mavenDependencies.getDirectDependencies();
expect(mavenDependencies.getPackageCount()).to.equal(19);
const topLevelNames = topLevelDependencies.map(pkg => pkg.packageID());
expect(topLevelNames).to.have.members([
"pkg:maven/org.eclipse.jetty/[email protected]?type=jar",
"pkg:maven/com.github.octodemo/[email protected]?type=jar",
"pkg:maven/junit/[email protected]?type=jar"
]);
});
});
+91 -38
View File
@@ -1,16 +1,16 @@
import * as fs from 'fs';
import { PackageURL } from 'packageurl-js'
import { PackageCache, Package, Manifest } from '@github/dependency-submission-toolkit';
import { DependencyScope } from '@github/dependency-submission-toolkit/dist/manifest';
import { loadFileContents } from './utils/file-utils';
type Depgraph = {
export type Depgraph = {
graphName: string,
artifacts: DepgraphArtifact[],
dependencies: DepgraphDependency[],
isMultiModule: boolean,
}
type DepgraphArtifact = {
export type DepgraphArtifact = {
id: string,
numericId: number,
groupId: string,
@@ -19,9 +19,10 @@ type DepgraphArtifact = {
optional?: boolean,
scopes?: string[],
types?: string[],
classifiers?: string[],
}
type DepgraphDependency = {
export type DepgraphDependency = {
from: string,
to: string,
numericFrom: number,
@@ -39,9 +40,6 @@ export class MavenDependencyGraph {
private directDependencies: Array<Package>;
// //@ ts-ignore
// private rootPackage: DepgraphArtifact;
constructor(graph: Depgraph) {
this.depGraph = graph;
this.cache = new PackageCache();
@@ -72,9 +70,13 @@ export class MavenDependencyGraph {
}
createManifest(filePath?: string): Manifest {
// The project name is not shown in the UI when you utilize a file path currently, but the file path is required to link up to the repository file
// which is more beneficial at this point.
const manifest = new Manifest(this.getProjectName(), filePath);
let manifest: Manifest;
if (filePath) {
manifest = new Manifest(this.getProjectName(), filePath);
} else {
manifest = new Manifest(this.getProjectName());
}
const packageUrlToArtifact = this.packageUrlToArtifact;
this.directDependencies.forEach(depPackage => {
@@ -104,10 +106,11 @@ export class MavenDependencyGraph {
const graph = this.depGraph;
const cache = this.cache;
const rootPackageArtifactId = graph.graphName;
let rootPackageNumericId = 0;
const dependencies = graph.dependencies || [];
const dependencyIdMap = dependencyMap(graph.dependencies);
const rootArtifactIds: string[] = [];
const dependencyIdMap = dependencyMap(dependencies);
const dependencyArtifactIdsWithParents = extractDependencyArtifactIdsWithParents(dependencies);
const idToPackageCachePackage: Map<string, Package> = new Map<string, Package>();
// Create the packages for all known artifacts
@@ -119,8 +122,8 @@ export class MavenDependencyGraph {
// Store a reference from the package URL to the original artifact as the artifact has extra metadata we need later for scopes and optionality
this.packageUrlToArtifact[artifactUrl.toString()] = artifact;
if (artifact.artifactId === rootPackageArtifactId) {
rootPackageNumericId = artifact.numericId - 1;
if (dependencyArtifactIdsWithParents.indexOf(artifact.id) === -1) {
rootArtifactIds.push(artifact.id);
}
});
@@ -145,35 +148,76 @@ export class MavenDependencyGraph {
});
}
});
this.directDependencies = getDirectDependencies(rootPackageNumericId, graph.dependencies).map(id => { return idToPackageCachePackage[id] });
const uniqueRootArtifactDependencies: string[] = [];
rootArtifactIds.forEach(rootArtifactId => {
const dependencyIds = getDirectDependencies(rootArtifactId, dependencies);
if (dependencyIds) {
dependencyIds.forEach(dependencyId => {
if (uniqueRootArtifactDependencies.indexOf(dependencyId) === -1) {
uniqueRootArtifactDependencies.push(dependencyId);
}
})
}
});
this.directDependencies = uniqueRootArtifactDependencies.map(depId => idToPackageCachePackage[depId]);
}
}
export function parseDependencyJson(file: string): Depgraph {
export function parseDependencyJson(file: string, isMultiModule: boolean = false): Depgraph {
const data = loadFileContents(file);
if (!data) {
return {
graphName: 'empty',
artifacts: [],
dependencies: [],
isMultiModule: isMultiModule
};
}
try {
const data: Buffer = fs.readFileSync(file);
try {
const depGraph: Depgraph = JSON.parse(data.toString('utf-8'));
return depGraph;
} catch (err: any) {
throw new Error(`Failed to parse JSON payload: ${err.message}`);
}
const depGraph: Depgraph = JSON.parse(data);
depGraph.isMultiModule = isMultiModule;
return depGraph;
} catch (err: any) {
throw new Error(`Failed to load file ${file}: ${err}`);
throw new Error(`Failed to parse JSON dependency data: ${err.message}`);
}
}
export function artifactToPackageURL(artifact: DepgraphArtifact): PackageURL {
const qualifiers = getArtifactQualifiers(artifact);
return new PackageURL(
'maven',
artifact.groupId,
artifact.artifactId,
artifact.version,
undefined,
qualifiers,
undefined
);
}
function getArtifactQualifiers(artifact: DepgraphArtifact): { [key: string]: string; } | undefined {
let qualifiers: { [key: string]: string; } | undefined = undefined;
if (artifact.types && artifact.types.length > 0) {
if (!qualifiers) {
qualifiers = {};
}
qualifiers['type'] = artifact.types[0];
}
if (artifact.classifiers && artifact.classifiers.length > 0) {
if (!qualifiers) {
qualifiers = {};
}
qualifiers['classifier'] = artifact.classifiers[0];
}
return qualifiers;
}
function getDependencyScopeForMavenScope(mavenScopes: string[] | undefined | null): DependencyScope {
// Once the API scopes are improved and expanded we should be able to perform better mapping here from Maven to cater for
// provided, runtime, compile, test, system, etc... in the future.
@@ -187,25 +231,34 @@ function getDependencyScopeForMavenScope(mavenScopes: string[] | undefined | nul
return 'runtime';
}
function extractDependencyArtifactIdsWithParents(dependencies: DepgraphDependency[]): string[] {
if (dependencies) {
return dependencies.map(dependency => { return dependency.to; })
}
return [];
}
function dependencyMap(dependencies: DepgraphDependency[]): Map<string, string[] | undefined> {
const map = new Map<string, string[]>();
dependencies.forEach(dependency => {
const fromUrl = dependency.from;
if (dependencies) {
dependencies.forEach(dependency => {
const fromUrl = dependency.from;
let deps = map[fromUrl];
if (!deps) {
deps = [];
map[fromUrl] = deps;
}
let deps = map[fromUrl];
if (!deps) {
deps = [];
map[fromUrl] = deps;
}
deps.push(dependency.to);
});
deps.push(dependency.to);
});
}
return map;
}
function getDirectDependencies(rootPackageNumericId: number, dependencies: DepgraphDependency[]): string[] {
const topLevel = dependencies.filter(dependency => { return dependency.numericFrom === rootPackageNumericId; });
function getDirectDependencies(artifactId: string, dependencies: DepgraphDependency[]): string[] {
const topLevel = dependencies.filter(dependency => { return dependency.from === artifactId; });
return topLevel.map(dep => { return dep.to; });
}
+37 -11
View File
@@ -1,31 +1,45 @@
import { Snapshot, submitSnapshot } from '@github/dependency-submission-toolkit';
import { generateSnapshot } from '../snapshot-generator';
import pkg from '../../package.json';
const { program } = require('commander');
program.name('maven-dependency-submission');
program.name(pkg.name);
program.version(pkg.version);
program.requiredOption('-t, --token <token>', 'GitHub access token');
program.requiredOption('-r --repository <repository>', 'GitHub repository, owner/repo_name format');
program.requiredOption('-b --branch-ref <ref>', 'GitHub repository branch reference, e.g. /refs/heads/main');
program.requiredOption('-b --branch-ref <ref>', 'GitHub repository branch reference, e.g. refs/heads/main');
program.requiredOption('-s --sha <commitSha>', 'GitHub repository commit SHA');
program.option('-d --directory <maven-project-directory>', 'the directory containing the Maven POM file', '.');
program.option('--settings-file <settings-file>', 'path to the Maven settings file');
program.option('--ignore-maven-wrapper', 'ingore Maven wrappers, if present, and use Maven from the PATH');
program.option('--maven-args <maven-args>', 'additional arguments to pass to Maven');
program.option('--github-api-url <url>', 'GitHub API URL', 'https://api.github.com');
program.option('-j --job-name <jobName>', 'Optional name for the activity creating and submitting the graph', 'maven-dependency-submission-cli');
program.option('-i --run-id <jobName>', 'Optional Run ID number for the activity that is providing the graph');
program.parse(process.argv);
const opts = program.opts();
// Inject some required environment variables like the Actions INPUTs and special environment variables
process.env['INPUT_TOKEN'] = opts.token;
process.env['GITHUB_REPOSITORY'] = opts.repository;
process.env['GITHUB_API_URL'] = opts.githubApiUrl;
// The above injection of environment variables is required before the submission APIs are imported
import { Snapshot, submitSnapshot } from '@github/dependency-submission-toolkit';
import { generateSnapshot } from '../snapshot-generator';
async function execute() {
const opts = program.opts();
// Inject some required environment variables like the Actions INPUTs and special environment variables
process.env['INPUT_TOKEN'] = opts.token;
process.env['GITHUB_REPOSITORY'] = opts.repository;
let snapshot: Snapshot | undefined;
// The dependency submission API requires a formatted ref reference so check early fo now
if (`/^refs\//`.match(opts.branchRef) === null) {
console.error(`Branch reference must be in path form, e.g. 'refs/heads/main' for the 'main' branch.`);
program.help({ error: true });
process.exit(1);
}
try {
// Build a fake GitHub Actions context so that values for the submission APIs can be retrieved
const context = {
@@ -38,7 +52,19 @@ async function execute() {
id: `${opts.runId || Date.now()}`
};
snapshot = await generateSnapshot(opts.directory, context, job);
const mvnConfig = {
directory: opts.directory,
settingsFile: opts.settingsFile,
ignoreMavenWrapper: opts.ignoreMavenWrapper,
mavenArgs: opts.mavenArgs
};
const snapshotConfig = {
context,
job,
}
snapshot = await generateSnapshot(opts.directory, mvnConfig, snapshotConfig);
} catch (err: any) {
console.error(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
+8 -2
View File
@@ -2,14 +2,20 @@ import * as core from '@actions/core';
import {Snapshot, submitSnapshot} from '@github/dependency-submission-toolkit';
import { generateSnapshot } from './snapshot-generator';
async function run() {
let snapshot: Snapshot | undefined;
try {
const directory = core.getInput('directory', { required: true });
snapshot = await generateSnapshot(directory);
const mavenConfig = {
ignoreMavenWrapper: core.getBooleanInput('ignore-maven-wrapper'),
settingsFile: core.getInput('settings-file'),
mavenArgs: core.getInput('maven-args') || '',
}
const includeFilename = core.getBooleanInput('snapshot-include-file-name');
const manifestFilename = core.getInput('snapshot-dependency-file-name');
snapshot = await generateSnapshot(directory, mavenConfig, {includeManifestFile: includeFilename, manifestFile: manifestFilename});
} catch (err: any) {
core.error(err);
core.setFailed(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
+117
View File
@@ -0,0 +1,117 @@
import * as path from 'path';
import { getMavenProjectDirectory, getMavenSettingsFile } from './utils/test-util';
import { MavenRunner } from './maven-runner';
describe('maven-runner', () => {
jest.setTimeout(20000);
describe('create', () => {
it('should create a runner without a wrapper', async () => {
const projectDir = getMavenProjectDirectory('simple');
const runner = new MavenRunner(projectDir);
expect(runner.configuration.executable).toBeDefined();
expect(runner.configuration.executable).toBe('mvn');
expect(runner.configuration.settingsFile).toBeUndefined();
});
it('should create a runner with wrapper', async () => {
const projectDir = getMavenProjectDirectory('maven-wrapper');
const runner = new MavenRunner(projectDir);
expect(runner.configuration.executable).toBeDefined();
expect(runner.configuration.executable).toBe(path.join(projectDir, 'mvnw'));
expect(runner.configuration.settingsFile).toBeUndefined();
});
describe('with settings', () => {
it('should create a runner without a wrapper', async () => {
const projectDir = getMavenProjectDirectory('simple');
const settings = getMavenSettingsFile();
const runner = new MavenRunner(projectDir, settings);
expect(runner.configuration.executable).toBeDefined();
expect(runner.configuration.executable).toBe('mvn');
expect(runner.configuration.settingsFile).toBe(settings);
});
})
});
describe('#exec()', () => {
it('should run path provided maven', async () => {
const projectDir = getMavenProjectDirectory('simple');
const runner = new MavenRunner(projectDir);
const results = await runner.exec(projectDir, ['--version']);
expect(results.exitCode).toBe(0);
expect(results.stdout).toContain('Apache Maven');
});
it('should run wrapper provided maven', async () => {
const projectDir = getMavenProjectDirectory('maven-wrapper');
const runner = new MavenRunner(projectDir);
const results = await runner.exec(projectDir, ['--version']);
expect(results.exitCode).toBe(0);
expect(results.stdout).toContain('Apache Maven');
expect(results.stdout).toContain('3.8.6');
});
it('should run wrapper provided maven with validate phase', async () => {
const projectDir = getMavenProjectDirectory('maven-wrapper');
const runner = new MavenRunner(projectDir);
const results = await runner.exec(projectDir, ['validate']);
expect(results.exitCode).toBe(0);
});
describe('with additional arguments', () => {
it('should run path provided maven with additional arguments', async () => {
const projectDir = getMavenProjectDirectory('simple');
const additionalMavenArgs = ' -DskipTests -q';
const runner = new MavenRunner(projectDir, undefined, false, additionalMavenArgs);
const results = await runner.exec(projectDir, ['validate']);
expect(results.exitCode).toBe(0);
// by running with quiet mode there should be no output
expect(results.stdout.length).toBe(0);
});
});
describe('with settings', () => {
it('should run path provided maven with settings file', async () => {
const projectDir = getMavenProjectDirectory('simple');
const settingsFile = getMavenSettingsFile();
const runner = new MavenRunner(projectDir, settingsFile);
const results = await runner.exec(projectDir, ['-X', 'validate']);
expect(results.exitCode).toBe(0);
// When running in debug mode the settings files that are loaded are displayed in the stdout
expect(results.stdout).toContain(`Reading user settings from ${path.resolve(settingsFile)}`);
});
it('should run wrapper provided maven with settings file', async () => {
const projectDir = getMavenProjectDirectory('maven-wrapper');
const settingsFile = getMavenSettingsFile();
const runner = new MavenRunner(projectDir, settingsFile);
const results = await runner.exec(projectDir, ['-X', 'validate']);
expect(results.exitCode).toBe(0);
// When running in debug mode the settings files that are loaded are displayed in the stdout
expect(results.stdout).toContain(`Reading user settings from ${path.resolve(settingsFile)}`);
});
});
});
});
+147
View File
@@ -0,0 +1,147 @@
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as path from 'path';
import { fileExists } from './utils/file-utils';
export type ExecResults = {
stdout: string,
stderr: string,
exitCode: number
}
export type MavenRunnerConfiguration = {
executable: string
settingsFile?: string
mavenArgs?: string
}
export class MavenRunner {
private mavenExecutable: string
private settings: string | undefined;
private additionalArguments: string[];
constructor(directory?: string, settingsFile?: string, ingoreWrapper: boolean = false, mavenArguments: string = '') {
this.mavenExecutable = resolveMavenExecutable(directory, ingoreWrapper);
if (settingsFile) {
if (fileExists(settingsFile)) {
this.settings = settingsFile;
} else {
throw new Error(`The specified settings file '${settingsFile}' does not exist`);
}
}
this.additionalArguments = [];
if (mavenArguments.trim().length > 0) {
this.additionalArguments = mavenArguments.trim().split(' ');
}
}
get configuration() {
return {
executable: this.mavenExecutable,
settingsFile: this.settings
};
}
async exec(cwd: string, parameters: string[]): Promise<ExecResults> {
const commandArgs: string[] = [];
// implictly run in batch mode, might need to make this configurable in the future
commandArgs.push('-B');
if (this.settings) {
commandArgs.push('--settings')
commandArgs.push(this.settings);
}
// Only append the additional arguments they are not empty values
if (this.additionalArguments && this.additionalArguments.length > 0) {
this.additionalArguments.forEach(arg => {
if (arg.trim().length > 0) {
commandArgs.push(arg);
}
});
}
Array.prototype.push.apply(commandArgs, parameters);
let executionOutput = '';
let executionErrors = '';
const options = {
cwd: cwd,
listeners: {
stdout: (data: Buffer) => {
executionOutput += data.toString();
},
stderr: (data: Buffer) => {
executionErrors += data.toString();
}
}
};
try {
const exitCode = await exec.exec(this.mavenExecutable, commandArgs, options);
return {
stdout: executionOutput,
stderr: executionErrors,
exitCode: exitCode
}
} catch (err: any) {
//TODO possibly throw a wrapped error here
core.warning(`Error encountered executing maven: ${err.message}`);
return {
stdout: executionOutput,
stderr: executionErrors,
exitCode: -1
}
}
}
}
function resolveMavenExecutable(directory?: string, ignoreWrapper: boolean = false): string {
if (ignoreWrapper) {
return getMavenExecutable();
}
const wrapper = getMavenWrapper(directory);
// Return the matche maven wrapper script or otherwise fall back to mvn on the path
return wrapper || getMavenExecutable();
}
function getMavenWrapper(directory?: string): string | undefined {
if (!directory) {
return undefined;
}
const mavenWrapperFilename = path.join(directory, getMavenWrapperExecutable());
if (fileExists(mavenWrapperFilename)) {
return mavenWrapperFilename;
}
return undefined;
}
function getMavenWrapperExecutable(): string {
if (isWindows()) {
return 'mvnw.cmd';
}
return 'mvnw';
}
function getMavenExecutable(): string {
if (isWindows()) {
return 'mvn.cmd';
}
return 'mvn';
}
function isWindows() {
return process.platform === 'win32';
}
+38 -7
View File
@@ -1,5 +1,5 @@
import * as path from 'path';
import {generateDependencyGraph, generateSnapshot} from './snapshot-generator';
import { getMavenProjectDirectory } from './utils/test-util';
import { generateDependencyGraph, generateSnapshot } from './snapshot-generator';
describe('snapshot-generator', () => {
@@ -25,9 +25,40 @@ describe('snapshot-generator', () => {
expect(snapshot.manifests['bookstore-v3']).toBeDefined();
expect(snapshot.detector.version).toBe(version);
});
});
});
function getMavenProjectDirectory(name: string): string {
return path.join(__dirname, '..', 'test-data', 'maven', name);
}
it('should generate a snapshot for a multi-module project', async () => {
const projectDir = getMavenProjectDirectory('multi-module');
const snapshot = await generateSnapshot(projectDir);
expect(snapshot.manifests['bs-parent']).toBeDefined();
expect(snapshot.detector.version).toBe(version);
});
it('should generate a snapshot for a multi-module-multi-branch project', async () => {
const projectDir = getMavenProjectDirectory('multi-module-multi-branch');
const snapshot = await generateSnapshot(projectDir);
expect(snapshot.manifests['bs-parent']).toBeDefined();
expect(snapshot.detector.version).toBe(version);
expect(snapshot.manifests['bs-parent'].countDependencies()).toBe(20);
});
it('should generate a snapshot for a maven-wrapper project', async () => {
const projectDir = getMavenProjectDirectory('maven-wrapper');
const snapshot = await generateSnapshot(projectDir);
expect(snapshot.manifests['maven-wrapper-test']).toBeDefined();
expect(snapshot.detector.version).toBe(version);
expect(snapshot.manifests['maven-wrapper-test'].countDependencies()).toBe(0);
});
it('should generate a snapshot for an artifact with classifiers project', async () => {
const projectDir = getMavenProjectDirectory('artifact-with-classifiers');
const snapshot = await generateSnapshot(projectDir);
expect(snapshot.manifests['artifact-with-classifiers']).toBeDefined();
expect(snapshot.detector.version).toBe(version);
expect(snapshot.manifests['artifact-with-classifiers'].countDependencies()).toBe(7);
});
});
});
+108 -35
View File
@@ -1,20 +1,49 @@
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as path from 'path';
import { Snapshot } from '@github/dependency-submission-toolkit';
import { MavenDependencyGraph, parseDependencyJson } from './depgraph';
import { Manifest, Snapshot } from '@github/dependency-submission-toolkit';
import { Depgraph, MavenDependencyGraph, parseDependencyJson } from './depgraph';
import { MavenRunner } from './maven-runner';
import { loadFileContents } from './utils/file-utils';
const version = require('../package.json')['version'];
export async function generateSnapshot(directory: string, context?: any, job?: any) {
const depgraph = await generateDependencyGraph(directory);
const DEPGRAPH_MAVEN_PLUGIN_VERSION = '4.0.2';
export type MavenConfiguration = {
ignoreMavenWrapper?: boolean;
settingsFile?: string;
mavenArgs?: string;
}
export type SnapshotConfig = {
includeManifestFile?: boolean;
manifestFile?: string;
context?: any;
job?: any
};
export async function generateSnapshot(directory: string, mvnConfig?: MavenConfiguration, snapshotConfig?: SnapshotConfig) {
const depgraph = await generateDependencyGraph(directory, mvnConfig);
try {
const mavenDependencies = new MavenDependencyGraph(depgraph);
const manifest = mavenDependencies.createManifest(path.join(directory, 'pom.xml'));
const snapshot = new Snapshot(getDetector(), context, job);
let manifest: Manifest;
if (snapshotConfig?.includeManifestFile) {
let pomFile;
if (snapshotConfig?.manifestFile) {
pomFile = snapshotConfig.manifestFile;
} else {
// The filepath to the POM needs to be relative to the root of the GitHub repository for the links to work once uploaded
pomFile = getRepositoryRelativePath(path.join(directory, 'pom.xml'));
}
manifest = mavenDependencies.createManifest(pomFile);
} else {
manifest = mavenDependencies.createManifest();
}
const snapshot = new Snapshot(getDetector(), snapshotConfig?.context, snapshotConfig?.job);
snapshot.addManifest(manifest);
return snapshot;
@@ -32,47 +61,91 @@ function getDetector() {
};
}
export async function generateDependencyGraph(directory: string) {
export async function generateDependencyGraph(directory: string, config?: MavenConfiguration): Promise<Depgraph> {
try {
let executionOutput = '';
let errors = '';
const mvn = new MavenRunner(directory, config?.settingsFile, config?.ignoreMavenWrapper);
const options = {
cwd: directory,
listeners: {
stdout: (data: Buffer) => {
executionOutput += data.toString();
},
stderr: (data: Buffer) => {
errors += data.toString();
}
}
};
const mavenArguments = [
'com.github.ferstl:depgraph-maven-plugin:4.0.1:graph',
core.startGroup('depgraph-maven-plugin:reactor');
const mavenReactorArguments = [
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:reactor`,
'-DgraphFormat=json',
'-DoutputFileName=reactor.json'
];
const reactorResults = await mvn.exec(directory, mavenReactorArguments);
core.startGroup('depgraph-maven-plugin');
await exec.exec('mvn', mavenArguments, options);
core.info(executionOutput);
core.info(errors);
core.info(reactorResults.stdout);
core.info(reactorResults.stderr);
core.endGroup();
if (reactorResults.exitCode !== 0) {
throw new Error(`Failed to successfully generate reactor results with Maven, exit code: ${reactorResults.exitCode}`);
}
core.startGroup('depgraph-maven-plugin:aggregate');
const mavenAggregateArguments = [
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:aggregate`,
'-DgraphFormat=json',
'-DoutputFileName=aggregate-depgraph.json'
];
const aggregateResults = await mvn.exec(directory, mavenAggregateArguments);
core.info(aggregateResults.stdout);
core.info(aggregateResults.stderr);
core.endGroup();
if (aggregateResults.exitCode !== 0) {
throw new Error(`Failed to successfully dependency results with Maven, exit code: ${aggregateResults.exitCode}`);
}
} catch (err: any) {
core.error(err);
throw new Error(`A problem was encountered generating dependency files, please check execution logs for details; ${err.message}`);
}
//TODO need to account for multi module projects
const targetPath = path.join(directory, 'target');
const isMultiModule = checkForMultiModule(path.join(targetPath, 'reactor.json'));
// Now we have the target/dependency-graph.json file to process
const file = path.join(directory, 'target', 'dependency-graph.json');
// Now we have the aggregate dependency graph file to process
const aggregateGraphFile = path.join(targetPath, 'aggregate-depgraph.json');
try {
return parseDependencyJson(file);
return parseDependencyJson(aggregateGraphFile, isMultiModule);
} catch (err: any) {
core.error(err);
throw new Error(`Could not parse maven dependency file, '${file}': ${err.message}`);
throw new Error(`Could not parse maven dependency file, '${aggregateGraphFile}': ${err.message}`);
}
}
function checkForMultiModule(reactorJsonFile): boolean {
const data = loadFileContents(reactorJsonFile);
if (data) {
try {
const reactor = JSON.parse(data);
// The reactor file will have an array of artifacts making up the parent and child modules if it is a multi module project
return reactor.artifacts && reactor.artifacts.length > 0;
} catch (err: any) {
throw new Error(`Failed to parse reactor JSON payload: ${err.message}`);
}
}
// If no data report that it is not a multi module project
return false;
}
// TODO this is assuming the checkout was made into the base path of the workspace...
function getRepositoryRelativePath(file) {
const workspaceDirectory = path.resolve(process.env.GITHUB_WORKSPACE || '.');
const fileResolved = path.resolve(file);
const fileDirectory = path.dirname(fileResolved);
core.debug(`Workspace directory = ${workspaceDirectory}`);
core.debug(`Snapshot file = ${fileResolved}`);
core.debug(`Snapshot directory = ${fileDirectory}`);
let result = fileResolved;
if (fileDirectory.startsWith(workspaceDirectory)) {
result = fileResolved.substring(workspaceDirectory.length + path.sep.length);
}
core.debug(`Snapshot relative file = ${result}`);
return result;
}
+31
View File
@@ -0,0 +1,31 @@
import * as fs from 'fs';
export function loadFileContents(file: string): string | undefined {
if (!fileExists(file)) {
return undefined;
}
try {
const data: Buffer = fs.readFileSync(file);
return data.toString('utf8');
} catch (err: any) {
throw new Error(`Failed to load file contents ${file}: ${err}`);
}
}
export function fileExists(file?: string): boolean {
if (!file) {
return false;
}
try {
const wrapperFileStats = fs.statSync(file);
// TODO might need to deal with a linked file, but ingoring that for now
return wrapperFileStats && wrapperFileStats.isFile();
} catch (err: any) {
if (err.code == 'ENOENT') {
return false;
}
throw err;
}
}
+13
View File
@@ -0,0 +1,13 @@
import * as path from 'path';
function getTestDataDirectory() {
return path.join(__dirname, '..', '..', 'test-data');
}
export function getMavenProjectDirectory(name: string): string {
return path.join(getTestDataDirectory(), 'maven', name);
}
export function getMavenSettingsFile(): string {
return path.join(getTestDataDirectory(), 'maven', 'settings.xml');
}
+61 -61
View File
@@ -1,7 +1,7 @@
{
"graphName" : "bookstore-v3",
"artifacts" : [ {
"id" : "org.eclipse.jetty:jetty-server:jar",
"id" : "org.eclipse.jetty:jetty-server:jar:compile",
"numericId" : 1,
"groupId" : "org.eclipse.jetty",
"artifactId" : "jetty-server",
@@ -10,7 +10,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.eclipse.jetty.toolchain:jetty-servlet-api:jar",
"id" : "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:compile",
"numericId" : 2,
"groupId" : "org.eclipse.jetty.toolchain",
"artifactId" : "jetty-servlet-api",
@@ -19,7 +19,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.eclipse.jetty:jetty-http:jar",
"id" : "org.eclipse.jetty:jetty-http:jar:compile",
"numericId" : 3,
"groupId" : "org.eclipse.jetty",
"artifactId" : "jetty-http",
@@ -28,7 +28,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.eclipse.jetty:jetty-util:jar",
"id" : "org.eclipse.jetty:jetty-util:jar:compile",
"numericId" : 4,
"groupId" : "org.eclipse.jetty",
"artifactId" : "jetty-util",
@@ -37,7 +37,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.eclipse.jetty:jetty-io:jar",
"id" : "org.eclipse.jetty:jetty-io:jar:compile",
"numericId" : 5,
"groupId" : "org.eclipse.jetty",
"artifactId" : "jetty-io",
@@ -46,7 +46,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.slf4j:slf4j-api:jar",
"id" : "org.slf4j:slf4j-api:jar:compile",
"numericId" : 6,
"groupId" : "org.slf4j",
"artifactId" : "slf4j-api",
@@ -55,7 +55,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "com.github.octodemo:bookstore-v3:jar",
"id" : "com.github.octodemo:bookstore-v3:jar:compile",
"numericId" : 7,
"groupId" : "com.github.octodemo",
"artifactId" : "bookstore-v3",
@@ -64,7 +64,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.eclipse.jetty:jetty-servlet:jar",
"id" : "org.eclipse.jetty:jetty-servlet:jar:compile",
"numericId" : 8,
"groupId" : "org.eclipse.jetty",
"artifactId" : "jetty-servlet",
@@ -73,7 +73,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.eclipse.jetty:jetty-security:jar",
"id" : "org.eclipse.jetty:jetty-security:jar:compile",
"numericId" : 9,
"groupId" : "org.eclipse.jetty",
"artifactId" : "jetty-security",
@@ -82,7 +82,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "ognl:ognl:jar",
"id" : "ognl:ognl:jar:compile",
"numericId" : 10,
"groupId" : "ognl",
"artifactId" : "ognl",
@@ -91,7 +91,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.javassist:javassist:jar",
"id" : "org.javassist:javassist:jar:compile",
"numericId" : 11,
"groupId" : "org.javassist",
"artifactId" : "javassist",
@@ -100,7 +100,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.thymeleaf:thymeleaf:jar",
"id" : "org.thymeleaf:thymeleaf:jar:compile",
"numericId" : 12,
"groupId" : "org.thymeleaf",
"artifactId" : "thymeleaf",
@@ -109,7 +109,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.attoparser:attoparser:jar",
"id" : "org.attoparser:attoparser:jar:compile",
"numericId" : 13,
"groupId" : "org.attoparser",
"artifactId" : "attoparser",
@@ -118,7 +118,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.unbescape:unbescape:jar",
"id" : "org.unbescape:unbescape:jar:compile",
"numericId" : 14,
"groupId" : "org.unbescape",
"artifactId" : "unbescape",
@@ -127,7 +127,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.json:json:jar",
"id" : "org.json:json:jar:compile",
"numericId" : 15,
"groupId" : "org.json",
"artifactId" : "json",
@@ -136,7 +136,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.xerial:sqlite-jdbc:jar",
"id" : "org.xerial:sqlite-jdbc:jar:compile",
"numericId" : 16,
"groupId" : "org.xerial",
"artifactId" : "sqlite-jdbc",
@@ -145,7 +145,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar",
"id" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar:compile",
"numericId" : 17,
"groupId" : "org.apache.logging.log4j",
"artifactId" : "log4j-slf4j18-impl",
@@ -154,7 +154,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.apache.logging.log4j:log4j-api:jar",
"id" : "org.apache.logging.log4j:log4j-api:jar:compile",
"numericId" : 18,
"groupId" : "org.apache.logging.log4j",
"artifactId" : "log4j-api",
@@ -163,7 +163,7 @@
"scopes" : [ "compile" ],
"types" : [ "jar" ]
}, {
"id" : "org.apache.logging.log4j:log4j-core:jar",
"id" : "org.apache.logging.log4j:log4j-core:jar:runtime",
"numericId" : 19,
"groupId" : "org.apache.logging.log4j",
"artifactId" : "log4j-core",
@@ -172,7 +172,7 @@
"scopes" : [ "runtime" ],
"types" : [ "jar" ]
}, {
"id" : "junit:junit:jar",
"id" : "junit:junit:jar:test",
"numericId" : 20,
"groupId" : "junit",
"artifactId" : "junit",
@@ -181,7 +181,7 @@
"scopes" : [ "test" ],
"types" : [ "jar" ]
}, {
"id" : "org.hamcrest:hamcrest-core:jar",
"id" : "org.hamcrest:hamcrest-core:jar:test",
"numericId" : 21,
"groupId" : "org.hamcrest",
"artifactId" : "hamcrest-core",
@@ -191,122 +191,122 @@
"types" : [ "jar" ]
} ],
"dependencies" : [ {
"from" : "org.eclipse.jetty:jetty-server:jar",
"to" : "org.eclipse.jetty.toolchain:jetty-servlet-api:jar",
"from" : "org.eclipse.jetty:jetty-server:jar:compile",
"to" : "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:compile",
"numericFrom" : 0,
"numericTo" : 1,
"resolution" : "INCLUDED"
}, {
"from" : "org.eclipse.jetty:jetty-http:jar",
"to" : "org.eclipse.jetty:jetty-util:jar",
"from" : "org.eclipse.jetty:jetty-http:jar:compile",
"to" : "org.eclipse.jetty:jetty-util:jar:compile",
"numericFrom" : 2,
"numericTo" : 3,
"resolution" : "INCLUDED"
}, {
"from" : "org.eclipse.jetty:jetty-server:jar",
"to" : "org.eclipse.jetty:jetty-http:jar",
"from" : "org.eclipse.jetty:jetty-server:jar:compile",
"to" : "org.eclipse.jetty:jetty-http:jar:compile",
"numericFrom" : 0,
"numericTo" : 2,
"resolution" : "INCLUDED"
}, {
"from" : "org.eclipse.jetty:jetty-server:jar",
"to" : "org.eclipse.jetty:jetty-io:jar",
"from" : "org.eclipse.jetty:jetty-server:jar:compile",
"to" : "org.eclipse.jetty:jetty-io:jar:compile",
"numericFrom" : 0,
"numericTo" : 4,
"resolution" : "INCLUDED"
}, {
"from" : "org.eclipse.jetty:jetty-server:jar",
"to" : "org.slf4j:slf4j-api:jar",
"from" : "org.eclipse.jetty:jetty-server:jar:compile",
"to" : "org.slf4j:slf4j-api:jar:compile",
"numericFrom" : 0,
"numericTo" : 5,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "org.eclipse.jetty:jetty-server:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "org.eclipse.jetty:jetty-server:jar:compile",
"numericFrom" : 6,
"numericTo" : 0,
"resolution" : "INCLUDED"
}, {
"from" : "org.eclipse.jetty:jetty-servlet:jar",
"to" : "org.eclipse.jetty:jetty-security:jar",
"from" : "org.eclipse.jetty:jetty-servlet:jar:compile",
"to" : "org.eclipse.jetty:jetty-security:jar:compile",
"numericFrom" : 7,
"numericTo" : 8,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "org.eclipse.jetty:jetty-servlet:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "org.eclipse.jetty:jetty-servlet:jar:compile",
"numericFrom" : 6,
"numericTo" : 7,
"resolution" : "INCLUDED"
}, {
"from" : "ognl:ognl:jar",
"to" : "org.javassist:javassist:jar",
"from" : "ognl:ognl:jar:compile",
"to" : "org.javassist:javassist:jar:compile",
"numericFrom" : 9,
"numericTo" : 10,
"resolution" : "INCLUDED"
}, {
"from" : "org.thymeleaf:thymeleaf:jar",
"to" : "ognl:ognl:jar",
"from" : "org.thymeleaf:thymeleaf:jar:compile",
"to" : "ognl:ognl:jar:compile",
"numericFrom" : 11,
"numericTo" : 9,
"resolution" : "INCLUDED"
}, {
"from" : "org.thymeleaf:thymeleaf:jar",
"to" : "org.attoparser:attoparser:jar",
"from" : "org.thymeleaf:thymeleaf:jar:compile",
"to" : "org.attoparser:attoparser:jar:compile",
"numericFrom" : 11,
"numericTo" : 12,
"resolution" : "INCLUDED"
}, {
"from" : "org.thymeleaf:thymeleaf:jar",
"to" : "org.unbescape:unbescape:jar",
"from" : "org.thymeleaf:thymeleaf:jar:compile",
"to" : "org.unbescape:unbescape:jar:compile",
"numericFrom" : 11,
"numericTo" : 13,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "org.thymeleaf:thymeleaf:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "org.thymeleaf:thymeleaf:jar:compile",
"numericFrom" : 6,
"numericTo" : 11,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "org.json:json:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "org.json:json:jar:compile",
"numericFrom" : 6,
"numericTo" : 14,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "org.xerial:sqlite-jdbc:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "org.xerial:sqlite-jdbc:jar:compile",
"numericFrom" : 6,
"numericTo" : 15,
"resolution" : "INCLUDED"
}, {
"from" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar",
"to" : "org.apache.logging.log4j:log4j-api:jar",
"from" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar:compile",
"to" : "org.apache.logging.log4j:log4j-api:jar:compile",
"numericFrom" : 16,
"numericTo" : 17,
"resolution" : "INCLUDED"
}, {
"from" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar",
"to" : "org.apache.logging.log4j:log4j-core:jar",
"from" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar:compile",
"to" : "org.apache.logging.log4j:log4j-core:jar:runtime",
"numericFrom" : 16,
"numericTo" : 18,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "org.apache.logging.log4j:log4j-slf4j18-impl:jar:compile",
"numericFrom" : 6,
"numericTo" : 16,
"resolution" : "INCLUDED"
}, {
"from" : "junit:junit:jar",
"to" : "org.hamcrest:hamcrest-core:jar",
"from" : "junit:junit:jar:test",
"to" : "org.hamcrest:hamcrest-core:jar:test",
"numericFrom" : 19,
"numericTo" : 20,
"resolution" : "INCLUDED"
}, {
"from" : "com.github.octodemo:bookstore-v3:jar",
"to" : "junit:junit:jar",
"from" : "com.github.octodemo:bookstore-v3:jar:compile",
"to" : "junit:junit:jar:test",
"numericFrom" : 6,
"numericTo" : 19,
"resolution" : "INCLUDED"
@@ -0,0 +1,427 @@
{
"graphName": "bs-parent",
"artifacts": [
{
"id": "org.eclipse.jetty:jetty-http:jar:compile",
"numericId": 1,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-http",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty:jetty-util:jar:compile",
"numericId": 2,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-util",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty:jetty-client:jar:compile",
"numericId": 3,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-client",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty:jetty-io:jar:compile",
"numericId": 4,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-io",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty:jetty-alpn-client:jar:compile",
"numericId": 5,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-alpn-client",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty.http2:http2-http-client-transport:jar:compile",
"numericId": 6,
"groupId": "org.eclipse.jetty.http2",
"artifactId": "http2-http-client-transport",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty.http2:http2-common:jar:compile",
"numericId": 7,
"groupId": "org.eclipse.jetty.http2",
"artifactId": "http2-common",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty.http2:http2-hpack:jar:compile",
"numericId": 8,
"groupId": "org.eclipse.jetty.http2",
"artifactId": "http2-hpack",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty.http2:http2-client:jar:compile",
"numericId": 9,
"groupId": "org.eclipse.jetty.http2",
"artifactId": "http2-client",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty:jetty-alpn-java-client:jar:compile",
"numericId": 10,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-alpn-java-client",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.slf4j:slf4j-api:jar:compile",
"numericId": 11,
"groupId": "org.slf4j",
"artifactId": "slf4j-api",
"version": "2.0.0-alpha6",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "com.github.octodemo:bs-library:jar:compile",
"numericId": 12,
"groupId": "com.github.octodemo",
"artifactId": "bs-library",
"version": "1.0.0-SNAPSHOT",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.apache.logging.log4j:log4j-api:jar:compile",
"numericId": 13,
"groupId": "org.apache.logging.log4j",
"artifactId": "log4j-api",
"version": "2.19.0",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "junit:junit:jar:test",
"numericId": 14,
"groupId": "junit",
"artifactId": "junit",
"version": "4.13",
"optional": false,
"scopes": [
"test"
],
"types": [
"jar"
]
},
{
"id": "org.hamcrest:hamcrest-core:jar:test",
"numericId": 15,
"groupId": "org.hamcrest",
"artifactId": "hamcrest-core",
"version": "1.3",
"optional": false,
"scopes": [
"test"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty:jetty-server:jar:compile",
"numericId": 16,
"groupId": "org.eclipse.jetty",
"artifactId": "jetty-server",
"version": "10.0.10",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:compile",
"numericId": 17,
"groupId": "org.eclipse.jetty.toolchain",
"artifactId": "jetty-servlet-api",
"version": "4.0.6",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "com.github.octodemo:bs-application:jar:compile",
"numericId": 18,
"groupId": "com.github.octodemo",
"artifactId": "bs-application",
"version": "1.0.0-SNAPSHOT",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
},
{
"id": "com.github.octodemo:bs-other:jar:compile",
"numericId": 19,
"groupId": "com.github.octodemo",
"artifactId": "bs-other",
"version": "1.0.0-SNAPSHOT",
"optional": false,
"scopes": [
"compile"
],
"types": [
"jar"
]
}
],
"dependencies": [
{
"from": "org.eclipse.jetty:jetty-http:jar:compile",
"to": "org.eclipse.jetty:jetty-util:jar:compile",
"numericFrom": 0,
"numericTo": 1,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-client:jar:compile",
"to": "org.eclipse.jetty:jetty-http:jar:compile",
"numericFrom": 2,
"numericTo": 0,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-client:jar:compile",
"to": "org.eclipse.jetty:jetty-io:jar:compile",
"numericFrom": 2,
"numericTo": 3,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-client:jar:compile",
"to": "org.eclipse.jetty:jetty-alpn-client:jar:compile",
"numericFrom": 2,
"numericTo": 4,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty.http2:http2-http-client-transport:jar:compile",
"to": "org.eclipse.jetty:jetty-client:jar:compile",
"numericFrom": 5,
"numericTo": 2,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty.http2:http2-common:jar:compile",
"to": "org.eclipse.jetty.http2:http2-hpack:jar:compile",
"numericFrom": 6,
"numericTo": 7,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty.http2:http2-client:jar:compile",
"to": "org.eclipse.jetty.http2:http2-common:jar:compile",
"numericFrom": 8,
"numericTo": 6,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty.http2:http2-http-client-transport:jar:compile",
"to": "org.eclipse.jetty.http2:http2-client:jar:compile",
"numericFrom": 5,
"numericTo": 8,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty.http2:http2-http-client-transport:jar:compile",
"to": "org.eclipse.jetty:jetty-alpn-java-client:jar:compile",
"numericFrom": 5,
"numericTo": 9,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty.http2:http2-http-client-transport:jar:compile",
"to": "org.slf4j:slf4j-api:jar:compile",
"numericFrom": 5,
"numericTo": 10,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-library:jar:compile",
"to": "org.eclipse.jetty.http2:http2-http-client-transport:jar:compile",
"numericFrom": 11,
"numericTo": 5,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-library:jar:compile",
"to": "org.apache.logging.log4j:log4j-api:jar:compile",
"numericFrom": 11,
"numericTo": 12,
"resolution": "INCLUDED"
},
{
"from": "junit:junit:jar:test",
"to": "org.hamcrest:hamcrest-core:jar:test",
"numericFrom": 13,
"numericTo": 14,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-library:jar:compile",
"to": "junit:junit:jar:test",
"numericFrom": 11,
"numericTo": 13,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-server:jar:compile",
"to": "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:compile",
"numericFrom": 15,
"numericTo": 16,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-server:jar:compile",
"to": "org.eclipse.jetty:jetty-http:jar:compile",
"numericFrom": 15,
"numericTo": 0,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-server:jar:compile",
"to": "org.eclipse.jetty:jetty-io:jar:compile",
"numericFrom": 15,
"numericTo": 3,
"resolution": "INCLUDED"
},
{
"from": "org.eclipse.jetty:jetty-server:jar:compile",
"to": "org.slf4j:slf4j-api:jar:compile",
"numericFrom": 15,
"numericTo": 10,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-application:jar:compile",
"to": "org.eclipse.jetty:jetty-server:jar:compile",
"numericFrom": 17,
"numericTo": 15,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-application:jar:compile",
"to": "com.github.octodemo:bs-library:jar:compile",
"numericFrom": 17,
"numericTo": 11,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-application:jar:compile",
"to": "junit:junit:jar:test",
"numericFrom": 17,
"numericTo": 13,
"resolution": "INCLUDED"
},
{
"from": "com.github.octodemo:bs-other:jar:compile",
"to": "junit:junit:jar:test",
"numericFrom": 18,
"numericTo": 13,
"resolution": "INCLUDED"
}
]
}
@@ -0,0 +1,22 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.octodemo</groupId>
<artifactId>artifact-with-classifiers</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!-- dependency triggering Maximum call stack size exceeded due to not propery processing the classifiers -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>2.0.54.Final</version>
</dependency>
</dependencies>
</project>
Binary file not shown.
@@ -0,0 +1,18 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
+287
View File
@@ -0,0 +1,287 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Apache Maven Wrapper startup batch script, version 3.1.1
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
JAVA_HOME="`/usr/libexec/java_home`"; export JAVA_HOME
else
JAVA_HOME="/Library/Java/Home"; export JAVA_HOME
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
printf '%s' "$(cd "$basedir"; pwd)"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=$(find_maven_basedir "$(dirname $0)")
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
else
wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) wrapperUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $wrapperUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
QUIET="--quiet"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
QUIET=""
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget $QUIET "$wrapperUrl" -O "$wrapperJarPath"
else
wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath"
fi
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
elif command -v curl > /dev/null; then
QUIET="--silent"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
QUIET=""
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L
else
curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L
fi
[ $? -eq 0 ] || rm -f "$wrapperJarPath"
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaSource="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaSource=`cygpath --path --windows "$javaSource"`
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaSource" ]; then
if [ ! -e "$javaClass" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaSource")
fi
if [ -e "$javaClass" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
+187
View File
@@ -0,0 +1,187 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Apache Maven Wrapper startup batch script, version 3.1.1
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %WRAPPER_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
+10
View File
@@ -0,0 +1,10 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.octodemo</groupId>
<artifactId>maven-wrapper-test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- puposely has no dependencies -->
</project>
@@ -0,0 +1,29 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-application</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bs-library-web</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bs-library-web</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,25 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-libraries</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-library-database</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.36.0.3</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,19 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-libraries</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-library-web</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,36 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-libraries</artifactId>
<packaging>pom</packaging>
<modules>
<module>bs-library-web</module>
<module>bs-library-database</module>
</modules>
<!-- Control some versions of dependencies here, overriding the parent -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- All child libraries should use these dependencies -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,12 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-other</artifactId>
<packaging>jar</packaging>
</project>
@@ -0,0 +1,131 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
<packaging>pom</packaging>
<description>A Java example project to demonstrate a Java development stack with Maven, GitHub Actions, GitHub Package Registry and Azure.</description>
<modules>
<module>bs-libraries</module>
<module>bs-application</module>
<module>bs-other</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<!--
Dependency Versions
-->
<jetty.version>10.0.10</jetty.version>
<log4j.version>2.19.0</log4j.version>
<!--
Properties used to create a CD style version number for the Maven build
-->
<revision>1.0.0</revision>
<changelist></changelist>
<sha1>-SNAPSHOT</sha1>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-bom</artifactId>
<version>${jetty.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bs-library-web</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bs-library-logging</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>${log4j.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- This is overwritten in the bs-libraries versions -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- To enable debug compilation use the maven.compiler.debug user property -->
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>com.github.ekryd.echo-maven-plugin</groupId>
<artifactId>echo-maven-plugin</artifactId>
<version>1.3.2</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
@@ -1,21 +1,24 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>com.github.octodemo:bs-parent:>${revision}${changelist}${sha1}</parent>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-parent</artifactId>
<version</version>
<packaging>pom</packaging>
<modules>
<module>bs-library</module>
<module>bs-application</module>
</modules>
<artifactId>bs-application</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bs-library</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,24 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-library</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,12 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
</parent>
<artifactId>bs-other</artifactId>
<packaging>jar</packaging>
</project>
+17 -12
View File
@@ -11,6 +11,7 @@
<modules>
<module>bs-library</module>
<module>bs-application</module>
<module>bs-other</module>
</modules>
<properties>
@@ -22,8 +23,8 @@
<!--
Dependency Versions
-->
<jetty.version>10.0.0</jetty.version>
<log4j.version>2.17.2</log4j.version>
<jetty.version>10.0.10</jetty.version>
<log4j.version>2.19.0</log4j.version>
<!--
Properties used to create a CD style version number for the Maven build
@@ -42,20 +43,24 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bs-library</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>${log4j.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
+12
View File
@@ -0,0 +1,12 @@
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository/>
<interactiveMode/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>