use of com.google.devtools.build.lib.analysis.BlazeDirectories in project bazel by bazelbuild.
the class RepositoryDelegatorFunction method compute.
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException {
RepositoryName repositoryName = (RepositoryName) skyKey.argument();
Rule rule = RepositoryFunction.getRule(repositoryName, null, env);
if (rule == null) {
return null;
}
BlazeDirectories directories = PrecomputedValue.BLAZE_DIRECTORIES.get(env);
if (directories == null) {
return null;
}
RepositoryFunction handler;
if (rule.getRuleClassObject().isSkylark()) {
handler = skylarkHandler;
} else {
handler = handlers.get(rule.getRuleClass());
}
if (handler == null) {
throw new RepositoryFunctionException(new EvalException(Location.fromFile(directories.getWorkspace().getRelative("WORKSPACE")), "Could not find handler for " + rule), Transience.PERSISTENT);
}
handler.setClientEnvironment(clientEnvironment);
Path repoRoot = RepositoryFunction.getExternalRepositoryDirectory(directories).getRelative(rule.getName());
byte[] ruleSpecificData = handler.getRuleSpecificMarkerData(rule, env);
if (ruleSpecificData == null) {
return null;
}
String ruleKey = computeRuleKey(rule, ruleSpecificData);
Map<String, String> markerData = new TreeMap<>();
Path markerPath = getMarkerPath(directories, rule);
if (handler.isLocal(rule)) {
// Local repositories are always fetched because the operation is generally fast and they do
// not depend on non-local data, so it does not make much sense to try to cache from across
// server instances.
setupRepositoryRoot(repoRoot);
RepositoryDirectoryValue.Builder localRepo = handler.fetch(rule, repoRoot, directories, env, markerData);
if (localRepo == null) {
return null;
} else {
// We write the marker file for local repository essentially for getting the digest and
// injecting it in the RepositoryDirectoryValue.
byte[] digest = writeMarkerFile(markerPath, markerData, ruleKey);
return localRepo.setDigest(digest).build();
}
}
// We check the repository root for existence here, but we can't depend on the FileValue,
// because it's possible that we eventually create that directory in which case the FileValue
// and the state of the file system would be inconsistent.
byte[] markerHash = isFilesystemUpToDate(markerPath, rule, ruleKey, handler, env);
if (env.valuesMissing()) {
return null;
}
if (markerHash != null && repoRoot.exists()) {
// Now that we know that it exists, we can declare a Skyframe dependency on the repository
// root.
RepositoryFunction.getRepositoryDirectory(repoRoot, env);
if (env.valuesMissing()) {
return null;
}
return RepositoryDirectoryValue.builder().setPath(repoRoot).setDigest(markerHash).build();
}
if (isFetch.get()) {
// Fetching enabled, go ahead.
setupRepositoryRoot(repoRoot);
RepositoryDirectoryValue.Builder result = handler.fetch(rule, repoRoot, directories, env, markerData);
if (env.valuesMissing()) {
return null;
}
// No new Skyframe dependencies must be added between calling the repository implementation
// and writing the marker file because if they aren't computed, it would cause a Skyframe
// restart thus calling the possibly very slow (networking, decompression...) fetch()
// operation again. So we write the marker file here immediately.
byte[] digest = writeMarkerFile(markerPath, markerData, ruleKey);
return result.setDigest(digest).build();
}
if (!repoRoot.exists()) {
// The repository isn't on the file system, there is nothing we can do.
throw new RepositoryFunctionException(new IOException("to fix, run\n\tbazel fetch //...\nExternal repository " + repositoryName + " not found and fetching repositories is disabled."), Transience.TRANSIENT);
}
// Declare a Skyframe dependency so that this is re-evaluated when something happens to the
// directory.
FileValue repoRootValue = RepositoryFunction.getRepositoryDirectory(repoRoot, env);
if (env.valuesMissing()) {
return null;
}
// Try to build with whatever is on the file system and emit a warning.
env.getListener().handle(Event.warn(rule.getLocation(), String.format("External repository '%s' is not up-to-date and fetching is disabled. To update, " + "run the build without the '--nofetch' command line option.", rule.getName())));
return RepositoryDirectoryValue.builder().setPath(repoRootValue.realRootedPath().asPath()).setFetchingDelayed().build();
}
use of com.google.devtools.build.lib.analysis.BlazeDirectories in project bazel by bazelbuild.
the class ConfigurationFactory method getConfiguration.
/**
* Returns a {@link com.google.devtools.build.lib.analysis.config.BuildConfiguration} based on the
* given set of build options.
*
* <p>If the configuration has already been created, re-uses it, otherwise, creates a new one.
*/
@Nullable
public BuildConfiguration getConfiguration(PackageProviderForConfigurations loadedPackageProvider, BuildOptions buildOptions, boolean actionsDisabled, Cache<String, BuildConfiguration> cache) throws InvalidConfigurationException, InterruptedException {
String cacheKey = buildOptions.computeCacheKey();
BuildConfiguration result = cache.getIfPresent(cacheKey);
if (result != null) {
return result;
}
Map<Class<? extends Fragment>, Fragment> fragments = new HashMap<>();
// Create configuration fragments
for (ConfigurationFragmentFactory factory : configurationFragmentFactories) {
Class<? extends Fragment> fragmentType = factory.creates();
Fragment fragment = loadedPackageProvider.getFragment(buildOptions, fragmentType);
if (fragment != null && fragments.get(fragment.getClass()) == null) {
fragments.put(fragment.getClass(), fragment);
}
}
BlazeDirectories directories = loadedPackageProvider.getDirectories();
if (loadedPackageProvider.valuesMissing()) {
return null;
}
result = new BuildConfiguration(directories, fragments, buildOptions, actionsDisabled);
cache.put(cacheKey, result);
return result;
}
use of com.google.devtools.build.lib.analysis.BlazeDirectories in project bazel by bazelbuild.
the class MavenServerFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException, RepositoryFunctionException {
String repository = (String) skyKey.argument();
Rule repositoryRule = null;
try {
repositoryRule = RepositoryFunction.getRule(repository, env);
} catch (RepositoryNotFoundException ex) {
// Ignored. We throw a new one below.
}
BlazeDirectories directories = PrecomputedValue.BLAZE_DIRECTORIES.get(env);
if (env.valuesMissing()) {
return null;
}
String serverName;
String url;
Map<String, FileValue> settingsFiles;
boolean foundRepoRule = repositoryRule != null && repositoryRule.getRuleClass().equals(MavenServerRule.NAME);
if (!foundRepoRule) {
if (repository.equals(MavenServerValue.DEFAULT_ID)) {
settingsFiles = getDefaultSettingsFile(directories, env);
serverName = MavenServerValue.DEFAULT_ID;
url = MavenConnector.getMavenCentralRemote().getUrl();
} else {
throw new RepositoryFunctionException(new IOException("Could not find maven repository " + repository), Transience.TRANSIENT);
}
} else {
WorkspaceAttributeMapper mapper = WorkspaceAttributeMapper.of(repositoryRule);
serverName = repositoryRule.getName();
try {
url = mapper.get("url", Type.STRING);
if (!mapper.isAttributeValueExplicitlySpecified("settings_file")) {
settingsFiles = getDefaultSettingsFile(directories, env);
} else {
PathFragment settingsFilePath = new PathFragment(mapper.get("settings_file", Type.STRING));
RootedPath settingsPath = RootedPath.toRootedPath(directories.getWorkspace().getRelative(settingsFilePath), PathFragment.EMPTY_FRAGMENT);
FileValue fileValue = (FileValue) env.getValue(FileValue.key(settingsPath));
if (fileValue == null) {
return null;
}
if (!fileValue.exists()) {
throw new RepositoryFunctionException(new IOException("Could not find settings file " + settingsPath), Transience.TRANSIENT);
}
settingsFiles = ImmutableMap.<String, FileValue>builder().put(USER_KEY, fileValue).build();
}
} catch (EvalException e) {
throw new RepositoryFunctionException(e, Transience.PERSISTENT);
}
}
if (settingsFiles == null) {
return null;
}
Fingerprint fingerprint = new Fingerprint();
try {
for (Map.Entry<String, FileValue> entry : settingsFiles.entrySet()) {
fingerprint.addString(entry.getKey());
Path path = entry.getValue().realRootedPath().asPath();
if (path.exists()) {
fingerprint.addBoolean(true);
fingerprint.addBytes(path.getDigest());
} else {
fingerprint.addBoolean(false);
}
}
} catch (IOException e) {
throw new RepositoryFunctionException(e, Transience.TRANSIENT);
}
byte[] fingerprintBytes = fingerprint.digestAndReset();
if (settingsFiles.isEmpty()) {
return new MavenServerValue(serverName, url, new Server(), fingerprintBytes);
}
DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
if (settingsFiles.containsKey(SYSTEM_KEY)) {
request.setGlobalSettingsFile(settingsFiles.get(SYSTEM_KEY).realRootedPath().asPath().getPathFile());
}
if (settingsFiles.containsKey(USER_KEY)) {
request.setUserSettingsFile(settingsFiles.get(USER_KEY).realRootedPath().asPath().getPathFile());
}
DefaultSettingsBuilder builder = (new DefaultSettingsBuilderFactory()).newInstance();
SettingsBuildingResult result;
try {
result = builder.build(request);
} catch (SettingsBuildingException e) {
throw new RepositoryFunctionException(new IOException("Error parsing settings files: " + e.getMessage()), Transience.TRANSIENT);
}
if (!result.getProblems().isEmpty()) {
throw new RepositoryFunctionException(new IOException("Errors interpreting settings file: " + Arrays.toString(result.getProblems().toArray())), Transience.PERSISTENT);
}
Settings settings = result.getEffectiveSettings();
Server server = settings.getServer(serverName);
server = server == null ? new Server() : server;
return new MavenServerValue(serverName, url, server, fingerprintBytes);
}
use of com.google.devtools.build.lib.analysis.BlazeDirectories in project bazel by bazelbuild.
the class FdoSupportFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws FdoSkyException, InterruptedException {
BlazeDirectories blazeDirectories = PrecomputedValue.BLAZE_DIRECTORIES.get(env);
if (env.valuesMissing()) {
return null;
}
// TODO(kchodorow): create a SkyFunction to get the main repository name and pass it in here.
Path execRoot = blazeDirectories.getExecRoot();
FdoSupportValue.Key key = (FdoSupportValue.Key) skyKey.argument();
FdoSupport fdoSupport;
try {
fdoSupport = FdoSupport.create(env, key.getFdoInstrument(), key.getFdoZip(), key.getLipoMode(), execRoot);
if (env.valuesMissing()) {
return null;
}
} catch (FdoException e) {
throw new FdoSkyException(e, Transience.PERSISTENT);
} catch (IOException e) {
throw new FdoSkyException(e, Transience.TRANSIENT);
}
return new FdoSupportValue(fdoSupport);
}
use of com.google.devtools.build.lib.analysis.BlazeDirectories in project bazel by bazelbuild.
the class BlazeRuntime method newRuntime.
/**
* Creates a new blaze runtime, given the install and output base directories.
*
* <p>Note: This method can and should only be called once per startup, as it also creates the
* filesystem object that will be used for the runtime. So it should only ever be called from the
* main method of the Blaze program.
*
* @param args Blaze startup options.
*
* @return a new BlazeRuntime instance initialized with the given filesystem and directories, and
* an error string that, if not null, describes a fatal initialization failure that makes
* this runtime unsuitable for real commands
*/
private static BlazeRuntime newRuntime(Iterable<BlazeModule> blazeModules, List<String> args, Runnable abruptShutdownHandler) throws AbruptExitException, OptionsParsingException {
OptionsProvider options = parseOptions(blazeModules, args);
for (BlazeModule module : blazeModules) {
module.globalInit(options);
}
BlazeServerStartupOptions startupOptions = options.getOptions(BlazeServerStartupOptions.class);
String productName = startupOptions.productName.toLowerCase(Locale.US);
if (startupOptions.oomMoreEagerlyThreshold != 100) {
new RetainedHeapLimiter(startupOptions.oomMoreEagerlyThreshold).install();
}
PathFragment workspaceDirectory = startupOptions.workspaceDirectory;
PathFragment installBase = startupOptions.installBase;
PathFragment outputBase = startupOptions.outputBase;
// Must be before first use of JNI.
maybeForceJNI(installBase);
// are mandatory options, despite the comment in their declarations.
if (installBase == null || !installBase.isAbsolute()) {
// (includes "" default case)
throw new IllegalArgumentException("Bad --install_base option specified: '" + installBase + "'");
}
if (outputBase != null && !outputBase.isAbsolute()) {
// (includes "" default case)
throw new IllegalArgumentException("Bad --output_base option specified: '" + outputBase + "'");
}
FileSystem fs = null;
for (BlazeModule module : blazeModules) {
FileSystem moduleFs = module.getFileSystem(options);
if (moduleFs != null) {
Preconditions.checkState(fs == null, "more than one module returns a file system");
fs = moduleFs;
}
}
if (fs == null) {
fs = fileSystemImplementation();
}
Path.setFileSystemForSerialization(fs);
SubprocessBuilder.setSubprocessFactory(subprocessFactoryImplementation());
Path installBasePath = fs.getPath(installBase);
Path outputBasePath = fs.getPath(outputBase);
Path workspaceDirectoryPath = null;
if (!workspaceDirectory.equals(PathFragment.EMPTY_FRAGMENT)) {
workspaceDirectoryPath = fs.getPath(workspaceDirectory);
}
ServerDirectories serverDirectories = new ServerDirectories(installBasePath, outputBasePath, startupOptions.installMD5);
Clock clock = BlazeClock.instance();
BlazeRuntime.Builder runtimeBuilder = new BlazeRuntime.Builder().setProductName(productName).setServerDirectories(serverDirectories).setStartupOptionsProvider(options).setClock(clock).setAbruptShutdownHandler(abruptShutdownHandler).setEventBusExceptionHandler(startupOptions.fatalEventBusExceptions || !BlazeVersionInfo.instance().isReleasedBlaze() ? new BlazeRuntime.BugReportingExceptionHandler() : new BlazeRuntime.RemoteExceptionHandler());
if (System.getenv("TEST_TMPDIR") != null && System.getenv("NO_CRASH_ON_LOGGING_IN_TEST") == null) {
LoggingUtil.installRemoteLogger(getTestCrashLogger());
}
runtimeBuilder.addBlazeModule(new BuiltinCommandModule());
for (BlazeModule blazeModule : blazeModules) {
runtimeBuilder.addBlazeModule(blazeModule);
}
BlazeRuntime runtime = runtimeBuilder.build();
BlazeDirectories directories = new BlazeDirectories(serverDirectories, workspaceDirectoryPath, startupOptions.deepExecRoot, productName);
BinTools binTools;
try {
binTools = BinTools.forProduction(directories);
} catch (IOException e) {
throw new AbruptExitException("Cannot enumerate embedded binaries: " + e.getMessage(), ExitCode.LOCAL_ENVIRONMENTAL_ERROR);
}
runtime.initWorkspace(directories, binTools);
if (startupOptions.useCustomExitCodeOnAbruptExit) {
CustomExitCodePublisher.setAbruptExitStatusFileDir(serverDirectories.getOutputBase());
}
AutoProfiler.setClock(runtime.getClock());
BugReport.setRuntime(runtime);
return runtime;
}
Aggregations