@jnxplus/nx-maven
Version:
[](https://badge.fury.io/js/@jnxplus%2Fnx-maven)
342 lines • 14.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getWorkspaceData = getWorkspaceData;
exports.getCachedWorkspaceData = getCachedWorkspaceData;
exports.removeWorkspaceDataCache = removeWorkspaceDataCache;
exports.addProjects = addProjects;
exports.getEffectiveVersion = getEffectiveVersion;
exports.validateTargetInputs = validateTargetInputs;
exports.getProject = getProject;
exports.getOutputDirLocalRepo = getOutputDirLocalRepo;
exports.getTask = getTask;
exports.ifOutputDirLocalRepoNotPresent = ifOutputDirLocalRepoNotPresent;
const xml_1 = require("@jnxplus/xml");
const devkit_1 = require("@nx/devkit");
const flatCache = require("flat-cache");
const fs_1 = require("fs");
const cache_directory_1 = require("nx/src/utils/cache-directory");
const path = require("path");
const utils_1 = require("../utils");
const cacheId = 'workspace-data.json';
const cacheDirectory = path.join(cache_directory_1.workspaceDataDirectory, 'nx-maven');
const cache = flatCache.create({
cacheId: cacheId,
cacheDir: cacheDirectory,
ttl: 60 * 60 * 1000,
});
const key = 'workspace-data';
function getWorkspaceData(opts) {
var _a;
const mavenRootDirectory = (opts === null || opts === void 0 ? void 0 : opts.mavenRootDirectory)
? opts.mavenRootDirectory
: '';
const mavenRootDirAbsolutePath = path.join(devkit_1.workspaceRoot, mavenRootDirectory);
const skipProjectWithoutProjectJson = ((_a = opts === null || opts === void 0 ? void 0 : opts.graphOptions) === null || _a === void 0 ? void 0 : _a.skipProjectWithoutProjectJson)
? opts.graphOptions.skipProjectWithoutProjectJson
: false;
const projects = [];
addProjects(skipProjectWithoutProjectJson, mavenRootDirAbsolutePath, projects, '');
//TODO calculate versions here
const localRepositoryPath = (0, utils_1.getLocalRepositoryPath)(opts, mavenRootDirAbsolutePath);
const data = {
mavenRootDirAbsolutePath: mavenRootDirAbsolutePath,
targetDefaults: getTargetDefaults(),
localRepo: localRepositoryPath,
projects: projects,
};
// Store data in cache for future use
cache.setKey(key, data);
cache.save();
return data;
}
function getCachedWorkspaceData() {
return cache.getKey(key);
}
function removeWorkspaceDataCache() {
flatCache.clearCacheById(cacheId, cacheDirectory);
}
function addProjects(skipProjectWithoutProjectJson, mavenRootDirAbsolutePath, projects, projectRelativePath, aggregatorProjectArtifactId) {
//projectAbsolutePath
const projectAbsolutePath = path.join(mavenRootDirAbsolutePath, projectRelativePath);
const pomXmlPath = path.join(projectAbsolutePath, 'pom.xml');
const pomXmlContent = (0, xml_1.readXml)(pomXmlPath);
const artifactId = (0, utils_1.getArtifactId)(pomXmlContent);
const groupId = (0, utils_1.getGroupId)(artifactId, pomXmlContent);
const version = (0, utils_1.getVersion)(artifactId, pomXmlContent);
const isRootProject = !aggregatorProjectArtifactId;
const isPomPackaging = isPomPackagingFunction(pomXmlContent);
const projectRoot = getProjectRoot(projectAbsolutePath);
const parentProjectArtifactId = getParentProjectName(pomXmlContent);
const dependencies = getDependencyArtifactIds(pomXmlContent);
const profileDependencies = getProfileDependencyArtifactIds(pomXmlContent);
const pluginDependencies = getPluginDependencyArtifactIds(pomXmlContent);
const properties = getProperties(pomXmlContent);
const projectJsonPath = path.join(projectAbsolutePath, 'project.json');
const skipProject = skipProjectWithoutProjectJson && !(0, fs_1.existsSync)(projectJsonPath);
projects.push({
artifactId: artifactId,
groupId: groupId,
version: version,
isRootProject: isRootProject,
isPomPackaging: isPomPackaging,
projectRoot: projectRoot,
projectAbsolutePath: projectAbsolutePath,
dependencies: dependencies,
profileDependencies: profileDependencies,
pluginDependencies: pluginDependencies,
parentProjectArtifactId: parentProjectArtifactId,
aggregatorProjectArtifactId: aggregatorProjectArtifactId,
properties: properties,
skipProject: skipProject,
});
const modulesXmlElement = pomXmlContent.childNamed('modules');
if (modulesXmlElement === undefined) {
return;
}
const moduleXmlElementArray = modulesXmlElement.childrenNamed('module');
if (moduleXmlElementArray.length === 0) {
return;
}
for (const moduleXmlElement of moduleXmlElementArray) {
const moduleRelativePath = (0, devkit_1.joinPathFragments)(projectRelativePath, moduleXmlElement.val.trim());
addProjects(skipProjectWithoutProjectJson, mavenRootDirAbsolutePath, projects, moduleRelativePath, artifactId);
}
}
function getProjectRoot(projectAbsolutePath) {
let projectRoot = (0, devkit_1.normalizePath)(path.relative(devkit_1.workspaceRoot, projectAbsolutePath));
// projectRoot should not be an empty string
if (!projectRoot) {
projectRoot = '.';
}
return projectRoot;
}
function getParentProjectName(pomXmlContent) {
var _a, _b;
const parentXmlElement = pomXmlContent.childNamed('parent');
if (parentXmlElement === undefined) {
return undefined;
}
const relativePath = (_a = parentXmlElement.childNamed('relativePath')) === null || _a === void 0 ? void 0 : _a.val;
if (!relativePath) {
return undefined;
}
return (_b = parentXmlElement.childNamed('artifactId')) === null || _b === void 0 ? void 0 : _b.val;
}
function getDependencyArtifactIds(pomXml) {
const dependenciesXml = pomXml.childNamed('dependencies');
if (dependenciesXml === undefined) {
return [];
}
return dependenciesXml
.childrenNamed('dependency')
.filter((dependencyXmlElement) => {
var _a;
const groupId = (_a = dependencyXmlElement.childNamed('groupId')) === null || _a === void 0 ? void 0 : _a.val;
return (groupId !== 'org.springframework.boot' &&
groupId !== 'io.quarkus' &&
groupId !== 'io.micronaut');
})
.map((dependencyXmlElement) => {
var _a;
return (_a = dependencyXmlElement.childNamed('artifactId')) === null || _a === void 0 ? void 0 : _a.val;
});
}
function isPomPackagingFunction(pomXmlContent) {
const packagingXml = pomXmlContent.childNamed('packaging');
if (packagingXml === undefined) {
return false;
}
return packagingXml.val === 'pom';
}
function getEffectiveVersion(project, workspaceData) {
let newVersion = project.version;
//1 if version is constant return it
if (isConstantVersion(newVersion)) {
return newVersion;
}
//2 try to calculate version from project properties
newVersion = getVersionFromProperties(newVersion, project.properties);
if (isConstantVersion(newVersion)) {
return newVersion;
}
//3 try to calculate version from parent project
// we just calculate the part we didn't calculate in step 2
newVersion = getVersionFromParentProject(newVersion, project.parentProjectArtifactId, workspaceData.projects);
if (isConstantVersion(newVersion)) {
return newVersion;
}
//4 Can't calculate version, maybe contains something like ${project.parent.version}
// call help:evaluate to get version and add warning because help:evaluate took a lot of time
devkit_1.logger.warn(`Can't calculate version ${newVersion} of project ${project.artifactId} without using mvn help:evaluate that take a lot of time. Please Open an issue to address this case.`);
return (0, utils_1.getExpressionValue)('project.version', workspaceData.mavenRootDirAbsolutePath, project.artifactId);
}
function getVersionFromParentProject(newVersion, parentProjectArtifactId, projects) {
if (!parentProjectArtifactId) {
return newVersion;
}
const parentProject = getProject(projects, parentProjectArtifactId);
newVersion = getVersionFromProperties(newVersion, parentProject.properties);
if (isConstantVersion(newVersion)) {
return newVersion;
}
return getVersionFromParentProject(newVersion, parentProject.parentProjectArtifactId, projects);
}
function validateTargetInputs(targetName, file, inputs) {
if ((inputs !== null && inputs !== void 0 ? inputs : []).some((element) => typeof element === 'string' &&
element === '{options.outputDirLocalRepo}')) {
throw new Error(`"{options.outputDirLocalRepo}" is not allowed in target inputs. To make it works, remove it from "${targetName}" target in "${file}" file. If you have a valid use case, please open an issue.`);
}
}
function getTargetDefaults() {
var _a;
const targetDefaults = [];
const nxJsonPath = path.join(devkit_1.workspaceRoot, 'nx.json');
const nxJson = (0, devkit_1.readJsonFile)(nxJsonPath);
if (nxJson.targetDefaults) {
for (const [targetName, target] of Object.entries(nxJson.targetDefaults)) {
validateTargetInputs(targetName, 'nx.json', target.inputs);
if (((_a = target.outputs) !== null && _a !== void 0 ? _a : []).some((element) => element === '{options.outputDirLocalRepo}')) {
targetDefaults.push(targetName);
}
}
}
return targetDefaults;
}
function getProject(projects, artifactId) {
const project = projects.find((project) => project.artifactId === artifactId);
if (!project) {
throw new Error(`Project ${artifactId} not found`);
}
return project;
}
function isConstantVersion(version) {
const index = version.indexOf('${');
if (index >= 0) {
return false;
}
return true;
}
function getProperties(pomXmlContent) {
//properties
const propertiesXml = pomXmlContent.childNamed('properties');
const properties = [];
if (propertiesXml === undefined) {
return properties;
}
propertiesXml.eachChild((propertyXml) => {
properties.push({ key: propertyXml.name, value: propertyXml.val });
});
return properties;
}
function getVersionFromProperties(version, properties) {
if (properties.length === 0) {
return version;
}
const versionExpressions = extractExpressions(version);
if (versionExpressions.length === 0) {
throw new Error(`Version ${version} is a constant`);
}
const commonProperties = properties.filter((p) => versionExpressions.includes(p.key));
if (commonProperties.length === 0) {
return version;
}
let parsedVersion = version;
for (const property of commonProperties) {
parsedVersion = parsedVersion.replace('${' + property.key + '}', property.value);
}
if (version === parsedVersion) {
throw new Error(`Code not working properly: version ${version} and parsedVersion ${parsedVersion} should not be the same`);
}
return parsedVersion;
}
function extractExpressions(version) {
const expressionRegex = /\${([^${}]*)}/g;
const expressions = [];
let match;
while ((match = expressionRegex.exec(version)) !== null) {
expressions.push(match[1]);
}
const containsAnExpression = expressions.some((p) => p.indexOf('$') >= 0);
if (containsAnExpression) {
throw new Error(`Version ${version} not correctly parsed with regex ${expressionRegex}`);
}
return expressions;
}
function getProfileDependencyArtifactIds(pomXml) {
let results = [];
const profilesXml = pomXml.childNamed('profiles');
if (profilesXml === undefined) {
return [];
}
const profileXmlArray = profilesXml.childrenNamed('profile');
for (const profileXml of profileXmlArray) {
const dependenciesXml = profileXml.childNamed('dependencies');
if (dependenciesXml === undefined) {
continue;
}
const profileDependencyArtifactIds = dependenciesXml
.childrenNamed('dependency')
.map((dependencyXmlElement) => {
var _a;
return (_a = dependencyXmlElement.childNamed('artifactId')) === null || _a === void 0 ? void 0 : _a.val;
});
results = results.concat(profileDependencyArtifactIds);
}
return results;
}
function getPluginDependencyArtifactIds(pomXml) {
let results = [];
const buildXml = pomXml.childNamed('build');
if (buildXml === undefined) {
return [];
}
results = results.concat(getPluginDependencyArtifactIdsFromPluginsTag(buildXml));
const pluginManagementXml = buildXml.childNamed('pluginManagement');
if (pluginManagementXml === undefined) {
return results;
}
results = results.concat(getPluginDependencyArtifactIdsFromPluginsTag(pluginManagementXml));
return results;
}
function getPluginDependencyArtifactIdsFromPluginsTag(xmlElement) {
let results = [];
const pluginsXml = xmlElement.childNamed('plugins');
if (pluginsXml === undefined) {
return [];
}
const pluginXmlArray = pluginsXml.childrenNamed('plugin');
for (const profileXml of pluginXmlArray) {
const dependenciesXml = profileXml.childNamed('dependencies');
if (dependenciesXml === undefined) {
continue;
}
const pluginDependencyArtifactIds = dependenciesXml
.childrenNamed('dependency')
.map((dependencyXmlElement) => {
var _a;
return (_a = dependencyXmlElement.childNamed('artifactId')) === null || _a === void 0 ? void 0 : _a.val;
});
results = results.concat(pluginDependencyArtifactIds);
}
return results;
}
function getOutputDirLocalRepo(localRepositoryPath, groupId, artifactId, projectVersion) {
return path.join(localRepositoryPath, `${groupId.replace(new RegExp(/\./, 'g'), '/')}/${artifactId}/${projectVersion}`);
}
function getTask(isRootProject) {
if (isRootProject) {
return 'install -N';
}
return 'install';
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function ifOutputDirLocalRepoNotPresent(options) {
if (!options) {
return true;
}
if ('outputDirLocalRepo' in options) {
return false;
}
return true;
}
//# sourceMappingURL=graph-utils.js.map