Skip to content

Add CreateNewServiceModuleMain and FinalizeNewServiceModuleMain relea… #2173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.release;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import software.amazon.awssdk.utils.Validate;
import software.amazon.awssdk.utils.internal.CodegenNamingUtils;

/**
* A command line application to create a new, empty service. This *does not* add the new service to the shared pom.xmls, that
* should be done via {@link FinalizeNewServiceModuleMain}.
*
* Example usage:
* <pre>
* mvn exec:java -pl :release-scripts \
* -Dexec.mainClass="software.amazon.awssdk.release.CreateNewServiceModuleMain" \
* -Dexec.args="--maven-project-root /path/to/root
* --maven-project-version 2.1.4-SNAPSHOT
* --service-id 'Service Id'
* --service-module-name service-module-name
* --service-protocol json"
* </pre>
*/
public class CreateNewServiceModuleMain extends Cli {
private CreateNewServiceModuleMain() {
super(requiredOption("service-module-name", "The name of the service module to be created."),
requiredOption("service-id", "The service ID of the service module to be created."),
requiredOption("service-protocol", "The protocol of the service module to be created."),
requiredOption("maven-project-root", "The root directory for the maven project."),
requiredOption("maven-project-version", "The maven version of the service module to be created."));
}

public static void main(String[] args) {
new CreateNewServiceModuleMain().run(args);
}

@Override
protected void run(CommandLine commandLine) throws Exception {
new NewServiceCreator(commandLine).run();
}

private static class NewServiceCreator {
private final Path mavenProjectRoot;
private final String mavenProjectVersion;
private final String serviceModuleName;
private final String serviceId;
private final String serviceProtocol;

private NewServiceCreator(CommandLine commandLine) {
this.mavenProjectRoot = Paths.get(commandLine.getOptionValue("maven-project-root").trim());
this.mavenProjectVersion = commandLine.getOptionValue("maven-project-version").trim();
this.serviceModuleName = commandLine.getOptionValue("service-module-name").trim();
this.serviceId = commandLine.getOptionValue("service-id").trim();
this.serviceProtocol = transformSpecialProtocols(commandLine.getOptionValue("service-protocol").trim());

Validate.isTrue(Files.exists(mavenProjectRoot), "Project root does not exist: " + mavenProjectRoot);
}

private String transformSpecialProtocols(String protocol) {
switch (protocol) {
case "ec2": return "query";
case "rest-xml": return "xml";
case "rest-json": return "json";
default: return protocol;
}
}

public void run() throws Exception {
Path servicesRoot = mavenProjectRoot.resolve("services");
Path templateModulePath = servicesRoot.resolve("new-service-template");
Path newServiceModulePath = servicesRoot.resolve(serviceModuleName);

createNewModuleFromTemplate(templateModulePath, newServiceModulePath);
replaceTemplatePlaceholders(newServiceModulePath);
}

private void createNewModuleFromTemplate(Path templateModulePath, Path newServiceModule) throws IOException {
FileUtils.copyDirectory(templateModulePath.toFile(), newServiceModule.toFile());
}

private void replaceTemplatePlaceholders(Path newServiceModule) throws IOException {
Files.walkFileTree(newServiceModule, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
replacePlaceholdersInFile(file);
return FileVisitResult.CONTINUE;
}
});
}

private void replacePlaceholdersInFile(Path file) throws IOException {
String fileContents = new String(Files.readAllBytes(file), UTF_8);
String newFileContents = replacePlaceholders(fileContents);
Files.write(file, newFileContents.getBytes(UTF_8));
}

private String replacePlaceholders(String line) {
String[] searchList = {
"{{MVN_ARTIFACT_ID}}",
"{{MVN_NAME}}",
"{{MVN_VERSION}}",
"{{PROTOCOL}}"
};
String[] replaceList = {
serviceModuleName,
mavenName(serviceId),
mavenProjectVersion,
serviceProtocol
};
return StringUtils.replaceEach(line, searchList, replaceList);
}

private String mavenName(String serviceId) {
return Stream.of(CodegenNamingUtils.splitOnWordBoundaries(serviceId))
.map(StringUtils::capitalize)
.collect(Collectors.joining(" "));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.release;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.cli.CommandLine;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import software.amazon.awssdk.utils.Validate;

/**
* A command line application to add new services to the shared pom.xml files.
*
* Example usage:
* <pre>
* mvn exec:java -pl :release-scripts \
* -Dexec.mainClass="software.amazon.awssdk.release.FinalizeNewServiceModuleMain" \
* -Dexec.args="--maven-project-root /path/to/root
* --service-module-names service-module-name-1,service-module-name-2"
* </pre>
*/
public class FinalizeNewServiceModuleMain extends Cli {
private FinalizeNewServiceModuleMain() {
super(requiredOption("service-module-names",
"A comma-separated list containing the name of the service modules to be created."),
requiredOption("maven-project-root", "The root directory for the maven project."));
}

public static void main(String[] args) {
new FinalizeNewServiceModuleMain().run(args);
}

@Override
protected void run(CommandLine commandLine) throws Exception {
new NewServiceCreator(commandLine).run();
}

private static class NewServiceCreator {
private final Path mavenProjectRoot;
private final List<String> serviceModuleNames;

private NewServiceCreator(CommandLine commandLine) {
this.mavenProjectRoot = Paths.get(commandLine.getOptionValue("maven-project-root").trim());
this.serviceModuleNames = Stream.of(commandLine.getOptionValue("service-module-names").split(","))
.map(String::trim)
.collect(Collectors.toList());

Validate.isTrue(Files.exists(mavenProjectRoot), "Project root does not exist: " + mavenProjectRoot);
}

public void run() throws Exception {
for (String serviceModuleName : serviceModuleNames) {
Path servicesPomPath = mavenProjectRoot.resolve("services").resolve("pom.xml");
Path aggregatePomPath = mavenProjectRoot.resolve("aws-sdk-java").resolve("pom.xml");
Path bomPomPath = mavenProjectRoot.resolve("bom").resolve("pom.xml");

new AddSubmoduleTransformer(serviceModuleName).transform(servicesPomPath);
new AddDependencyTransformer(serviceModuleName).transform(aggregatePomPath);
new AddDependencyManagementDependencyTransformer(serviceModuleName).transform(bomPomPath);
}
}

private static class AddSubmoduleTransformer extends PomTransformer {
private final String serviceModuleName;

private AddSubmoduleTransformer(String serviceModuleName) {
this.serviceModuleName = serviceModuleName;
}

@Override
protected void updateDocument(Document doc) {
Node project = findChild(doc, "project");
Node modules = findChild(project, "modules");

modules.appendChild(textElement(doc, "module", serviceModuleName));
}
}

private static class AddDependencyTransformer extends PomTransformer {
private final String serviceModuleName;

private AddDependencyTransformer(String serviceModuleName) {
this.serviceModuleName = serviceModuleName;
}

@Override
protected void updateDocument(Document doc) {
Node project = findChild(doc, "project");
Node dependencies = findChild(project, "dependencies");

dependencies.appendChild(sdkDependencyElement(doc, serviceModuleName));
}
}

private static class AddDependencyManagementDependencyTransformer extends PomTransformer {
private final String serviceModuleName;

private AddDependencyManagementDependencyTransformer(String serviceModuleName) {
this.serviceModuleName = serviceModuleName;
}

@Override
protected void updateDocument(Document doc) {
Node project = findChild(doc, "project");
Node dependencyManagement = findChild(project, "dependencyManagement");
Node dependencies = findChild(dependencyManagement, "dependencies");

dependencies.appendChild(sdkDependencyElement(doc, serviceModuleName));
}
}
}
}