aleksandr-m / gitflow-maven-plugin

The Git-Flow Maven Plugin supports various Git workflows, including GitFlow and GitHub Flow. This plugin runs Git and Maven commands from the command line.
https://aleksandr-m.github.io/gitflow-maven-plugin/
Apache License 2.0
487 stars 180 forks source link

Support for Maven Versions Plugin propertiesVersionsFile #400

Open kolitt18 opened 4 months ago

kolitt18 commented 4 months ago

For property versions, it is helpful to maintain these properties in a single file and utilize the propertiesVersionsFile in Maven Versions Plugin. This check can live in AbstractGitFlowMojo.java.

In AbstractGitFlowMojo.java starting at line 1186:

            if (StringUtils.isNotBlank(propertiesVersionsFile)) {
                runCommand = true;
                getLog().info("Updating properties using file '" + propertiesVersionsFile + "'.");
                args.add(VERSIONS_MAVEN_PLUGIN + ":" + versionsMavenPluginVersion + ":" + VERSIONS_MAVEN_PLUGIN_SET_PROPERTY_GOAL);
                args.add("-DpropertiesVersionsFile=" + propertiesVersionsFile);
            }

with a new property:

    @Parameter(property = "propertiesVersionsFile")
    protected String propertiesVersionsFile;

This does complicate the release-finish goal because if useSnapshotInRelease is true, then SNAPSHOTs can be used in this property file as well. This file will need to contain the latest versions and if they are SNAPSHOTs, they need to be rolled back to the tag during tagging. This is a similar process to the parent pom version.

In GitFlowReleaseFinishMojo.java:

            // If propertiesVersionsFile is set, save dev and tag version
            Path path = null;
            Properties devProperties = null;
            Properties tagProperties = null;
            if (StringUtils.isNotBlank(propertiesVersionsFile)) {
                devProperties = new Properties();
                tagProperties = new Properties();
                path = Paths.get(propertiesVersionsFile);

                //load a properties file from class path
                Properties prop = new Properties();
                try (InputStream inputStream = Files.newInputStream(path)) {
                    prop.load(inputStream);
                }

                // Set properties versions file to tags
                for (Map.Entry<Object, Object> entry : prop.entrySet()) {
                    devProperties.put(entry.getKey(), entry.getValue());
                    String tagValue = String.valueOf(entry.getValue());
                    if (tagValue.contains("-" + Artifact.SNAPSHOT_VERSION)) {
                        tagValue = tagValue.replace("-" + Artifact.SNAPSHOT_VERSION, "");
                        String[] tagValueSplit = tagValue.split("\\.");
                        int tagValueInt = Integer.parseInt(tagValueSplit[tagValueSplit.length - 1]) - 1;
                        tagValueSplit[tagValueSplit.length - 1] = String.valueOf(tagValueInt);
                        tagProperties.put(entry.getKey(), String.join(".", tagValueSplit));
                    } else {
                        tagProperties.put(entry.getKey(), entry.getValue());
                    }
                }
            }

With devProperties and tagProperties saved, the file can easily be switched between for tagging, updating dev to prod values, then updating dev back to dev values:

                if (StringUtils.isNotBlank(propertiesVersionsFile) && tagProperties != null) {
                    writePropertiesFile(path, tagProperties);
                }

This method is the same as Java Properties store method without the timestamp, which causes merge conflicts for develop.

Write method:

    private void writePropertiesFile(Path path, Properties properties) throws IOException {
        try (OutputStream outputStream = Files.newOutputStream(path)) {
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
            for (Map.Entry<Object, Object> entry : properties.entrySet()) {
                bw.write(entry.getKey() + "=" + entry.getValue());
                bw.newLine();
            }
            bw.flush();
        }
    }