@nxrocks/common-jvm
Version:
Common library to share code among the JVM-related plugins.
373 lines (357 loc) • 16.1 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.SPOTLESS_MAVEN_PLUGIN_VERSION = exports.SPOTLESS_MAVEN_PLUGIN_ARTIFACT_ID = exports.SPOTLESS_MAVEN_PLUGIN_GROUP_ID = void 0;
exports.hasMavenPlugin = hasMavenPlugin;
exports.hasMavenPluginInTree = hasMavenPluginInTree;
exports.hasMavenProperty = hasMavenProperty;
exports.addMavenPlugin = addMavenPlugin;
exports.removeMavenPlugin = removeMavenPlugin;
exports.addMavenProperty = addMavenProperty;
exports.getMavenSpotlessConfig = getMavenSpotlessConfig;
exports.addSpotlessMavenPlugin = addSpotlessMavenPlugin;
exports.hasMultiModuleMavenProjectInTree = hasMultiModuleMavenProjectInTree;
exports.hasMultiModuleMavenProject = hasMultiModuleMavenProject;
exports.hasMavenModuleInTree = hasMavenModuleInTree;
exports.hasMavenModule = hasMavenModule;
exports.addMavenModule = addMavenModule;
exports.initMavenParentModule = initMavenParentModule;
exports.getMavenModules = getMavenModules;
exports.getMavenWrapperFiles = getMavenWrapperFiles;
exports.hasMavenWrapperInTree = hasMavenWrapperInTree;
exports.hasMavenWrapper = hasMavenWrapper;
exports.getCoordinatesForMavenProjet = getCoordinatesForMavenProjet;
const index_1 = require("./index");
const fileutils_1 = require("@nx/workspace/src/utilities/fileutils");
const path_1 = require("path");
const common_1 = require("@nxrocks/common");
exports.SPOTLESS_MAVEN_PLUGIN_GROUP_ID = 'com.diffplug.spotless';
exports.SPOTLESS_MAVEN_PLUGIN_ARTIFACT_ID = 'spotless-maven-plugin';
exports.SPOTLESS_MAVEN_PLUGIN_VERSION = '2.23.0';
function readPomXml(tree, rootFolder) {
const pomFile = `./${rootFolder}/pom.xml`;
const pomXmlStr = tree.read(pomFile, 'utf-8');
return pomXmlStr !== null ? (0, index_1.readXml)(pomXmlStr) : null;
}
function hasMavenPlugin(cwd, groupId, artifactId, version) {
const pomXmlStr = (0, common_1.getProjectFileContent)({ root: cwd }, `pom.xml`);
const pomXml = (0, index_1.readXml)(pomXmlStr);
return hasMavenPluginBase(pomXml, groupId, artifactId, version);
}
function hasMavenPluginInTree(tree, rootFolder, groupId, artifactId, version) {
const pomXml = readPomXml(tree, rootFolder);
return hasMavenPluginBase(pomXml, groupId, artifactId, version);
}
function hasMavenPluginBase(pomXml, groupId, artifactId, version) {
if (pomXml === null)
return false;
let pluginXPath = `/project/build/plugins/plugin/groupId/text()[.="${groupId}"]/../../artifactId/text()[.="${artifactId}"]`;
if (version) {
pluginXPath += `/../../version/text()[.="${version}"]`;
}
return (0, index_1.hasXmlMatching)(pomXml, pluginXPath);
}
function hasMavenProperty(tree, rootFolder, property, value) {
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
const propertyXPath = value
? `/project/properties/${property}/text()[.="${value}"]`
: `/project/properties/${property}`;
return (0, index_1.hasXmlMatching)(pomXml, propertyXPath);
}
function addMavenPlugin(tree, rootFolder, groupId, artifactId, version, configuration, executions) {
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
if (hasMavenPluginInTree(tree, rootFolder, groupId, artifactId, version)) {
return false; // plugin already exists
}
if (configuration && executions && typeof configuration !== typeof executions)
throw new Error('"configuration" and "executions" must be of same type (either object or string)');
const projectNode = (0, index_1.findXmlMatching)(pomXml, '/project');
if (!projectNode)
throw new Error('The POM.xml is invalid (no "<project>" node found)');
const buildNode = (0, index_1.findXmlMatching)(pomXml, '/project/build');
if (!buildNode) {
// make sure the <build> node exists
(0, index_1.addXmlNode)(projectNode, {
build: {
plugins: {},
},
});
}
let pluginsNode = (0, index_1.findXmlMatching)(pomXml, '/project/build/plugins');
if (!pluginsNode) {
// make sure the <plugins> node exists
if (!buildNode)
return false;
(0, index_1.addXmlNode)(buildNode, {
plugins: {},
});
pluginsNode = (0, index_1.findXmlMatching)(pomXml, '/project/build/plugins');
}
const pluginNode = (configuration || executions) &&
(typeof configuration === 'object' || typeof executions === 'object')
? {
plugin: {
groupId: groupId,
artifactId: artifactId,
...(version && { version: version }),
...(configuration && { configuration: configuration }),
...(executions && { executions: executions }),
},
}
: `<plugin>
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
${version ? `<version>${version}</version>` : ''}
${configuration
? `<configuration>${configuration}</configuration>`
: ''}
${executions ? `<executions>${executions}</executions>` : ''}
</plugin>`;
if (pluginsNode) {
(0, index_1.addXmlNode)(pluginsNode, pluginNode);
tree.write(`${rootFolder}/pom.xml`, pomXml.toString({ prettyPrint: true, indent: '\t' }));
return true;
}
return false;
}
function removeMavenPlugin(tree, rootFolder, groupId, artifactId) {
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
const pluginNode = (0, index_1.findXmlMatching)(pomXml, `/project/build/plugins/plugin/groupId/text()[.="${groupId}"]/../../artifactId/text()[.="${artifactId}"]`)
?.up()
?.up();
if (pluginNode) {
const pluginsNode = (0, index_1.removeXmlNode)(pluginNode);
//if parent 'plugins' node is now empty, remove it
if ((0, index_1.isXmlNodeEmpty)(pluginsNode)) {
const buildNode = (0, index_1.removeXmlNode)(pluginsNode);
//if parent 'build' node is now empty, remove it
if ((0, index_1.isXmlNodeEmpty)(buildNode)) {
(0, index_1.removeXmlNode)(buildNode);
}
}
tree.write(`${rootFolder}/pom.xml`, pomXml.toString({ prettyPrint: true, indent: '\t' }));
return true;
}
return false;
}
function addMavenProperty(tree, rootFolder, property, value) {
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
if (hasMavenProperty(tree, rootFolder, property, value)) {
return false; // property already exists
}
const projectNode = (0, index_1.findXmlMatching)(pomXml, '/project');
if (!projectNode)
throw new Error('The POM.xml is invalid (no "<project>" node found)');
let propertiesNode = (0, index_1.findXmlMatching)(pomXml, '/project/properties');
if (!propertiesNode) {
// make sure the <properties> node exists
(0, index_1.addXmlNode)(projectNode, {
properties: {},
});
propertiesNode = (0, index_1.findXmlMatching)(pomXml, '/project/properties');
}
const propertyNode = `<${property}>${value}</${property}>`;
if (propertiesNode) {
(0, index_1.addXmlNode)(propertiesNode, propertyNode);
tree.write(`${rootFolder}/pom.xml`, pomXml.toString({ prettyPrint: true, indent: '\t' }));
return true;
}
return false;
}
function getMavenSpotlessBaseConfig(languageConfig, baseGitBranch) {
const ratchetFrom = baseGitBranch
? (0, common_1.stripIndent) `
<!-- optional: limit format enforcement to just the files changed by this feature branch -->
<ratchetFrom>${baseGitBranch}</ratchetFrom>
`
: '';
return (0, common_1.stripIndent) `
${ratchetFrom}
<formats>
<!-- you can define as many formats as you want, each is independent -->
<format>
<!-- define the files to apply to -->
<includes>
<include>*.md</include>
<include>.gitignore</include>
</includes>
<!-- define the steps to apply to those files -->
<trimTrailingWhitespace/>
<endWithNewline/>
<indent>
<tabs>true</tabs>
<spacesPerTab>4</spacesPerTab>
</indent>
</format>
</formats>
${languageConfig}`;
}
function getMavenSpotlessConfig(language, jdkVersion, baseGitBranch) {
switch (language) {
case 'java':
return getMavenSpotlessBaseConfig((0, common_1.stripIndent) `
<java>
<!-- to customize, go to https://github.com/diffplug/spotless/tree/main/plugin-maven#java -->
<!-- Use the default importOrder configuration -->
<importOrder/>
<!-- Clean up -->
<removeUnusedImports/>
<!-- Apply google-java-format formatter -->
<googleJavaFormat/>
</java`, baseGitBranch);
case 'kotlin':
return getMavenSpotlessBaseConfig((0, common_1.stripIndent) `
<kotlin>
<!-- to customize, go to https://github.com/diffplug/spotless/tree/main/plugin-maven#kotlin -->
<!-- Use the default importOrder configuration -->
<importOrder/>
<!-- Clean up -->
<removeUnusedImports/>
<!-- Apply ${jdkVersion && jdkVersion >= 11
? 'ktfmt formatter(similar to google-java-format, but for Kotlin)'
: 'ktlint formatter'} -->
${jdkVersion && jdkVersion >= 11 ? '<ktfmt/>' : '<ktlint/>'}
</kotlin>`, baseGitBranch);
case 'groovy':
return getMavenSpotlessBaseConfig((0, common_1.stripIndent) `
<groovy>
<!-- to customize, go to https://github.com/diffplug/spotless/tree/main/plugin-maven#groovy -->
<!-- Use the default importOrder configuration -->
<importOrder/>
<!-- Clean up -->
<removeUnusedImports/>
<!-- Apply groovy-eclipse formatter -->
<greclipse/>
</groovy>`, baseGitBranch);
}
}
function addSpotlessMavenPlugin(tree, rootFolder, language, jdkVersion, gitBaseBranch) {
const spotlessConfig = getMavenSpotlessConfig(language, jdkVersion, gitBaseBranch);
return addMavenPlugin(tree, rootFolder, exports.SPOTLESS_MAVEN_PLUGIN_GROUP_ID, exports.SPOTLESS_MAVEN_PLUGIN_ARTIFACT_ID, exports.SPOTLESS_MAVEN_PLUGIN_VERSION, spotlessConfig);
}
function hasMultiModuleMavenProjectInTree(tree, rootFolder) {
if (!(0, index_1.isMavenProjectInTree)(tree, rootFolder))
return false;
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
const modulesXpath = `/project/modules`;
return (0, index_1.hasXmlMatching)(pomXml, modulesXpath);
}
function hasMultiModuleMavenProject(cwd) {
if (!(0, index_1.hasMavenProject)(cwd))
return false;
const pomXmlStr = (0, common_1.getProjectFileContent)({ root: cwd }, `pom.xml`);
const pomXml = (0, index_1.readXml)(pomXmlStr);
const modulesXpath = `/project/modules`;
return (0, index_1.hasXmlMatching)(pomXml, modulesXpath);
}
function hasMavenModuleInTree(tree, rootFolder, moduleName) {
if (!hasMultiModuleMavenProjectInTree(tree, rootFolder))
return false;
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
const modulesXpath = `/project/modules/module/text()[.="${moduleName}"]`;
return (0, index_1.hasXmlMatching)(pomXml, modulesXpath);
}
function hasMavenModule(cwd, moduleName) {
if (!hasMultiModuleMavenProject(cwd))
return false;
const pomXmlStr = (0, common_1.getProjectFileContent)({ root: cwd }, `pom.xml`);
const pomXml = (0, index_1.readXml)(pomXmlStr);
const modulesXpath = `/project/modules/module/text()[.="${moduleName}"]`;
return (0, index_1.hasXmlMatching)(pomXml, modulesXpath);
}
function addMavenModule(tree, rootFolder, moduleName) {
if (hasMavenModuleInTree(tree, rootFolder, moduleName))
return false;
const pomXml = readPomXml(tree, rootFolder);
if (pomXml === null)
return false;
const modulesNode = (0, index_1.findXmlMatching)(pomXml, `/project/modules`);
if (modulesNode) {
(0, index_1.addXmlNode)(modulesNode, {
module: moduleName,
});
tree.write(`${rootFolder}/pom.xml`, pomXml.toString({ prettyPrint: true, indent: '\t' }));
return true;
}
return false;
}
function initMavenParentModule(tree, rootFolder, groupId, parentModuleName, childModuleName, helpComment = '', version = 'O.0.1-SNAPSHOT') {
const parentPomXml = `<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
${helpComment}
<groupId>${groupId}</groupId>
<artifactId>${parentModuleName}</artifactId>
<version>${version}</version>
<packaging>pom</packaging>
<modules>
<module>${childModuleName}</module>
</modules>
</project>
`;
tree.write(`./${rootFolder}/pom.xml`, parentPomXml);
}
function getMavenModules(cwd) {
if (!hasMultiModuleMavenProject(cwd))
return [];
const pomXmlStr = (0, common_1.getProjectFileContent)({ root: cwd }, `pom.xml`);
const pomXml = (0, index_1.readXml)(pomXmlStr);
const modulesXpath = `/project/modules/module/text()`;
return (0, index_1.findXmlContents)(pomXml, modulesXpath);
}
function getMavenWrapperFiles() {
return [
'mvnw',
'mvnw.bat',
'mvnw.cmd',
'.mvn/wrapper/maven-wrapper.properties',
'.mvn/wrapper/MavenWrapperDownloader.class',
'.mvn/wrapper/MavenWrapperDownloader.java',
'.mvn/wrapper/maven-wrapper.jar',
];
}
function hasMavenWrapperInTree(tree, rootFolder) {
return hasMavenWrapperWithPredicate((file) => tree.exists(`./${rootFolder}/${file}`));
}
function hasMavenWrapper(rootFolder) {
return hasMavenWrapperWithPredicate((file) => (0, fileutils_1.fileExists)((0, path_1.resolve)(rootFolder, file)));
}
function getCoordinatesForMavenProjet(cwd) {
const pomXmlStr = (0, common_1.getProjectFileContent)({ root: cwd }, 'pom.xml');
const pomXmlNode = (0, index_1.readXml)(pomXmlStr);
let groupId = (0, index_1.findXmlContent)(pomXmlNode, `/project/groupId/text()`);
const artifactId = (0, index_1.findXmlContent)(pomXmlNode, `/project/artifactId/text()`);
if (!groupId && artifactId) {
// groupId might be defined at parent module level, continue searching for it
groupId = getGroupIdInHierarchy(cwd);
}
return { groupId, artifactId };
}
function getGroupIdInHierarchy(cwd) {
const { root, name } = (0, common_1.getNameAndRoot)(cwd);
if (root === '.')
// we reach the root of the workspace without finding the groupId, so we stop the search
return undefined;
if (!hasMavenModule(root, name))
return undefined;
const pomXmlStr = (0, common_1.getProjectFileContent)({ root }, 'pom.xml');
const pomXmlNode = (0, index_1.readXml)(pomXmlStr);
const groupId = (0, index_1.findXmlContent)(pomXmlNode, `/project/groupId/text()`);
return groupId ?? getGroupIdInHierarchy(root);
}
function hasMavenWrapperWithPredicate(predicate) {
return (['mvnw', '.mvn/wrapper/maven-wrapper.properties'].every((file) => predicate(file)) && ['mvnw.bat', 'mvnw.cmd'].some((file) => predicate(file)));
}
//# sourceMappingURL=maven-utils.js.map
;