Refactoring to batch (#181)
The rationale of this pull request is to * have more maintainable and granular code * not maintain the custom made job engine * allow the users to customize the defaults of the releaser more easy * allow the users to create their own steps without the need to change any existing code * allow the users to fully change the flows and tasks logic * abstract underlying batch mechanism (Spring Batch) so it doesn't leak to production code * allow parallelization of the release process and release tasks
This commit is contained in:
committed by
GitHub
parent
ea85372e05
commit
8992e45321
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright 2013-2019 the original author or authors.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
package releaser.internal.spring;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import releaser.internal.Releaser;
|
||||
import releaser.internal.ReleaserProperties;
|
||||
import releaser.internal.options.Options;
|
||||
import releaser.internal.project.ProjectVersion;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
class ProjectsToRunFactory implements Closeable {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ProjectsToRunFactory.class);
|
||||
|
||||
private final ProjectsToRun storedProjects = new ProjectsToRun();
|
||||
|
||||
private final VersionsToBumpFactory versionsToBumpFactory;
|
||||
|
||||
private final Releaser releaser;
|
||||
|
||||
private final ReleaserPropertiesUpdater updater;
|
||||
|
||||
ProjectsToRunFactory(VersionsToBumpFactory versionsToBumpFactory, Releaser releaser,
|
||||
ReleaserPropertiesUpdater updater) {
|
||||
this.versionsToBumpFactory = versionsToBumpFactory;
|
||||
this.releaser = releaser;
|
||||
this.updater = updater;
|
||||
}
|
||||
|
||||
ProjectsToRun release(OptionsAndProperties optionsAndProperties) {
|
||||
ProjectsToRun projectsToRun = doRelease(optionsAndProperties);
|
||||
this.storedProjects.addAll(projectsToRun);
|
||||
return projectsToRun;
|
||||
}
|
||||
|
||||
private ProjectsToRun doRelease(OptionsAndProperties optionsAndProperties) {
|
||||
Options options = optionsAndProperties.options;
|
||||
ReleaserProperties properties = optionsAndProperties.properties;
|
||||
if (!options.metaRelease) {
|
||||
log.info(
|
||||
"Single project release picked. Will release only the current project");
|
||||
File projectFolder = projectFolder(properties);
|
||||
ProjectVersion version = new ProjectVersion(projectFolder);
|
||||
ProjectsFromBom projectsFromBom = this.versionsToBumpFactory
|
||||
.withProject(projectFolder);
|
||||
return new ProjectsToRun(new ProjectToRun.ProjectToRunSupplier(
|
||||
version.projectName, () -> new ProjectToRun(projectFolder,
|
||||
projectsFromBom, version, properties, options)));
|
||||
}
|
||||
log.info("Meta release picked");
|
||||
return metaReleaseProjectsToRun(options, properties);
|
||||
}
|
||||
|
||||
ProjectsToRun postReleaseTrain(OptionsAndProperties optionsAndProperties) {
|
||||
ProjectsToRun projectsToRun = doPostRelease(optionsAndProperties);
|
||||
this.storedProjects.addAll(projectsToRun);
|
||||
return projectsToRun;
|
||||
}
|
||||
|
||||
private ProjectsToRun doPostRelease(OptionsAndProperties optionsAndProperties) {
|
||||
Options options = optionsAndProperties.options;
|
||||
ReleaserProperties properties = optionsAndProperties.properties;
|
||||
if (!options.metaRelease) {
|
||||
return new ProjectsToRun();
|
||||
}
|
||||
log.info("Meta release picked");
|
||||
return metaReleasePostReleaseProjectsToRun(options, properties);
|
||||
}
|
||||
|
||||
private File projectFolder(ReleaserProperties properties) {
|
||||
String workingDir = properties.getWorkingDir();
|
||||
return new File(workingDir);
|
||||
}
|
||||
|
||||
private ProjectsToRun metaReleaseProjectsToRun(Options options,
|
||||
ReleaserProperties originalProps) {
|
||||
return metaProjectsToRun(options, originalProps,
|
||||
metaReleaseProjects(options, originalProps));
|
||||
}
|
||||
|
||||
private ProjectsToRun metaReleasePostReleaseProjectsToRun(Options options,
|
||||
ReleaserProperties originalProps) {
|
||||
return metaProjectsToRun(options, originalProps,
|
||||
allButSkippedProjects(originalProps));
|
||||
}
|
||||
|
||||
private ProjectsToRun metaProjectsToRun(Options options,
|
||||
ReleaserProperties originalProps, List<String> projectNames) {
|
||||
return projectNames.stream()
|
||||
.map(project -> projectSupplier(options, originalProps, project))
|
||||
.collect(Collectors.toCollection(ProjectsToRun::new));
|
||||
}
|
||||
|
||||
private ProjectToRun.ProjectToRunSupplier projectSupplier(Options options,
|
||||
ReleaserProperties originalProps, String project) {
|
||||
return new ProjectToRun.ProjectToRunSupplier(project, () -> {
|
||||
File clonedProjectFromOrg = this.releaser.clonedProjectFromOrg(project);
|
||||
ReleaserProperties properties = updatePropertiesIfCustomConfigPresent(
|
||||
originalProps.copy(), clonedProjectFromOrg);
|
||||
log.info("Successfully cloned the project [{}] to [{}]", project,
|
||||
clonedProjectFromOrg);
|
||||
ProjectVersion originalVersion = new ProjectVersion(clonedProjectFromOrg);
|
||||
ProjectsFromBom projectsFromBom = this.versionsToBumpFactory
|
||||
.withProject(clonedProjectFromOrg);
|
||||
return new ProjectToRun(clonedProjectFromOrg, projectsFromBom,
|
||||
originalVersion, properties, options);
|
||||
});
|
||||
}
|
||||
|
||||
private ReleaserProperties updatePropertiesIfCustomConfigPresent(
|
||||
ReleaserProperties copy, File clonedProjectFromOrg) {
|
||||
return this.updater.updateProperties(copy, clonedProjectFromOrg);
|
||||
}
|
||||
|
||||
private List<String> metaReleaseProjects(Options options,
|
||||
ReleaserProperties properties) {
|
||||
List<String> filteredProjects = allButSkippedProjects(properties);
|
||||
if (StringUtils.hasText(options.startFrom)) {
|
||||
filteredProjects = filterStartFrom(options, filteredProjects);
|
||||
}
|
||||
else if (!options.taskNames.isEmpty()) {
|
||||
filteredProjects = filterTaskNames(options, filteredProjects);
|
||||
}
|
||||
log.info("\n\n\nFor meta-release, will release the projects {}\n\n\n",
|
||||
filteredProjects);
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
private List<String> allButSkippedProjects(ReleaserProperties properties) {
|
||||
List<String> projects = new ArrayList<>(properties.getFixedVersions().keySet());
|
||||
log.info("List of projects that should not be cloned {}",
|
||||
properties.getMetaRelease().getProjectsToSkip());
|
||||
List<String> filteredProjects = filterProjectsToSkip(projects, properties);
|
||||
log.info("List of all projects to clone before filtering {}", filteredProjects);
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
private List<String> allProjects(ReleaserProperties properties) {
|
||||
return new ArrayList<>(properties.getFixedVersions().keySet());
|
||||
}
|
||||
|
||||
private List<String> filterProjectsToSkip(List<String> projects,
|
||||
ReleaserProperties properties) {
|
||||
return projects
|
||||
.stream().filter(project -> !properties.getMetaRelease()
|
||||
.getProjectsToSkip().contains(project))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<String> filterStartFrom(Options options, List<String> filteredProjects) {
|
||||
log.info("Start from option provided [{}]", options.startFrom);
|
||||
int projectIndex = filteredProjects.indexOf(options.startFrom);
|
||||
if (projectIndex < 0) {
|
||||
throw new IllegalStateException(
|
||||
"Project [" + options.startFrom + "] not found");
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Index of project [{}] is [{}]", options.startFrom, projectIndex);
|
||||
}
|
||||
filteredProjects = filteredProjects.subList(projectIndex,
|
||||
filteredProjects.size());
|
||||
options.startFrom = "";
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
private List<String> filterTaskNames(Options options, List<String> filteredProjects) {
|
||||
log.info("Task names provided {}", options.taskNames);
|
||||
filteredProjects = filteredProjects.stream()
|
||||
.filter(project -> options.taskNames.contains(project))
|
||||
.collect(Collectors.toList());
|
||||
options.taskNames = new ArrayList<>();
|
||||
return filteredProjects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.storedProjects.forEach(ProjectToRun.ProjectToRunSupplier::close);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user