blob: 8a4bcfb74712151387dfd5c63d8ca59dbfba48a2 [file] [log] [blame]
/*
* Copyright 2013-present Facebook, Inc.
*
* 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
*
* http://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 com.facebook.buck.cli;
import com.facebook.buck.util.MoreFiles;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.io.Files;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* This class creates a terminal command for Buck that creates a sample Buck project in the
* directory the user specifies. It copies from {@link #PATH_TO_QUICKSTART_DIR} to the
* directory specified. It then asks the user for the location of the Android SDK so Buck can
* successfully build the quickstart project. It will fail if it cannot find the template directory,
* or if it is unable to write to the destination directory.
*/
public class QuickstartCommand extends AbstractCommandRunner<QuickstartCommandOptions> {
private static final Path PATH_TO_QUICKSTART_DIR = Paths.get(
System.getProperty(
"buck.quickstart_origin_dir",
new File("src/com/facebook/buck/cli/quickstart/android").getAbsolutePath()
)
);
public QuickstartCommand(CommandRunnerParams params) {
super(params);
}
@Override
QuickstartCommandOptions createOptions(BuckConfig buckConfig) {
return new QuickstartCommandOptions(buckConfig);
}
/**
* Runs the command "buck quickstart", which copies a template project into a new directory to
* give the user a functional buck project. It copies from
* src/com/facebook/buck/cli/quickstart/android to the directory specified. It then asks the user
* for the location of the Android SDK so Buck cansuccessfully build the quickstart project. It
* will fail if it cannot find the template directory or if it is unable to write to the
* destination directory.
*
* @param options an object representing command line options
* @return status code - zero means no problem
* @throws IOException if the command fails to read from the template project or write to the
* new project
*/
@Override
int runCommandWithOptionsInternal(QuickstartCommandOptions options) throws IOException {
String projectDir = options.getDestDir().trim();
if (projectDir.isEmpty()) {
projectDir = promptForPath("Enter the directory where you would like to create the " +
"project: ");
}
File dir = new File(projectDir);
while (!dir.isDirectory() && !dir.mkdirs() && !projectDir.isEmpty()) {
projectDir = promptForPath("Cannot create project directory. Enter another directory: ");
dir = new File(projectDir);
}
if (projectDir.isEmpty()) {
getStdErr().println("No project directory specified. Aborting quickstart.");
return 1;
}
String sdkLocation = options.getAndroidSdkDir();
if (sdkLocation.isEmpty()) {
sdkLocation = promptForPath("Enter your Android SDK's location: ");
}
File sdkLocationFile = new File(sdkLocation);
if (!sdkLocationFile.isDirectory()) {
getStdErr().println("WARNING: That Android SDK directory does not exist.");
}
sdkLocation = sdkLocationFile.getAbsoluteFile().toString();
Path origin = PATH_TO_QUICKSTART_DIR;
Path destination = Paths.get(projectDir);
MoreFiles.copyRecursively(origin, destination);
File out = new File(projectDir + "/local.properties");
Files.write("sdk.dir=" + sdkLocation + "\n", out, StandardCharsets.UTF_8);
getStdOut().print(
Files.toString(origin.resolve("README.md").toFile(), StandardCharsets.UTF_8)
);
getStdOut().flush();
return 0;
}
private String promptForPath(String prompt) throws IOException {
getStdOut().print(prompt);
getStdOut().flush();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
return expandTilde(br.readLine().trim());
}
/**
* A simple function to convert "~" to the home directory (i.e. /home/user) in paths. It does not
* support the shortcut for other users' home directories, "~user". If the path does not start
* with "~/", then this function returns the same string it was given.
*
* @param path an absolute path string that begins with "~/"
* @return an absolute path with an expanded home directory
*/
protected static String expandTilde(String path) {
return expandTildeInternal(System.getProperty("user.home"), path);
}
@VisibleForTesting
static String expandTildeInternal(String homeDir, String path) {
if (path.startsWith("~/")) {
return homeDir + path.substring(1);
} else if (path.equals("~")) {
return homeDir;
} else {
return path;
}
}
@Override
String getUsageIntro() {
return "generates a default project directory";
}
}