-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
aca7df7
commit 39da3cc
Showing
2 changed files
with
177 additions
and
1 deletion.
There are no files selected for viewing
175 changes: 175 additions & 0 deletions
175
smithy-cli/src/main/java/software/amazon/smithy/cli/commands/InitCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
* 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.smithy.cli.commands; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.net.URISyntaxException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.nio.file.StandardCopyOption; | ||
import java.util.function.Consumer; | ||
import software.amazon.smithy.cli.ArgumentReceiver; | ||
import software.amazon.smithy.cli.Arguments; | ||
import software.amazon.smithy.cli.Command; | ||
import software.amazon.smithy.cli.HelpPrinter; | ||
import software.amazon.smithy.model.node.Node; | ||
import software.amazon.smithy.utils.IoUtils; | ||
|
||
public class InitCommand implements Command { | ||
private static final String TEMP_DIRECTORY = ".temp"; | ||
private static final String SMITHY_TEMPLATE_JSON = "smithy-templates.json"; | ||
|
||
private final String parentCommandName; | ||
|
||
public InitCommand(String parentCommandName) { | ||
this.parentCommandName = parentCommandName; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "init"; | ||
} | ||
|
||
@Override | ||
public String getSummary() { | ||
return "Initialize a smithy project by template"; | ||
} | ||
|
||
@Override | ||
public int execute(Arguments arguments, Env env) { | ||
arguments.addReceiver(new Options()); | ||
CommandAction action = HelpActionWrapper.fromCommand(this, parentCommandName, this::run); | ||
return action.apply(arguments, env); | ||
} | ||
|
||
private int run(Arguments arguments, Env env) { | ||
Options options = arguments.getReceiver(Options.class); | ||
try { | ||
this.cloneTemplate(options.repositoryUrl, options.template, options.directory); | ||
} catch (IOException | InterruptedException | URISyntaxException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
private void cloneTemplate(String repositoryUrl, String templateName, String directory) | ||
throws IOException, InterruptedException, URISyntaxException { | ||
|
||
if (templateName == null || templateName.isEmpty()) { | ||
throw new IllegalArgumentException("Please specify template via `--template` argument"); | ||
} | ||
|
||
// Use templateName if directory is not specified | ||
if (directory == null) { | ||
directory = templateName; | ||
} | ||
|
||
// Clone the repository without downloading files | ||
new ProcessBuilder( | ||
"git", "clone", "--filter=blob:none", "--no-checkout", | ||
"--depth", "1", "--sparse", repositoryUrl, TEMP_DIRECTORY) | ||
.inheritIO().start().waitFor(); | ||
|
||
// Download template json file | ||
new ProcessBuilder("git", "sparse-checkout", "set", "--no-cone", SMITHY_TEMPLATE_JSON) | ||
.directory(new File(TEMP_DIRECTORY)) | ||
.start().waitFor(); | ||
|
||
new ProcessBuilder("git", "checkout") | ||
.directory(new File(TEMP_DIRECTORY)) | ||
.start().waitFor(); | ||
|
||
String templatePath = readJsonFileAsNode(Paths.get(TEMP_DIRECTORY, SMITHY_TEMPLATE_JSON)) | ||
.expectObjectNode() | ||
.expectObjectMember("templates") | ||
.expectObjectMember(templateName) | ||
.getStringMember("path").get().getValue(); | ||
|
||
// Specify the subdirectory to download | ||
new ProcessBuilder("git", "sparse-checkout", "set", "--no-cone", templatePath) | ||
.directory(new File(TEMP_DIRECTORY)) | ||
.start().waitFor(); | ||
|
||
new ProcessBuilder("git", "checkout") | ||
.directory(new File(TEMP_DIRECTORY)) | ||
.start().waitFor(); | ||
|
||
Files.move( | ||
Paths.get(TEMP_DIRECTORY, templatePath), | ||
Paths.get(directory), | ||
StandardCopyOption.REPLACE_EXISTING); | ||
|
||
deleteDirectory(new File(TEMP_DIRECTORY)); | ||
} | ||
|
||
private Node readJsonFileAsNode(Path jsonFilePath) throws IOException { | ||
return Node.parse(IoUtils.toUtf8String(Files.newInputStream(jsonFilePath))); | ||
} | ||
|
||
private boolean deleteDirectory(File directoryToBeDeleted) { | ||
File[] allContents = directoryToBeDeleted.listFiles(); | ||
if (allContents != null) { | ||
for (File file : allContents) { | ||
deleteDirectory(file); | ||
} | ||
} | ||
return directoryToBeDeleted.delete(); | ||
} | ||
|
||
private static final class Options implements ArgumentReceiver { | ||
private String template; | ||
|
||
private String directory; | ||
|
||
private String repositoryUrl = "https://github.com/smithy-lang/smithy-examples.git"; | ||
|
||
@Override | ||
public boolean testOption(String name) { | ||
return false; | ||
} | ||
|
||
@Override | ||
public Consumer<String> testParameter(String name) { | ||
switch (name) { | ||
case "--template": | ||
case "-t": | ||
return value -> template = value; | ||
case "--url": | ||
return value -> repositoryUrl = value; | ||
case "--directory": | ||
case "-d": | ||
return value -> directory = value; | ||
default: | ||
return value -> { | ||
}; | ||
} | ||
} | ||
|
||
@Override | ||
public void registerHelp(HelpPrinter printer) { | ||
printer.param("--template", "-t", "quickstart-cli", | ||
"Specify the template to be used in the Smithy project"); | ||
printer.param("--url", null, | ||
"https://github.com/smithy-lang/smithy-examples.git", | ||
"Smithy templates repository url"); | ||
printer.param("--directory", "-d", "new-smithy-project", | ||
"Smithy project directory"); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters