public ExitCode runWithoutHelp()

in src/com/facebook/buck/cli/CacheCommand.java [115:311]


  public ExitCode runWithoutHelp(CommandRunnerParams params) throws Exception {

    params.getBuckEventBus().post(ConsoleEvent.fine("cache command start"));

    if (isNoCache()) {
      params.getBuckEventBus().post(ConsoleEvent.severe("Caching is disabled."));
      return ExitCode.NOTHING_TO_DO;
    }

    List<String> arguments = getArguments();

    // Lack of arguments implicitly means fetch now. The old behaviour will be deprecated soon.
    // TODO(nga): Remove old behaviour of buck cache.
    if (!arguments.isEmpty() && arguments.get(0).equals("fetch")) {
      arguments = arguments.subList(1, arguments.size());
    } else {
      if (!MUTE_FETCH_SUBCOMMAND_WARNING) {
        params
            .getConsole()
            .printErrorText(
                "Using `cache` without a command is deprecated, use `cache fetch` instead");
      }
    }

    if (arguments.isEmpty() && targetsWithRuleKeys.isEmpty()) {
      throw new CommandLineException("no cache keys specified");
    }

    if (outputDir != null) {
      outputPath = Optional.of(Paths.get(outputDir));
      Files.createDirectories(outputPath.get());
    }

    ImmutableList<RuleKey> rawRuleKeys =
        arguments.stream().map(RuleKey::new).collect(ImmutableList.toImmutableList());

    ImmutableList<Pair<BuildTarget, RuleKey>> pairedRuleKeys =
        targetsWithRuleKeys.stream()
            .map(pair -> parseTargetRuleKeyPair(params, pair))
            .collect(ImmutableList.toImmutableList());

    Path tmpDir = Files.createTempDirectory("buck-cache-command");

    BuildEvent.Started started = BuildEvent.started(getArguments());

    List<ArtifactRunner> results = null;
    try (ArtifactCache cache = params.getArtifactCacheFactory().newInstance();
        CommandThreadManager pool =
            new CommandThreadManager("Build", getConcurrencyLimit(params.getBuckConfig()))) {
      WeightedListeningExecutorService executor = pool.getWeightedListeningExecutorService();

      fakeOutParseEvents(params.getBuckEventBus());

      params.getBuckEventBus().post(started);

      // Fetch all artifacts
      List<ListenableFuture<ArtifactRunner>> futures = new ArrayList<>();
      for (RuleKey ruleKey : rawRuleKeys) {
        futures.add(
            executor.submit(
                new ArtifactRunner(
                    params.getProjectFilesystemFactory(), null, ruleKey, tmpDir, cache)));
      }

      for (Pair<BuildTarget, RuleKey> targetRuleKeyPair : pairedRuleKeys) {
        futures.add(
            executor.submit(
                new ArtifactRunner(
                    params.getProjectFilesystemFactory(),
                    targetRuleKeyPair.getFirst(),
                    targetRuleKeyPair.getSecond(),
                    tmpDir,
                    cache)));
      }

      // Wait for all executions to complete or fail.
      try {
        results = Futures.allAsList(futures).get();
      } catch (ExecutionException ex) {
        params.getConsole().printBuildFailure("Failed");
        ex.printStackTrace(params.getConsole().getStdErr());
      }
    }

    int totalRuns = results.size();
    StringBuilder resultString = new StringBuilder();
    int goodRuns = 0;

    HashMap<ArtifactCacheMode, AtomicInteger> cacheHitsPerMode = new HashMap<>();
    HashMap<ArtifactCacheMode, AtomicInteger> cacheErrorsPerMode = new HashMap<>();
    HashMap<ArtifactCacheMode, AtomicLong> cacheBytesPerMode = new HashMap<>();
    for (ArtifactCacheMode mode : ArtifactCacheMode.values()) {
      cacheHitsPerMode.put(mode, new AtomicInteger(0));
      cacheErrorsPerMode.put(mode, new AtomicInteger(0));
      cacheBytesPerMode.put(mode, new AtomicLong(0L));
    }
    int cacheHits = 0;
    int cacheMisses = 0;
    int cacheErrors = 0;
    int cacheIgnored = 0;
    int localKeyUnchanged = 0;
    long cacheBytes = 0L;

    for (ArtifactRunner r : results) {
      if (r.completed) {
        goodRuns++;
      }
      resultString.append(r.resultString);
      ArtifactCacheMode artifactCacheMode = r.cacheResultMode.orElse(ArtifactCacheMode.unknown);
      switch (r.cacheResultType) {
        case ERROR:
        case SOFT_ERROR:
          if (cacheErrorsPerMode.containsKey(artifactCacheMode)) {
            cacheErrorsPerMode.get(artifactCacheMode).incrementAndGet();
          }
          ++cacheErrors;
          break;
        case CONTAINS:
          // Ignore it since it will be counted as a hit later.
          break;
        case HIT:
          if (cacheHitsPerMode.containsKey(artifactCacheMode)) {
            cacheHitsPerMode.get(artifactCacheMode).incrementAndGet();
          }
          AtomicLong bytes = cacheBytesPerMode.get(artifactCacheMode);
          if (bytes != null) {
            bytes.addAndGet(r.artifactSize);
          }
          ++cacheHits;
          cacheBytes += r.artifactSize;
          break;
        case MISS:
          ++cacheMisses;
          break;
        case IGNORED:
          ++cacheIgnored;
          break;
        case LOCAL_KEY_UNCHANGED_HIT:
          ++localKeyUnchanged;
          break;
        case SKIPPED:
          break;
      }

      if (!outputPath.isPresent()) {
        // legacy output
        if (r.completed) {
          params.getConsole().getStdOut().println(resultString);

          params
              .getConsole()
              .printSuccess(
                  String.format(
                      "Successfully downloaded artifact with id %s at %s.", r.ruleKey, r.artifact));
        } else {
          params
              .getConsole()
              .printErrorText(
                  String.format(
                      "Failed to retrieve an artifact with id %s (%s).", r.ruleKey, r.cacheResult));
        }
      }
    }

    params
        .getBuckEventBus()
        .post(
            CacheCountersSummaryEvent.newSummary(
                CacheCountersSummary.of(
                    cacheHitsPerMode,
                    cacheErrorsPerMode,
                    cacheBytesPerMode,
                    cacheHits,
                    cacheErrors,
                    cacheMisses,
                    cacheIgnored,
                    cacheBytes,
                    localKeyUnchanged,
                    new AtomicInteger(0),
                    new AtomicInteger(0))));

    ExitCode exitCode = (totalRuns == goodRuns) ? ExitCode.SUCCESS : ExitCode.BUILD_ERROR;
    params.getBuckEventBus().post(BuildEvent.finished(started, exitCode));

    if (outputPath.isPresent()) {
      if (totalRuns == goodRuns) {
        params.getConsole().printSuccess("Successfully downloaded all artifacts.");
      } else {
        params
            .getConsole()
            .printErrorText(String.format("Downloaded %d of %d artifacts", goodRuns, totalRuns));
      }
      params.getConsole().getStdOut().println(resultString);
    }

    return exitCode;
  }