Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Commit

Permalink
Work around Buck bug with outputs relative to Buck cell
Browse files Browse the repository at this point in the history
For example, running `buck build cell//:target` will create output with
paths relative to the cell, and not the current Buck root.
  • Loading branch information
Xanewok committed Sep 14, 2018
1 parent 9ce74be commit 9f64faf
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 9 deletions.
33 changes: 26 additions & 7 deletions pkg/nuclide-rust/lib/BuckIntegration.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getRustInputs,
getSaveAnalysisTargets,
normalizeNameForBuckQuery,
getRustBuildFile,
} from './BuckUtils';

import * as BuckService from '../../nuclide-buck-rpc';
Expand All @@ -33,14 +34,30 @@ export async function updateRlsBuildForTask(
) {
const buildTarget = normalizeNameForBuckQuery(task.buildTarget);

const files = await getRustInputs(task.buckRoot, buildTarget);
// Probably not a Rust build target, ignore
if (files.length === 0) {
// Output is relative to Buck root but the built target may be managed by a
// Buck cell (nested Buck root).
// Here, Buck returns input paths relative to the possible cell, but the build
// file always relative to the current Buck root. Because of that, we use the
// build file path to determine the possible Buck cell root to which the
// inputs are relative to.
// FIXME: This is a bug in Buck, only query for files when the output is fixed.
const [buildFile, files] = await Promise.all([
getRustBuildFile(task.buckRoot, buildTarget),
getRustInputs(task.buckRoot, buildTarget),
]);
// Not a Rust build target, ignore
if (buildFile == null || files.length === 0) {
return;
}
const buckRoot = await BuckService.getRootForPath(buildFile);
if (buckRoot == null) {
logger.error(`Couldn't find Buck root for ${buildFile}`);
return;
}

logger.debug(`Detected Buck root: ${buckRoot}`);
// We need only to pick a representative file to get a related lang service
const fileUri = task.buckRoot + '/' + files[0];
logger.debug(`fileUri: ${fileUri}`);
const fileUri = buckRoot + '/' + files[0];

const langService = await service.getLanguageServiceForUri(fileUri);
if (langService == null) {
Expand All @@ -59,20 +76,22 @@ export async function updateRlsBuildForTask(
buildTarget,
);
logger.debug(`analysisTargets: ${analysisTargets.join('\n')}`);
const artifacts: Array<string> = [];

const buildReport = await BuckService.build(task.buckRoot, analysisTargets);
if (!buildReport.success) {
atom.notifications.addError('[nuclide-rust] save-analysis build failed');
return;
}

const artifacts: Array<string> = [];
Object.values(buildReport.results)
// TODO: https://buckbuild.com/command/build.html specifies that for
// FETCHED_FROM_CACHE we might not get an output file - can we force it
// somehow? Or we always locally produce a save-analysis .json file for
// #save-analysis flavor?
.forEach((targetReport: any) => artifacts.push(targetReport.output));
.forEach((targetReport: any) =>
artifacts.push(`${buckRoot}/${targetReport.output}`),
);

const tempfile = await fsPromise.tempfile();
await fsPromise.writeFile(tempfile, artifacts.join('\n'));
Expand Down
15 changes: 13 additions & 2 deletions pkg/nuclide-rust/lib/BuckUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@

import * as BuckService from '../../nuclide-buck-rpc';

export type BuildTarget = string;

export async function getRustBuildFile(
buckRoot: string,
buildTarget: BuildTarget,
): Promise<?string> {
return BuckService.query(
buckRoot,
`buildfile(kind('^rust_.*', ${buildTarget}))`,
[],
).then(buildfiles => buildfiles[0] || null);
}

export function getRustInputs(
buckRoot: string,
buildTarget: BuildTarget,
Expand All @@ -34,8 +47,6 @@ export async function getSaveAnalysisTargets(
return deps.map(dep => dep + '#save-analysis');
}

export type BuildTarget = string;

// FIXME: Copied from nuclide-buck-rpc
// Buck query doesn't allow omitting // or adding # for flavors, this needs to be fixed in buck.
export function normalizeNameForBuckQuery(aliasOrTarget: string): BuildTarget {
Expand Down

0 comments on commit 9f64faf

Please sign in to comment.