| /* |
| * 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"; |
| } |
| } |