PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/facebook/buck/cli/PublishCommand.java

https://gitlab.com/smartether/buck
Java | 245 lines | 196 code | 29 blank | 20 comment | 12 complexity | f19f647f6df4f126752fbf6a932036b6 MD5 | raw file
  1. /*
  2. * Copyright 2015-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. * not use this file except in compliance with the License. You may obtain
  6. * a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations
  14. * under the License.
  15. */
  16. package com.facebook.buck.cli;
  17. import com.facebook.buck.event.ConsoleEvent;
  18. import com.facebook.buck.jvm.java.JavaLibrary;
  19. import com.facebook.buck.jvm.java.MavenPublishable;
  20. import com.facebook.buck.maven.Publisher;
  21. import com.facebook.buck.model.BuildTarget;
  22. import com.facebook.buck.parser.BuildTargetSpec;
  23. import com.facebook.buck.parser.NoSuchBuildTargetException;
  24. import com.facebook.buck.parser.TargetNodeSpec;
  25. import com.facebook.buck.rules.BuildRule;
  26. import com.facebook.buck.rules.SourcePathResolver;
  27. import com.facebook.buck.rules.SourcePathRuleFinder;
  28. import com.facebook.buck.util.MoreCollectors;
  29. import com.google.common.base.Joiner;
  30. import com.google.common.base.Preconditions;
  31. import com.google.common.collect.FluentIterable;
  32. import com.google.common.collect.ImmutableList;
  33. import com.google.common.collect.ImmutableSet;
  34. import org.eclipse.aether.artifact.Artifact;
  35. import org.eclipse.aether.deployment.DeployResult;
  36. import org.eclipse.aether.deployment.DeploymentException;
  37. import org.kohsuke.args4j.Option;
  38. import java.io.IOException;
  39. import java.net.URL;
  40. import java.util.Optional;
  41. import javax.annotation.Nullable;
  42. public class PublishCommand extends BuildCommand {
  43. public static final String REMOTE_REPO_LONG_ARG = "--remote-repo";
  44. public static final String REMOTE_REPO_SHORT_ARG = "-r";
  45. public static final String INCLUDE_SOURCE_LONG_ARG = "--include-source";
  46. public static final String INCLUDE_SOURCE_SHORT_ARG = "-s";
  47. public static final String TO_MAVEN_CENTRAL_LONG_ARG = "--to-maven-central";
  48. public static final String DRY_RUN_LONG_ARG = "--dry-run";
  49. @Option(
  50. name = REMOTE_REPO_LONG_ARG,
  51. aliases = REMOTE_REPO_SHORT_ARG,
  52. usage = "A url of the remote repository to publish artifact(s) to")
  53. @Nullable
  54. private URL remoteRepo = null;
  55. @Option(
  56. name = TO_MAVEN_CENTRAL_LONG_ARG,
  57. usage = "Same as \"" + REMOTE_REPO_LONG_ARG + " " + Publisher.MAVEN_CENTRAL_URL + "\"")
  58. private boolean toMavenCentral = false;
  59. @Option(
  60. name = INCLUDE_SOURCE_LONG_ARG,
  61. aliases = INCLUDE_SOURCE_SHORT_ARG,
  62. usage = "Publish source code as well")
  63. private boolean includeSource = false;
  64. @Option(
  65. name = DRY_RUN_LONG_ARG,
  66. usage = "Just print the artifacts to be published")
  67. private boolean dryRun = false;
  68. @Option(
  69. name = "--username",
  70. aliases = "-u",
  71. usage = "User name to use to authenticate with the server")
  72. @Nullable
  73. private String username = null;
  74. @Option(
  75. name = "--password",
  76. aliases = "-p",
  77. usage = "Password to use to authenticate with the server")
  78. @Nullable
  79. private String password = null;
  80. @Override
  81. public int runWithoutHelp(CommandRunnerParams params) throws IOException, InterruptedException {
  82. // Input validation
  83. if (remoteRepo == null && !toMavenCentral) {
  84. params.getBuckEventBus().post(ConsoleEvent.severe(
  85. "Please specify a remote repository to publish to.\n" +
  86. "Use " + REMOTE_REPO_LONG_ARG + " <URL> or " + TO_MAVEN_CENTRAL_LONG_ARG));
  87. return 1;
  88. }
  89. // Build the specified target(s).
  90. int exitCode = super.runWithoutHelp(params);
  91. if (exitCode != 0) {
  92. return exitCode;
  93. }
  94. // Publish starting with the given targets.
  95. return publishTargets(getBuildTargets(), params) ? 0 : 1;
  96. }
  97. private boolean publishTargets(
  98. ImmutableList<BuildTarget> buildTargets,
  99. CommandRunnerParams params) {
  100. ImmutableSet.Builder<MavenPublishable> publishables = ImmutableSet.builder();
  101. boolean success = true;
  102. for (BuildTarget buildTarget : buildTargets) {
  103. BuildRule buildRule = null;
  104. try {
  105. buildRule = getBuild().getRuleResolver().requireRule(buildTarget);
  106. } catch (NoSuchBuildTargetException e) {
  107. // This doesn't seem physically possible!
  108. throw new RuntimeException(e);
  109. }
  110. Preconditions.checkNotNull(buildRule);
  111. if (!(buildRule instanceof MavenPublishable)) {
  112. params.getBuckEventBus().post(ConsoleEvent.severe(
  113. "Cannot publish rule of type %s",
  114. buildRule.getClass().getName()));
  115. success &= false;
  116. continue;
  117. }
  118. MavenPublishable publishable = (MavenPublishable) buildRule;
  119. if (!publishable.getMavenCoords().isPresent()) {
  120. params.getBuckEventBus().post(ConsoleEvent.severe(
  121. "No maven coordinates specified for %s",
  122. buildTarget.getUnflavoredBuildTarget().getFullyQualifiedName()));
  123. success &= false;
  124. continue;
  125. }
  126. publishables.add(publishable);
  127. }
  128. Publisher publisher = new Publisher(
  129. params.getCell().getFilesystem(),
  130. Optional.ofNullable(remoteRepo),
  131. Optional.ofNullable(username),
  132. Optional.ofNullable(password),
  133. dryRun);
  134. try {
  135. ImmutableSet<DeployResult> deployResults = publisher.publish(
  136. new SourcePathResolver(new SourcePathRuleFinder(getBuild().getRuleResolver())),
  137. publishables.build());
  138. for (DeployResult deployResult : deployResults) {
  139. printArtifactsInformation(params, deployResult);
  140. }
  141. } catch (DeploymentException e) {
  142. params.getConsole().printBuildFailureWithoutStacktraceDontUnwrap(e);
  143. return false;
  144. }
  145. return success;
  146. }
  147. private static void printArtifactsInformation(
  148. CommandRunnerParams params,
  149. DeployResult deployResult) {
  150. params.getConsole().getStdOut().println(
  151. "\nPublished artifacts:\n" +
  152. Joiner.on('\n').join(
  153. FluentIterable
  154. .from(deployResult.getArtifacts())
  155. .transform(
  156. PublishCommand::artifactToString)));
  157. params.getConsole().getStdOut().println("\nDeployRequest:\n" + deployResult.getRequest());
  158. }
  159. private static String artifactToString(Artifact artifact) {
  160. return artifact.toString() + " < " + artifact.getFile();
  161. }
  162. @Override
  163. public ImmutableList<TargetNodeSpec> parseArgumentsAsTargetNodeSpecs(
  164. BuckConfig config, Iterable<String> targetsAsArgs) {
  165. ImmutableList<TargetNodeSpec> specs = super.parseArgumentsAsTargetNodeSpecs(
  166. config,
  167. targetsAsArgs);
  168. if (includeSource) {
  169. specs = ImmutableList.<TargetNodeSpec>builder()
  170. .addAll(specs)
  171. .addAll(
  172. specs.stream()
  173. .filter(
  174. input -> {
  175. if (!(input instanceof BuildTargetSpec)) {
  176. throw new IllegalArgumentException(
  177. "Targets must be explicitly defined when using " +
  178. INCLUDE_SOURCE_LONG_ARG);
  179. }
  180. return !((BuildTargetSpec) input)
  181. .getBuildTarget()
  182. .getFlavors()
  183. .contains(JavaLibrary.SRC_JAR);
  184. })
  185. .map(
  186. input -> BuildTargetSpec.of(
  187. ((BuildTargetSpec) input).getBuildTarget().withFlavors(JavaLibrary.SRC_JAR),
  188. input.getBuildFileSpec()))
  189. .iterator())
  190. .build();
  191. }
  192. // Append "maven" flavor
  193. specs = specs.stream()
  194. .map(input -> {
  195. if (!(input instanceof BuildTargetSpec)) {
  196. throw new IllegalArgumentException(
  197. "Need to specify build targets explicitly when publishing. " +
  198. "Cannot modify " + input);
  199. }
  200. BuildTargetSpec buildTargetSpec = (BuildTargetSpec) input;
  201. BuildTarget buildTarget =
  202. Preconditions.checkNotNull(buildTargetSpec.getBuildTarget());
  203. return buildTargetSpec.withBuildTarget(
  204. BuildTarget
  205. .builder(buildTarget)
  206. .addFlavors(JavaLibrary.MAVEN_JAR)
  207. .build());
  208. })
  209. .collect(MoreCollectors.toImmutableList());
  210. return specs;
  211. }
  212. @Override
  213. public String getShortDescription() {
  214. return "builds and publishes a library to a central repository";
  215. }
  216. }