aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/skyframe/RepositoryValue.java
blob: 51e3b4cea733a2ae784690446df084cd84a86233 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright 2014 Google Inc. 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.
// 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.google.devtools.build.lib.skyframe;

import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.devtools.build.lib.packages.PackageIdentifier.RepositoryName;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;

/**
 * A local view of an external repository.
 */
public class RepositoryValue implements SkyValue {
  private final Path path;

  /**
   * This is the FileValue for the [output_base]/external/repo-name directory.
   *
   * <p>If path is a symlink, this will keep track of what the symlink actually points to (for
   * checking equality).</p>
   */
  private final FileValue details;

  /**
   * If this repository is using a user-created BUILD file (any of the new_* functions) then that
   * FileValue needs to be propagated up to the PackageLookup so it doesn't get pruned. The BUILD
   * file symlink will be under external/, thus assumed to be immutable, thus Skyframe will prune
   * it. Then user changes will be ignored (in favor of the cached version).
   */
  private final Optional<FileValue> overlaidBuildFile;

  private RepositoryValue(
      Path path, FileValue repositoryDirectory, Optional<FileValue> overlaidBuildFile) {
    this.path = path;
    this.details = repositoryDirectory;
    this.overlaidBuildFile = overlaidBuildFile;
  }

  /**
   * Creates an immutable external repository.
   */
  public static RepositoryValue create(FileValue repositoryDirectory) {
    return new RepositoryValue(
        repositoryDirectory.realRootedPath().asPath(), repositoryDirectory,
        Optional.<FileValue>absent());
  }

  /**
   * Creates an immutable external repository that's a symlink to elsewhere on the system.
   *
   * <p>For local repositories, the repository path is something like [output root]/external/repo
   * and the repository value resolves that to the actual symlink it points to. We don't want to
   * lose the repository path, so this constructor is used.</p>
   */
  public static RepositoryValue create(Path repositoryDirectory, FileValue details) {
    return new RepositoryValue(repositoryDirectory, details, Optional.<FileValue>absent());
  }

  /**
   * Creates an immutable external repository with a mutable BUILD file.
   */
  public static RepositoryValue createNew(
      FileValue repositoryDirectory, FileValue overlaidBuildFile) {
    return new RepositoryValue(
        repositoryDirectory.realRootedPath().asPath(), repositoryDirectory,
        Optional.of(overlaidBuildFile));
  }

  /**
   * Returns the path to the directory containing the repository's contents. This directory is
   * guaranteed to exist.  It may contain a full Bazel repository (with a WORKSPACE file,
   * directories, and BUILD files) or simply contain a file (or set of files) for, say, a jar from
   * Maven.
   */
  public Path getPath() {
    return path;
  }

  public FileValue getRepositoryDirectory() {
    return details;
  }

  public Optional<FileValue> getOverlaidBuildFile() {
    return overlaidBuildFile;
  }

  @Override
  public boolean equals(Object other) {
    if (this == other) {
      return true;
    }

    if (other instanceof RepositoryValue) {
      RepositoryValue otherValue = (RepositoryValue) other;
      return details.equals(otherValue.details)
          && overlaidBuildFile.equals(otherValue.overlaidBuildFile);
    }
    return false;
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(details, overlaidBuildFile);
  }

  @Override
  public String toString() {
    return details + (overlaidBuildFile.isPresent()
        ? " (BUILD file: " + overlaidBuildFile.get() + ")" : "");
  }

  /**
   * Creates a key from the given repository name.
   */
  public static SkyKey key(RepositoryName repository) {
    return new SkyKey(SkyFunctions.REPOSITORY, repository);
  }
}