This commit is contained in:
+14
@@ -11,6 +11,20 @@ inputs:
|
|||||||
type: string
|
type: string
|
||||||
default: ${{ github.workspace }}
|
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: ''
|
||||||
|
|
||||||
token:
|
token:
|
||||||
description: The GitHub token to use to submit the depedency snapshot to the repository
|
description: The GitHub token to use to submit the depedency snapshot to the repository
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
Vendored
+285
-82
@@ -2,38 +2,15 @@ require('./sourcemap-register.js');/******/ (() => { // webpackBootstrap
|
|||||||
/******/ var __webpack_modules__ = ({
|
/******/ var __webpack_modules__ = ({
|
||||||
|
|
||||||
/***/ 8047:
|
/***/ 8047:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
||||||
|
|
||||||
"use strict";
|
"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 }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.artifactToPackageURL = exports.parseDependencyJson = exports.MavenDependencyGraph = void 0;
|
exports.artifactToPackageURL = exports.parseDependencyJson = exports.MavenDependencyGraph = void 0;
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
|
||||||
const packageurl_js_1 = __nccwpck_require__(8915);
|
const packageurl_js_1 = __nccwpck_require__(8915);
|
||||||
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
|
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
|
||||||
|
const file_utils_1 = __nccwpck_require__(799);
|
||||||
class MavenDependencyGraph {
|
class MavenDependencyGraph {
|
||||||
constructor(graph) {
|
constructor(graph) {
|
||||||
this.depGraph = graph;
|
this.depGraph = graph;
|
||||||
@@ -83,9 +60,10 @@ class MavenDependencyGraph {
|
|||||||
parseDependencies() {
|
parseDependencies() {
|
||||||
const graph = this.depGraph;
|
const graph = this.depGraph;
|
||||||
const cache = this.cache;
|
const cache = this.cache;
|
||||||
|
const dependencies = graph.dependencies || [];
|
||||||
const rootArtifactIds = [];
|
const rootArtifactIds = [];
|
||||||
const dependencyIdMap = dependencyMap(graph.dependencies);
|
const dependencyIdMap = dependencyMap(dependencies);
|
||||||
const dependencyArtifactIdsWithParents = extractDependencyArtifactIdsWithParents(graph.dependencies);
|
const dependencyArtifactIdsWithParents = extractDependencyArtifactIdsWithParents(dependencies);
|
||||||
const idToPackageCachePackage = new Map();
|
const idToPackageCachePackage = new Map();
|
||||||
// Create the packages for all known artifacts
|
// Create the packages for all known artifacts
|
||||||
graph.artifacts.forEach((artifact) => {
|
graph.artifacts.forEach((artifact) => {
|
||||||
@@ -118,7 +96,7 @@ class MavenDependencyGraph {
|
|||||||
});
|
});
|
||||||
const uniqueRootArtifactDependencies = [];
|
const uniqueRootArtifactDependencies = [];
|
||||||
rootArtifactIds.forEach(rootArtifactId => {
|
rootArtifactIds.forEach(rootArtifactId => {
|
||||||
const dependencyIds = getDirectDependencies(rootArtifactId, graph.dependencies);
|
const dependencyIds = getDirectDependencies(rootArtifactId, dependencies);
|
||||||
if (dependencyIds) {
|
if (dependencyIds) {
|
||||||
dependencyIds.forEach(dependencyId => {
|
dependencyIds.forEach(dependencyId => {
|
||||||
if (uniqueRootArtifactDependencies.indexOf(dependencyId) === -1) {
|
if (uniqueRootArtifactDependencies.indexOf(dependencyId) === -1) {
|
||||||
@@ -132,19 +110,22 @@ class MavenDependencyGraph {
|
|||||||
}
|
}
|
||||||
exports.MavenDependencyGraph = MavenDependencyGraph;
|
exports.MavenDependencyGraph = MavenDependencyGraph;
|
||||||
function parseDependencyJson(file, isMultiModule = false) {
|
function parseDependencyJson(file, isMultiModule = false) {
|
||||||
|
const data = (0, file_utils_1.loadFileContents)(file);
|
||||||
|
if (!data) {
|
||||||
|
return {
|
||||||
|
graphName: 'empty',
|
||||||
|
artifacts: [],
|
||||||
|
dependencies: [],
|
||||||
|
isMultiModule: isMultiModule
|
||||||
|
};
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const data = fs.readFileSync(file);
|
const depGraph = JSON.parse(data);
|
||||||
try {
|
depGraph.isMultiModule = isMultiModule;
|
||||||
const depGraph = JSON.parse(data.toString('utf-8'));
|
return depGraph;
|
||||||
depGraph.isMultiModule = isMultiModule;
|
|
||||||
return depGraph;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
throw new Error(`Failed to parse JSON payload: ${err.message}`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (err) {
|
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;
|
exports.parseDependencyJson = parseDependencyJson;
|
||||||
@@ -164,19 +145,24 @@ function getDependencyScopeForMavenScope(mavenScopes) {
|
|||||||
return 'runtime';
|
return 'runtime';
|
||||||
}
|
}
|
||||||
function extractDependencyArtifactIdsWithParents(dependencies) {
|
function extractDependencyArtifactIdsWithParents(dependencies) {
|
||||||
return dependencies.map(dependency => { return dependency.to; });
|
if (dependencies) {
|
||||||
|
return dependencies.map(dependency => { return dependency.to; });
|
||||||
|
}
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
function dependencyMap(dependencies) {
|
function dependencyMap(dependencies) {
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
dependencies.forEach(dependency => {
|
if (dependencies) {
|
||||||
const fromUrl = dependency.from;
|
dependencies.forEach(dependency => {
|
||||||
let deps = map[fromUrl];
|
const fromUrl = dependency.from;
|
||||||
if (!deps) {
|
let deps = map[fromUrl];
|
||||||
deps = [];
|
if (!deps) {
|
||||||
map[fromUrl] = deps;
|
deps = [];
|
||||||
}
|
map[fromUrl] = deps;
|
||||||
deps.push(dependency.to);
|
}
|
||||||
});
|
deps.push(dependency.to);
|
||||||
|
});
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
function getDirectDependencies(artifactId, dependencies) {
|
function getDirectDependencies(artifactId, dependencies) {
|
||||||
@@ -233,7 +219,12 @@ function run() {
|
|||||||
let snapshot;
|
let snapshot;
|
||||||
try {
|
try {
|
||||||
const directory = core.getInput('directory', { required: true });
|
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') || '',
|
||||||
|
};
|
||||||
|
snapshot = yield (0, snapshot_generator_1.generateSnapshot)(directory, mavenConfig);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
core.error(err);
|
core.error(err);
|
||||||
@@ -254,6 +245,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:
|
/***/ 2963:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
@@ -293,17 +438,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||||
exports.generateDependencyGraph = exports.generateSnapshot = void 0;
|
exports.generateDependencyGraph = exports.generateSnapshot = void 0;
|
||||||
const exec = __importStar(__nccwpck_require__(1514));
|
|
||||||
const core = __importStar(__nccwpck_require__(2186));
|
const core = __importStar(__nccwpck_require__(2186));
|
||||||
const path = __importStar(__nccwpck_require__(1017));
|
const path = __importStar(__nccwpck_require__(1017));
|
||||||
const fs = __importStar(__nccwpck_require__(7147));
|
|
||||||
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
|
const dependency_submission_toolkit_1 = __nccwpck_require__(9810);
|
||||||
const depgraph_1 = __nccwpck_require__(8047);
|
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);
|
const version = (__nccwpck_require__(2876)/* .version */ .i8);
|
||||||
const DEPGRAPH_MAVEN_PLUGIN_VERSION = '4.0.2';
|
const DEPGRAPH_MAVEN_PLUGIN_VERSION = '4.0.2';
|
||||||
function generateSnapshot(directory, context, job) {
|
function generateSnapshot(directory, mvnConfig, context, job) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const depgraph = yield generateDependencyGraph(directory);
|
const depgraph = yield generateDependencyGraph(directory, mvnConfig);
|
||||||
try {
|
try {
|
||||||
const mavenDependencies = new depgraph_1.MavenDependencyGraph(depgraph);
|
const mavenDependencies = new depgraph_1.MavenDependencyGraph(depgraph);
|
||||||
// The filepath to the POM needs to be relative to the root of the GitHub repository for the links to work once uploaded
|
// The filepath to the POM needs to be relative to the root of the GitHub repository for the links to work once uploaded
|
||||||
@@ -327,42 +472,36 @@ function getDetector() {
|
|||||||
version: version
|
version: version
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function generateDependencyGraph(directory) {
|
function generateDependencyGraph(directory, config) {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
try {
|
try {
|
||||||
let executionOutput = '';
|
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);
|
||||||
let errors = '';
|
|
||||||
const options = {
|
|
||||||
cwd: directory,
|
|
||||||
listeners: {
|
|
||||||
stdout: (data) => {
|
|
||||||
executionOutput += data.toString();
|
|
||||||
},
|
|
||||||
stderr: (data) => {
|
|
||||||
errors += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
core.startGroup('depgraph-maven-plugin:reactor');
|
core.startGroup('depgraph-maven-plugin:reactor');
|
||||||
const mavenReactorArguments = [
|
const mavenReactorArguments = [
|
||||||
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:reactor`,
|
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:reactor`,
|
||||||
'-DgraphFormat=json',
|
'-DgraphFormat=json',
|
||||||
'-DoutputFileName=reactor.json'
|
'-DoutputFileName=reactor.json'
|
||||||
];
|
];
|
||||||
yield exec.exec('mvn', mavenReactorArguments, options);
|
const reactorResults = yield mvn.exec(directory, mavenReactorArguments);
|
||||||
core.info(executionOutput);
|
core.info(reactorResults.stdout);
|
||||||
core.info(errors);
|
core.info(reactorResults.stderr);
|
||||||
core.endGroup();
|
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');
|
core.startGroup('depgraph-maven-plugin:aggregate');
|
||||||
const mavenAggregateArguments = [
|
const mavenAggregateArguments = [
|
||||||
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:aggregate`,
|
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:aggregate`,
|
||||||
'-DgraphFormat=json',
|
'-DgraphFormat=json',
|
||||||
'-DoutputFileName=aggregate-depgraph.json'
|
'-DoutputFileName=aggregate-depgraph.json'
|
||||||
];
|
];
|
||||||
yield exec.exec('mvn', mavenAggregateArguments, options);
|
const aggregateResults = yield mvn.exec(directory, mavenAggregateArguments);
|
||||||
core.info(executionOutput);
|
core.info(aggregateResults.stdout);
|
||||||
core.info(errors);
|
core.info(aggregateResults.stderr);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
|
if (aggregateResults.exitCode !== 0) {
|
||||||
|
throw new Error(`Failed to successfully dependency results with Maven, exit code: ${aggregateResults.exitCode}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
core.error(err);
|
core.error(err);
|
||||||
@@ -371,22 +510,22 @@ function generateDependencyGraph(directory) {
|
|||||||
const targetPath = path.join(directory, 'target');
|
const targetPath = path.join(directory, 'target');
|
||||||
const isMultiModule = checkForMultiModule(path.join(targetPath, 'reactor.json'));
|
const isMultiModule = checkForMultiModule(path.join(targetPath, 'reactor.json'));
|
||||||
// Now we have the aggregate dependency graph file to process
|
// Now we have the aggregate dependency graph file to process
|
||||||
const file = path.join(targetPath, 'aggregate-depgraph.json');
|
const aggregateGraphFile = path.join(targetPath, 'aggregate-depgraph.json');
|
||||||
try {
|
try {
|
||||||
return (0, depgraph_1.parseDependencyJson)(file, isMultiModule);
|
return (0, depgraph_1.parseDependencyJson)(aggregateGraphFile, isMultiModule);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
core.error(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;
|
exports.generateDependencyGraph = generateDependencyGraph;
|
||||||
function checkForMultiModule(reactorJsonFile) {
|
function checkForMultiModule(reactorJsonFile) {
|
||||||
try {
|
const data = (0, file_utils_1.loadFileContents)(reactorJsonFile);
|
||||||
const data = fs.readFileSync(reactorJsonFile);
|
if (data) {
|
||||||
try {
|
try {
|
||||||
const reactor = JSON.parse(data.toString('utf-8'));
|
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
|
// 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;
|
return reactor.artifacts && reactor.artifacts.length > 0;
|
||||||
}
|
}
|
||||||
@@ -394,9 +533,8 @@ function checkForMultiModule(reactorJsonFile) {
|
|||||||
throw new Error(`Failed to parse reactor JSON payload: ${err.message}`);
|
throw new Error(`Failed to parse reactor JSON payload: ${err.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
// If no data report that it is not a multi module project
|
||||||
throw new Error(`Failed to load file ${reactorJsonFile}: ${err}`);
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// TODO this is assuming the checkout was made into the base path of the workspace...
|
// TODO this is assuming the checkout was made into the base path of the workspace...
|
||||||
function getRepositoryRelativePath(file) {
|
function getRepositoryRelativePath(file) {
|
||||||
@@ -414,6 +552,71 @@ function getRepositoryRelativePath(file) {
|
|||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ 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:
|
/***/ 7351:
|
||||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+39
-27
@@ -1,17 +1,16 @@
|
|||||||
import * as fs from 'fs';
|
|
||||||
|
|
||||||
import { PackageURL } from 'packageurl-js'
|
import { PackageURL } from 'packageurl-js'
|
||||||
import { PackageCache, Package, Manifest } from '@github/dependency-submission-toolkit';
|
import { PackageCache, Package, Manifest } from '@github/dependency-submission-toolkit';
|
||||||
import { DependencyScope } from '@github/dependency-submission-toolkit/dist/manifest';
|
import { DependencyScope } from '@github/dependency-submission-toolkit/dist/manifest';
|
||||||
|
import { loadFileContents } from './utils/file-utils';
|
||||||
|
|
||||||
type Depgraph = {
|
export type Depgraph = {
|
||||||
graphName: string,
|
graphName: string,
|
||||||
artifacts: DepgraphArtifact[],
|
artifacts: DepgraphArtifact[],
|
||||||
dependencies: DepgraphDependency[],
|
dependencies: DepgraphDependency[],
|
||||||
isMultiModule: boolean,
|
isMultiModule: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
type DepgraphArtifact = {
|
export type DepgraphArtifact = {
|
||||||
id: string,
|
id: string,
|
||||||
numericId: number,
|
numericId: number,
|
||||||
groupId: string,
|
groupId: string,
|
||||||
@@ -22,7 +21,7 @@ type DepgraphArtifact = {
|
|||||||
types?: string[],
|
types?: string[],
|
||||||
}
|
}
|
||||||
|
|
||||||
type DepgraphDependency = {
|
export type DepgraphDependency = {
|
||||||
from: string,
|
from: string,
|
||||||
to: string,
|
to: string,
|
||||||
numericFrom: number,
|
numericFrom: number,
|
||||||
@@ -102,9 +101,11 @@ export class MavenDependencyGraph {
|
|||||||
const graph = this.depGraph;
|
const graph = this.depGraph;
|
||||||
const cache = this.cache;
|
const cache = this.cache;
|
||||||
|
|
||||||
|
const dependencies = graph.dependencies || [];
|
||||||
|
|
||||||
const rootArtifactIds: string[] = [];
|
const rootArtifactIds: string[] = [];
|
||||||
const dependencyIdMap = dependencyMap(graph.dependencies);
|
const dependencyIdMap = dependencyMap(dependencies);
|
||||||
const dependencyArtifactIdsWithParents = extractDependencyArtifactIdsWithParents(graph.dependencies);
|
const dependencyArtifactIdsWithParents = extractDependencyArtifactIdsWithParents(dependencies);
|
||||||
const idToPackageCachePackage: Map<string, Package> = new Map<string, Package>();
|
const idToPackageCachePackage: Map<string, Package> = new Map<string, Package>();
|
||||||
|
|
||||||
// Create the packages for all known artifacts
|
// Create the packages for all known artifacts
|
||||||
@@ -145,7 +146,7 @@ export class MavenDependencyGraph {
|
|||||||
|
|
||||||
const uniqueRootArtifactDependencies: string[] = [];
|
const uniqueRootArtifactDependencies: string[] = [];
|
||||||
rootArtifactIds.forEach(rootArtifactId => {
|
rootArtifactIds.forEach(rootArtifactId => {
|
||||||
const dependencyIds = getDirectDependencies(rootArtifactId, graph.dependencies);
|
const dependencyIds = getDirectDependencies(rootArtifactId, dependencies);
|
||||||
if (dependencyIds) {
|
if (dependencyIds) {
|
||||||
dependencyIds.forEach(dependencyId => {
|
dependencyIds.forEach(dependencyId => {
|
||||||
if (uniqueRootArtifactDependencies.indexOf(dependencyId) === -1) {
|
if (uniqueRootArtifactDependencies.indexOf(dependencyId) === -1) {
|
||||||
@@ -160,17 +161,23 @@ export class MavenDependencyGraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parseDependencyJson(file: string, isMultiModule: boolean = false): Depgraph {
|
export function parseDependencyJson(file: string, isMultiModule: boolean = false): Depgraph {
|
||||||
|
const data = loadFileContents(file);
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return {
|
||||||
|
graphName: 'empty',
|
||||||
|
artifacts: [],
|
||||||
|
dependencies: [],
|
||||||
|
isMultiModule: isMultiModule
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data: Buffer = fs.readFileSync(file);
|
const depGraph: Depgraph = JSON.parse(data);
|
||||||
try {
|
depGraph.isMultiModule = isMultiModule;
|
||||||
const depGraph: Depgraph = JSON.parse(data.toString('utf-8'));
|
return depGraph;
|
||||||
depGraph.isMultiModule = isMultiModule;
|
|
||||||
return depGraph;
|
|
||||||
} catch (err: any) {
|
|
||||||
throw new Error(`Failed to parse JSON payload: ${err.message}`);
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new Error(`Failed to load file ${file}: ${err}`);
|
throw new Error(`Failed to parse JSON dependency data: ${err.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,23 +206,28 @@ function getDependencyScopeForMavenScope(mavenScopes: string[] | undefined | nul
|
|||||||
}
|
}
|
||||||
|
|
||||||
function extractDependencyArtifactIdsWithParents(dependencies: DepgraphDependency[]): string[] {
|
function extractDependencyArtifactIdsWithParents(dependencies: DepgraphDependency[]): string[] {
|
||||||
return dependencies.map(dependency => { return dependency.to; })
|
if (dependencies) {
|
||||||
|
return dependencies.map(dependency => { return dependency.to; })
|
||||||
|
}
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function dependencyMap(dependencies: DepgraphDependency[]): Map<string, string[] | undefined> {
|
function dependencyMap(dependencies: DepgraphDependency[]): Map<string, string[] | undefined> {
|
||||||
const map = new Map<string, string[]>();
|
const map = new Map<string, string[]>();
|
||||||
|
|
||||||
dependencies.forEach(dependency => {
|
if (dependencies) {
|
||||||
const fromUrl = dependency.from;
|
dependencies.forEach(dependency => {
|
||||||
|
const fromUrl = dependency.from;
|
||||||
|
|
||||||
let deps = map[fromUrl];
|
let deps = map[fromUrl];
|
||||||
if (!deps) {
|
if (!deps) {
|
||||||
deps = [];
|
deps = [];
|
||||||
map[fromUrl] = deps;
|
map[fromUrl] = deps;
|
||||||
}
|
}
|
||||||
|
|
||||||
deps.push(dependency.to);
|
deps.push(dependency.to);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ async function execute() {
|
|||||||
id: `${opts.runId || Date.now()}`
|
id: `${opts.runId || Date.now()}`
|
||||||
};
|
};
|
||||||
|
|
||||||
snapshot = await generateSnapshot(opts.directory, context, job);
|
const mvnConfig = {};
|
||||||
|
|
||||||
|
snapshot = await generateSnapshot(opts.directory, mvnConfig, context, job);
|
||||||
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
|
console.error(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
|
||||||
|
|||||||
+6
-2
@@ -2,14 +2,18 @@ import * as core from '@actions/core';
|
|||||||
import {Snapshot, submitSnapshot} from '@github/dependency-submission-toolkit';
|
import {Snapshot, submitSnapshot} from '@github/dependency-submission-toolkit';
|
||||||
import { generateSnapshot } from './snapshot-generator';
|
import { generateSnapshot } from './snapshot-generator';
|
||||||
|
|
||||||
|
|
||||||
async function run() {
|
async function run() {
|
||||||
let snapshot: Snapshot | undefined;
|
let snapshot: Snapshot | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const directory = core.getInput('directory', { required: true });
|
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') || '',
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshot = await generateSnapshot(directory, mavenConfig);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
core.error(err);
|
core.error(err);
|
||||||
core.setFailed(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
|
core.setFailed(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
|
||||||
|
|||||||
@@ -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)}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
import * as exec from '@actions/exec';
|
||||||
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
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';
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as path from 'path';
|
import { getMavenProjectDirectory } from './utils/test-util';
|
||||||
import { generateDependencyGraph, generateSnapshot } from './snapshot-generator';
|
import { generateDependencyGraph, generateSnapshot } from './snapshot-generator';
|
||||||
|
|
||||||
describe('snapshot-generator', () => {
|
describe('snapshot-generator', () => {
|
||||||
@@ -42,9 +42,14 @@ describe('snapshot-generator', () => {
|
|||||||
expect(snapshot.detector.version).toBe(version);
|
expect(snapshot.detector.version).toBe(version);
|
||||||
expect(snapshot.manifests['bs-parent'].countDependencies()).toBe(20);
|
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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function getMavenProjectDirectory(name: string): string {
|
|
||||||
return path.join(__dirname, '..', 'test-data', 'maven', name);
|
|
||||||
}
|
|
||||||
+38
-36
@@ -1,18 +1,23 @@
|
|||||||
import * as exec from '@actions/exec';
|
|
||||||
import * as core from '@actions/core';
|
import * as core from '@actions/core';
|
||||||
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
|
||||||
|
|
||||||
import { Snapshot } from '@github/dependency-submission-toolkit';
|
import { Snapshot } from '@github/dependency-submission-toolkit';
|
||||||
import { MavenDependencyGraph, parseDependencyJson } from './depgraph';
|
import { Depgraph, MavenDependencyGraph, parseDependencyJson } from './depgraph';
|
||||||
|
import { MavenRunner } from './maven-runner';
|
||||||
|
import { loadFileContents } from './utils/file-utils';
|
||||||
|
|
||||||
const version = require('../package.json')['version'];
|
const version = require('../package.json')['version'];
|
||||||
|
|
||||||
const DEPGRAPH_MAVEN_PLUGIN_VERSION = '4.0.2';
|
const DEPGRAPH_MAVEN_PLUGIN_VERSION = '4.0.2';
|
||||||
|
|
||||||
export async function generateSnapshot(directory: string, context?: any, job?: any) {
|
export type MavenConfiguration = {
|
||||||
const depgraph = await generateDependencyGraph(directory);
|
ignoreMavenWrapper?: boolean;
|
||||||
|
settingsFile?: string;
|
||||||
|
mavenArgs?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function generateSnapshot(directory: string, mvnConfig?: MavenConfiguration, context?: any, job?: any) {
|
||||||
|
const depgraph = await generateDependencyGraph(directory, mvnConfig);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const mavenDependencies = new MavenDependencyGraph(depgraph);
|
const mavenDependencies = new MavenDependencyGraph(depgraph);
|
||||||
@@ -37,22 +42,9 @@ function getDetector() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateDependencyGraph(directory: string) {
|
export async function generateDependencyGraph(directory: string, config?: MavenConfiguration): Promise<Depgraph> {
|
||||||
try {
|
try {
|
||||||
let executionOutput = '';
|
const mvn = new MavenRunner(directory, config?.settingsFile, config?.ignoreMavenWrapper);
|
||||||
let errors = '';
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
cwd: directory,
|
|
||||||
listeners: {
|
|
||||||
stdout: (data: Buffer) => {
|
|
||||||
executionOutput += data.toString();
|
|
||||||
},
|
|
||||||
stderr: (data: Buffer) => {
|
|
||||||
errors += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
core.startGroup('depgraph-maven-plugin:reactor');
|
core.startGroup('depgraph-maven-plugin:reactor');
|
||||||
const mavenReactorArguments = [
|
const mavenReactorArguments = [
|
||||||
@@ -60,23 +52,31 @@ export async function generateDependencyGraph(directory: string) {
|
|||||||
'-DgraphFormat=json',
|
'-DgraphFormat=json',
|
||||||
'-DoutputFileName=reactor.json'
|
'-DoutputFileName=reactor.json'
|
||||||
];
|
];
|
||||||
await exec.exec('mvn', mavenReactorArguments, options);
|
const reactorResults = await mvn.exec(directory, mavenReactorArguments);
|
||||||
|
|
||||||
core.info(executionOutput);
|
core.info(reactorResults.stdout);
|
||||||
core.info(errors);
|
core.info(reactorResults.stderr);
|
||||||
core.endGroup();
|
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');
|
core.startGroup('depgraph-maven-plugin:aggregate');
|
||||||
const mavenAggregateArguments = [
|
const mavenAggregateArguments = [
|
||||||
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:aggregate`,
|
`com.github.ferstl:depgraph-maven-plugin:${DEPGRAPH_MAVEN_PLUGIN_VERSION}:aggregate`,
|
||||||
'-DgraphFormat=json',
|
'-DgraphFormat=json',
|
||||||
'-DoutputFileName=aggregate-depgraph.json'
|
'-DoutputFileName=aggregate-depgraph.json'
|
||||||
];
|
];
|
||||||
await exec.exec('mvn', mavenAggregateArguments, options);
|
const aggregateResults = await mvn.exec(directory, mavenAggregateArguments);
|
||||||
|
|
||||||
core.info(executionOutput);
|
core.info(aggregateResults.stdout);
|
||||||
core.info(errors);
|
core.info(aggregateResults.stderr);
|
||||||
core.endGroup();
|
core.endGroup();
|
||||||
|
|
||||||
|
if (aggregateResults.exitCode !== 0) {
|
||||||
|
throw new Error(`Failed to successfully dependency results with Maven, exit code: ${aggregateResults.exitCode}`);
|
||||||
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
core.error(err);
|
core.error(err);
|
||||||
throw new Error(`A problem was encountered generating dependency files, please check execution logs for details; ${err.message}`);
|
throw new Error(`A problem was encountered generating dependency files, please check execution logs for details; ${err.message}`);
|
||||||
@@ -86,28 +86,30 @@ export async function generateDependencyGraph(directory: string) {
|
|||||||
const isMultiModule = checkForMultiModule(path.join(targetPath, 'reactor.json'));
|
const isMultiModule = checkForMultiModule(path.join(targetPath, 'reactor.json'));
|
||||||
|
|
||||||
// Now we have the aggregate dependency graph file to process
|
// Now we have the aggregate dependency graph file to process
|
||||||
const file = path.join(targetPath, 'aggregate-depgraph.json');
|
const aggregateGraphFile = path.join(targetPath, 'aggregate-depgraph.json');
|
||||||
try {
|
try {
|
||||||
return parseDependencyJson(file, isMultiModule);
|
return parseDependencyJson(aggregateGraphFile, isMultiModule);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
core.error(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}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkForMultiModule(reactorJsonFile) {
|
function checkForMultiModule(reactorJsonFile): boolean {
|
||||||
try {
|
const data = loadFileContents(reactorJsonFile);
|
||||||
const data: Buffer = fs.readFileSync(reactorJsonFile);
|
|
||||||
|
if (data) {
|
||||||
try {
|
try {
|
||||||
const reactor = JSON.parse(data.toString('utf-8'));
|
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
|
// 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;
|
return reactor.artifacts && reactor.artifacts.length > 0;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new Error(`Failed to parse reactor JSON payload: ${err.message}`);
|
throw new Error(`Failed to parse reactor JSON payload: ${err.message}`);
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
|
||||||
throw new Error(`Failed to load file ${reactorJsonFile}: ${err}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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...
|
// TODO this is assuming the checkout was made into the base path of the workspace...
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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');
|
||||||
|
}
|
||||||
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
@@ -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
@@ -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%
|
||||||
@@ -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,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>
|
||||||
Reference in New Issue
Block a user