зеркало из https://github.com/microsoft/BuildXL.git
Properly build 'buildxl.dscript' VSCode extension with Npm (#966)
* build vscode extension automatically with BuildXL * copy package-lock.json to cg/npm
This commit is contained in:
Родитель
621edb7bd8
Коммит
b4785aa5f4
|
@ -71,7 +71,7 @@ namespace Node {
|
|||
pkgContents,
|
||||
],
|
||||
prepareTempDirectory: true,
|
||||
dependsOnWindowsDirectories: true,
|
||||
dependsOnCurrentHostOSDirectories: true,
|
||||
dependsOnAppDataDirectory: true,
|
||||
};
|
||||
}
|
||||
|
@ -103,4 +103,25 @@ namespace Node {
|
|||
|
||||
return pkgContents.getFile(executable);
|
||||
}
|
||||
|
||||
@@public
|
||||
export function tscCompile(workingDirectory: Directory, dependencies: StaticDirectory[]) : OpaqueDirectory {
|
||||
const outPath = d`${workingDirectory}/out`;
|
||||
const arguments: Argument[] = [
|
||||
Cmd.argument(Artifact.none(f`${workingDirectory}/node_modules/typescript/lib/tsc.js`)),
|
||||
Cmd.argument("-p"),
|
||||
Cmd.argument("."),
|
||||
];
|
||||
|
||||
const result = Node.run({
|
||||
arguments: arguments,
|
||||
workingDirectory: workingDirectory,
|
||||
dependencies: dependencies,
|
||||
outputs: [
|
||||
{ directory: outPath, kind: "shared" }
|
||||
]
|
||||
});
|
||||
|
||||
return result.getOutputDirectory(outPath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,36 @@ namespace Npm {
|
|||
};
|
||||
}
|
||||
|
||||
@@public
|
||||
export function npmInstall(rootDir: StaticDirectory): OpaqueDirectory {
|
||||
const wd = rootDir.root;
|
||||
const nodeModulesPath = d`${wd}/node_modules`;
|
||||
const npmCachePath = Context.getNewOutputDirectory('npm-install-cache');
|
||||
|
||||
const arguments: Argument[] = [
|
||||
Cmd.argument(Artifact.input(Node.npmCli)),
|
||||
Cmd.argument("install"),
|
||||
Cmd.option("--cache ", Artifact.none(npmCachePath)), // Forces the npm cache to use this output folder for this object so that it doesn't write to user folder
|
||||
];
|
||||
|
||||
const result = Node.run({
|
||||
arguments: arguments,
|
||||
workingDirectory: wd,
|
||||
dependencies: [ rootDir ],
|
||||
outputs: [
|
||||
{ directory: wd, kind: "shared" },
|
||||
npmCachePath, // Place the cache path as an output directory so it is cleaned each time.
|
||||
],
|
||||
environmentVariables: [
|
||||
{ name: "NPM_CONFIG_USERCONFIG", value: f`${wd}/.npmrc` }, // Prevents user configuration to change behavior
|
||||
{ name: "NPM_CONFIG_GLOBALCONFIG", value: f`${wd}/global.npmrc` }, // Prevent machine installed configuration file to change behavior.
|
||||
{ name: "NO_UPDATE_NOTIFIER", value: "1" }, // Prevent npm from checking for the latest version online and write to the user folder with the check information
|
||||
],
|
||||
});
|
||||
|
||||
return result.getOutputDirectory(wd);
|
||||
}
|
||||
|
||||
@@public
|
||||
export interface Arguments {
|
||||
name: string,
|
||||
|
@ -48,7 +78,6 @@ namespace Npm {
|
|||
}
|
||||
|
||||
export interface Result {
|
||||
nodeModules: OpaqueDirectory,
|
||||
nodeModules: OpaqueDirectory
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -53,12 +53,12 @@ export interface DeployedFileWithProvenance {
|
|||
@@public
|
||||
export interface FlattenedResult {
|
||||
flattenedFiles: Map<RelativePath, DeployedFileWithProvenance>,
|
||||
flattenedOpaques: Map<RelativePath, OpaqueDirectory>,
|
||||
flattenedOpaques: Map<RelativePath, OpaqueSubDirectory>, // Tuple of (1) an opaque directory, and (2) a path relative to that opaque directory designating a subdirectory to be added to the deployment
|
||||
visitedItems: Set<Object>,
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper type alias for handeling duplicate file deployments. It can decide to return one or the other, but commonly it should just fail.
|
||||
* Helper type alias for handling duplicate file deployments. It can decide to return one or the other, but commonly it should just fail.
|
||||
* The canaonical implementation is Diagnostics.reportDuplicateError
|
||||
*/
|
||||
@@public
|
||||
|
@ -84,7 +84,7 @@ export interface Deployable {
|
|||
|
||||
/**
|
||||
* Callback for when deployments will be processed. By processing we mean flattening the recursive structure into a flat list which is encoded by the FlattenedResult type.
|
||||
* @param item - The item that is deployable. Think of this as the 'this' pointer which is not accessable from interface implementations.
|
||||
* @param item - The item that is deployable. Think of this as the 'this' pointer which is not accessible from interface implementations.
|
||||
* @param targetFolder - The folder to place this deployable item into
|
||||
* @param onDuplicate - The error handler for duplicate files
|
||||
* @param currentResult - The current flattened result to add the extra flattened files to
|
||||
|
|
|
@ -16,6 +16,31 @@ export interface OnDiskDeployment {
|
|||
|
||||
/** Optional primary file, i.e. an executable or test dll */
|
||||
primaryFile?: File;
|
||||
|
||||
/** Optional opaque directories robocopied/rsynced into this deployment */
|
||||
targetOpaques?: OpaqueDirectory[];
|
||||
}
|
||||
|
||||
@@public
|
||||
export interface OpaqueSubDirectory {
|
||||
/** Parent opaque directory */
|
||||
opaque: OpaqueDirectory,
|
||||
|
||||
/** An optional path relative to that opaque directory designating a subdirectory to be added to the deployment.
|
||||
* If not specified, the whole opaque directory will be added to the deployment
|
||||
*/
|
||||
subDirectory?: RelativePath,
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to represent deployment of a subdirectory of an opaque directory.
|
||||
*
|
||||
* Call the 'createDeployableOpaqueSubDirectory' function below to create an instance of this type.
|
||||
*/
|
||||
@@public
|
||||
export interface DeployableOpaqueSubDirectory extends Deployable, OpaqueSubDirectory {
|
||||
/** This property is set automatically by the 'createDeployableOpaqueSubDirectory' function below */
|
||||
deploy: FlattenForDeploymentFunction
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,6 +64,153 @@ export interface DeployToDiskArguments {
|
|||
deploymentOptions?: DeploymentOptions;
|
||||
}
|
||||
|
||||
@@public
|
||||
export function createDeployableOpaqueSubDirectory(opaque: OpaqueDirectory, sub?: RelativePath): Deployable {
|
||||
return <DeployableOpaqueSubDirectory> {
|
||||
opaque: opaque,
|
||||
subDirectory: sub,
|
||||
deploy: (
|
||||
item: Object,
|
||||
targetFolder: RelativePath,
|
||||
handleDuplicateFile: HandleDuplicateFileDeployment,
|
||||
result: FlattenedResult,
|
||||
deploymentOptions?: Object,
|
||||
provenance?: Diagnostics.Provenance) =>
|
||||
{
|
||||
const existingOpaque = result.flattenedOpaques.get(targetFolder);
|
||||
|
||||
if (existingOpaque !== undefined) {
|
||||
if (!(existingOpaque.opaque === opaque && existingOpaque.subDirectory === sub)) {
|
||||
let subDir = sub || r`.`;
|
||||
Contract.fail(`Duplicate opaque directory. Can't deploy both '${existingOpaque.opaque.root}/${subDir}' and '${opaque.root}/${subDir}' to '${targetFolder}'`);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
return {
|
||||
flattenedFiles: result.flattenedFiles,
|
||||
flattenedOpaques: result.flattenedOpaques.add(targetFolder, {opaque: <OpaqueDirectory>opaque, subDirectory: sub}),
|
||||
visitedItems: result.visitedItems.add(d`{opaque.root}/${sub}`),
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a platform-specific process to copy file from 'source' to 'target'. This process takes a dependency
|
||||
* on 'sourceOpaqueDir`, which should be the parent opaque directory containing the file 'source'.
|
||||
*/
|
||||
@@public
|
||||
export function copyFileFromOpaqueDirectory(source: Path, target: Path, sourceOpaqueDir: OpaqueDirectory): DerivedFile {
|
||||
const args: Transformer.ExecuteArguments = Context.getCurrentHost().os === "win"
|
||||
? <Transformer.ExecuteArguments>{
|
||||
tool: {
|
||||
exe: f`${Context.getMount("Windows").path}/System32/cmd.exe`,
|
||||
dependsOnWindowsDirectories: true,
|
||||
description: "Copy File",
|
||||
},
|
||||
workingDirectory: d`${source.parent}`,
|
||||
arguments: [
|
||||
Cmd.argument("/D"),
|
||||
Cmd.argument("/C"),
|
||||
Cmd.argument("copy"),
|
||||
Cmd.argument("/Y"),
|
||||
Cmd.argument("/V"),
|
||||
Cmd.argument(Artifact.none(source)),
|
||||
Cmd.argument(Artifact.output(target))
|
||||
],
|
||||
dependencies: [
|
||||
sourceOpaqueDir
|
||||
]
|
||||
}
|
||||
: <Transformer.ExecuteArguments>{
|
||||
tool: {
|
||||
exe: f`/bin/cp`,
|
||||
description: "Copy File",
|
||||
dependsOnCurrentHostOSDirectories: true,
|
||||
prepareTempDirectory: true
|
||||
},
|
||||
workingDirectory: d`${source.parent}`,
|
||||
arguments: [
|
||||
Cmd.argument("-f"),
|
||||
Cmd.argument(Artifact.none(source)),
|
||||
Cmd.argument(Artifact.output(target))
|
||||
],
|
||||
dependencies: [
|
||||
sourceOpaqueDir
|
||||
]
|
||||
};
|
||||
|
||||
const result = Transformer.execute(args);
|
||||
return result.getOutputFile(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on the current platform schedules either a robocopy.exe or rsync pip to copy 'sourceDir' to 'targetDir'.
|
||||
* That pip takes a dependency on `sourceDirDep`. If 'sourceDir' is not within `sourceDirDep.root`, disallowed
|
||||
* file accesses are almost certain to happen.
|
||||
*/
|
||||
@@public
|
||||
export function copyDirectory(sourceDir: Directory, targetDir: Directory, sourceDirDep: StaticDirectory): OpaqueDirectory {
|
||||
const args: Transformer.ExecuteArguments = Context.getCurrentHost().os === "win"
|
||||
? <Transformer.ExecuteArguments>{
|
||||
tool: {
|
||||
exe: f`${Context.getMount("Windows").path}/System32/Robocopy.exe`,
|
||||
dependsOnWindowsDirectories: true,
|
||||
description: "Copy Directory",
|
||||
},
|
||||
workingDirectory: targetDir,
|
||||
successExitCodes: [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
4,
|
||||
],
|
||||
arguments: [
|
||||
Cmd.argument(Artifact.none(sourceDir)),
|
||||
Cmd.argument(Artifact.none(targetDir)),
|
||||
Cmd.argument("*.*"),
|
||||
Cmd.argument("/MIR"), // Mirror the directory
|
||||
Cmd.argument("/NJH"), // No Job Header
|
||||
Cmd.argument("/NFL"), // No File list reducing stdout processing
|
||||
Cmd.argument("/NP"), // Don't show per-file progress counter
|
||||
Cmd.argument("/MT"), // Multi threaded
|
||||
],
|
||||
dependencies: [
|
||||
sourceDirDep
|
||||
],
|
||||
outputs: [
|
||||
{ directory: targetDir, kind: "shared" }
|
||||
]
|
||||
}
|
||||
: <Transformer.ExecuteArguments>{
|
||||
tool: {
|
||||
exe: f`/usr/bin/rsync`,
|
||||
description: "Copy Directory",
|
||||
dependsOnCurrentHostOSDirectories: true,
|
||||
prepareTempDirectory: true
|
||||
},
|
||||
workingDirectory: targetDir,
|
||||
arguments: [
|
||||
Cmd.argument("-arvh"),
|
||||
Cmd.argument(Cmd.join("", [ Artifact.none(sourceDir), '/' ])),
|
||||
Cmd.argument(Artifact.none(targetDir)),
|
||||
Cmd.argument("--delete"),
|
||||
],
|
||||
dependencies: [
|
||||
sourceDirDep
|
||||
],
|
||||
outputs: [
|
||||
{ directory: targetDir, kind: "shared" }
|
||||
]
|
||||
};
|
||||
|
||||
const result = Transformer.execute(args);
|
||||
return result.getOutputDirectory(targetDir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploys a given deployment to disk
|
||||
*/
|
||||
|
@ -57,66 +229,26 @@ export function deployToDisk(args: DeployToDiskArguments): OnDiskDeployment {
|
|||
return Transformer.copyFile(data.file, targetPath, args.tags);
|
||||
});
|
||||
|
||||
if (flattened.flattenedOpaques.count() > 0) {
|
||||
const targetOpaques = flattened.flattenedOpaques.forEach(tuple => {
|
||||
const relativeTarget = tuple[0];
|
||||
const opaque = tuple[1];
|
||||
const targetOpaques = flattened.flattenedOpaques.toArray().map(tuple => {
|
||||
const relativeTarget = tuple[0];
|
||||
const opaque = tuple[1].opaque;
|
||||
const opaqueSub = tuple[1].subDirectory || r`.`;
|
||||
|
||||
const targetDir = d`${rootDir}/${relativeTarget}`;
|
||||
const targetDir = d`${rootDir}/${relativeTarget}`;
|
||||
return copyDirectory(d`${opaque}/${opaqueSub}`, targetDir, opaque);
|
||||
});
|
||||
|
||||
const result = Context.getCurrentHost().os === "win"
|
||||
? Transformer.execute({
|
||||
tool: {
|
||||
exe: f`${Context.getMount("Windows").path}/System32/Robocopy.exe`,
|
||||
dependsOnWindowsDirectories: true,
|
||||
description: "Copy Directory",
|
||||
},
|
||||
workingDirectory: targetDir,
|
||||
successExitCodes: [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
4,
|
||||
],
|
||||
arguments: [
|
||||
Cmd.argument(Artifact.input(opaque)),
|
||||
Cmd.argument(Artifact.output(targetDir)),
|
||||
Cmd.argument("*.*"),
|
||||
Cmd.argument("/MIR"), // Mirror the directory
|
||||
Cmd.argument("/NJH"), // No Job Header
|
||||
Cmd.argument("/NFL"), // No File list reducing stdout processing
|
||||
Cmd.argument("/NP"), // Don't show per-file progress counter
|
||||
Cmd.argument("/MT"), // Multi threaded
|
||||
]
|
||||
})
|
||||
: Transformer.execute({
|
||||
tool: {
|
||||
exe: f`/usr/bin/rsync`,
|
||||
description: "Copy Directory",
|
||||
},
|
||||
workingDirectory: targetDir,
|
||||
arguments: [
|
||||
Cmd.argument("-arvh"),
|
||||
Cmd.argument(Cmd.join("", [ Artifact.input(opaque), '/' ])),
|
||||
Cmd.argument(Artifact.output(targetDir)),
|
||||
Cmd.argument("--delete"),
|
||||
]
|
||||
});
|
||||
|
||||
return result.getOutputDirectory(targetDir);
|
||||
});;
|
||||
}
|
||||
|
||||
|
||||
// TODO: We lack the ability to combine files and OpagueDuirecties into a new OpaqueDirectory (unless we write a single process that would do all the copies)
|
||||
// Therefore for now we'll just copy the opaques but don't make it part of the output StaticDirectory field contents
|
||||
// There is a hole here for consumers but today we only use this in selfhost in the final deployment.
|
||||
// TODO: We lack the ability to combine files and OpaqueDirectories into a new OpaqueDirectory (unless we write a single process that would do all the copies)
|
||||
// Therefore for now we'll just copy the opaques but don't make it part of the output StaticDirectory field contents;
|
||||
// we do, however, pass those additional opaque directories along (via the 'targetOpaques' property)
|
||||
// so the caller can appropriately take dependencies on them.
|
||||
const contents = Transformer.sealPartialDirectory(rootDir, targetFiles, args.tags);
|
||||
|
||||
return {
|
||||
deployedDefinition: args.definition,
|
||||
contents: contents,
|
||||
primaryFile : args.primaryFile ? contents.getFile(args.primaryFile) : undefined,
|
||||
targetOpaques: targetOpaques
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -192,4 +324,4 @@ export interface CreateFromDiskOptions {
|
|||
|
||||
/** Whether to recurse into directories or not */
|
||||
recursive?: boolean
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@@public
|
||||
export const emptyFlattenedResult : FlattenedResult = {
|
||||
flattenedFiles: Map.empty<RelativePath, { file: File, disambiguationData: any }>(),
|
||||
flattenedOpaques: Map.empty<RelativePath, OpaqueDirectory>(),
|
||||
flattenedOpaques: Map.empty<RelativePath, OpaqueSubDirectory>(),
|
||||
visitedItems: Set.empty<Object>(),
|
||||
};
|
||||
|
||||
|
@ -230,7 +230,7 @@ function flattenStaticDirectory(staticDirectory: StaticDirectory, targetFolder:
|
|||
|
||||
// TODO: Improve error logging and disambiguation
|
||||
if (existingOpaque !== undefined) {
|
||||
if (existingOpaque !== staticDirectory) {
|
||||
if (existingOpaque[0] !== staticDirectory) {
|
||||
Contract.fail(`Duplicate opaque directory. Can't deploy both '{existingOpaque.root}' and '{staticDirectory.root}' to '{targetFolder}'`);
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ function flattenStaticDirectory(staticDirectory: StaticDirectory, targetFolder:
|
|||
// TODO: Validate if there is a flattenedFile already under this OpaqueDirectory. To implement this we'll need IsWithin on RelativePath
|
||||
return {
|
||||
flattenedFiles: result.flattenedFiles,
|
||||
flattenedOpaques: result.flattenedOpaques.add(targetFolder, <OpaqueDirectory>staticDirectory),
|
||||
flattenedOpaques: result.flattenedOpaques.add(targetFolder, {opaque: <OpaqueDirectory>staticDirectory}),
|
||||
visitedItems: result.visitedItems.add(staticDirectory),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -204,10 +204,10 @@ function createNuSpecFile(
|
|||
// Process the flattened opaque directories
|
||||
for (let opaque of flattened.flattenedOpaques.toArray())
|
||||
{
|
||||
dependencies = dependencies.push(opaque[1]);
|
||||
dependencies = dependencies.push(opaque[1].opaque);
|
||||
fileElements = fileElements.push(
|
||||
Xml.elem("file",
|
||||
Xml.attr("src", [opaque[1].path, "\\**"]),
|
||||
Xml.attr("src", [opaque[1].opaque.path, "\\**"]),
|
||||
Xml.attr("target", opaque[0])
|
||||
)
|
||||
);
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace DeploymentHelpers {
|
|||
const filesResult = runner.addFilesToDrop(createResult, args, filesToAdd);
|
||||
|
||||
// Add all Opaque directories via a batch call.
|
||||
const directoriesToAdd = flattenedResult.flattenedOpaques.forEach(kvp => <DirectoryInfo>{dropPath: kvp[0], directory: kvp[1]});
|
||||
const directoriesToAdd = flattenedResult.flattenedOpaques.forEach(kvp => <DirectoryInfo>{dropPath: kvp[0], directory: kvp[1].opaque});
|
||||
const directoryResults = runner.addDirectoriesToDrop(createResult, args, directoriesToAdd);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,22 +1,46 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
import {Transformer} from "Sdk.Transformers";
|
||||
import {Artifact, Transformer} from "Sdk.Transformers";
|
||||
import * as ManagedSdk from "Sdk.Managed";
|
||||
import * as Deployment from "Sdk.Deployment";
|
||||
import * as Transformers from "Sdk.Transformers";
|
||||
import * as DetoursServices from "BuildXL.Sandbox.Windows";
|
||||
import * as Branding from "BuildXL.Branding";
|
||||
import * as VSIntegration from "BuildXL.Ide.VsIntegration";
|
||||
import {Node, Npm} from "Sdk.NodeJs";
|
||||
|
||||
namespace VsCode.Client {
|
||||
// A new namespace with empty qualifier space to ensure the values inside are evaluated only once
|
||||
export declare const qualifier: {};
|
||||
|
||||
const clientSealDir = Transformer.sealDirectory(d`client`, globR(d`client`));
|
||||
|
||||
const clientCopy: OpaqueDirectory = Deployment.copyDirectory(clientSealDir.root, Context.getNewOutputDirectory("client-copy"), clientSealDir);
|
||||
|
||||
@public
|
||||
export const installRootDir: OpaqueDirectory = Npm.npmInstall(clientCopy);
|
||||
|
||||
@@public
|
||||
export const compileOutDir: OpaqueDirectory = Node.tscCompile(clientCopy.root, [clientCopy, installRootDir]);
|
||||
|
||||
@@public
|
||||
export const deployedNpmPackageLockFile = Deployment.copyFileFromOpaqueDirectory(
|
||||
// Here we want to copy a file from inside an opaque output directory.
|
||||
// If done using Transformer.copyFile we would have no way of specifying a dependency
|
||||
// of that copy pip to the pip producing this opaque directory, so we wouldn't be able to
|
||||
// ensure that the copy operation runs after the opaque directory is produced.
|
||||
p`${installRootDir}/package-lock.json`,
|
||||
p`${Context.getMount("CgNpmRoot").path}/package-lock.json`,
|
||||
installRootDir);
|
||||
}
|
||||
|
||||
namespace LanguageService.Server {
|
||||
|
||||
/**
|
||||
* Builds a VSIX for given version that packages the server assembly (with closure of its references)
|
||||
* as well as client resources
|
||||
*/
|
||||
export function buildVsix(serverAssembly: ManagedSdk.Assembly) : DerivedFile {
|
||||
|
||||
const vsixDeploymentDefinition = buildVsixDeploymentDefinition(serverAssembly);
|
||||
|
||||
// Special "scrubbable" mount should be use for deploying vsix package content.
|
||||
|
@ -34,7 +58,8 @@ namespace LanguageService.Server {
|
|||
outputFileName: `BuildXL.vscode.${qualifier.targetRuntime}.vsix`,
|
||||
inputDirectory: vsixDeployment.contents,
|
||||
useUriEncoding: true,
|
||||
fixUnixPermissions: qualifier.targetRuntime === "osx-x64"
|
||||
fixUnixPermissions: qualifier.targetRuntime === "osx-x64",
|
||||
additionalDependencies: vsixDeployment.targetOpaques
|
||||
});
|
||||
|
||||
return vsix;
|
||||
|
@ -48,7 +73,6 @@ namespace LanguageService.Server {
|
|||
* means that any change to client/src/extension.ts needs to be recompiled and the checked-in file updated.
|
||||
*/
|
||||
export function buildVsixDeploymentDefinition(serverAssembly: ManagedSdk.Assembly) : Deployment.Definition {
|
||||
|
||||
// We have to publish the vsix to the Visual Studio MarketPlace which doesn't handle prerelease tags.
|
||||
let version = Branding.versionNumberForToolsThatDontSupportPreReleaseTag;
|
||||
let manifest = IDE.VersionUtilities.updateVersion(version, f`pluginTemplate/extension.vsixmanifest`);
|
||||
|
@ -89,23 +113,24 @@ namespace LanguageService.Server {
|
|||
subfolder: a`projectManagement`,
|
||||
contents: globR(d`client/projectManagement`)
|
||||
},
|
||||
{
|
||||
subfolder: a`node_modules`,
|
||||
contents: [ Deployment.createDeployableOpaqueSubDirectory(VsCode.Client.installRootDir, r`node_modules`) ]
|
||||
},
|
||||
{
|
||||
subfolder: a`out`,
|
||||
contents: [ VsCode.Client.compileOutDir ]
|
||||
},
|
||||
f`client/License.txt`,
|
||||
f`client/package.nls.json`,
|
||||
readme,
|
||||
f`client/ThirdPartyNotices.txt`,
|
||||
Branding.pngFile,
|
||||
json,
|
||||
|
||||
// This contains the actual extension source as well as the
|
||||
// node_modules that it depends on.
|
||||
Transformer.sealDirectory({
|
||||
root: d`pluginTemplate/extension`,
|
||||
files: globR(d`pluginTemplate/extension`)
|
||||
}),
|
||||
]
|
||||
},
|
||||
f`pluginTemplate/[Content_Types].xml`,
|
||||
manifest
|
||||
manifest,
|
||||
]
|
||||
};
|
||||
|
||||
|
|
|
@ -1,15 +1,5 @@
|
|||
# BuildXL DScript IDE
|
||||
|
||||
## Making a change
|
||||
In order to avoid doing TS compilations in-build (that would have to deal with installing packages, etc.) the 'pluginTemplate' folder contains a checked-in compiled version extension.ts.
|
||||
|
||||
- This means that any changes to files under
|
||||
<b>client/src</b> needs to be recompiled and the checked-in file updated.
|
||||
The recompilation can be triggered by manually running <b>buildVsix.bat</b>, and then replacing <b>pluginTemplate/extension/out/src/extension.ts</b> with the result of the compilation, located under client/out/src.
|
||||
|
||||
- The same goes for node_modules, some of which are checked in. If you update <b>client/package.json</b> with a new version of a node module, please make sure to check in the updated modules to <b>pluginTemplates/extension</b>
|
||||
|
||||
|
||||
## Debugging with VSCode
|
||||
Step by step:
|
||||
> Install NPM (https://www.npmjs.com/get-npm)
|
||||
|
|
|
@ -303,8 +303,6 @@
|
|||
"vscode:prepublish": "npm run compile",
|
||||
"compile": "tsc -p ./",
|
||||
"watch": "tsc -watch -p ./",
|
||||
"update-vscode": "node ./node_modules/vscode/bin/install",
|
||||
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||
"package": "vsce package"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"lockfileVersion": 1
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
@echo off
|
||||
SET myPath=%~dp0
|
||||
set templatePath=%myPath%\pluginTemplate
|
||||
set clientPath=%myPath%\client
|
||||
|
||||
echo Recompiling the plugin
|
||||
cmd /c %clientPath%\node_modules\.bin\tsc -p %clientPath%
|
||||
|
||||
if exist %templatePath%\extension (
|
||||
echo Cleaning template directory
|
||||
rd /s /q %templatePath%\extension
|
||||
)
|
||||
|
||||
echo Updating the template
|
||||
xcopy /q /y /s /e %clientPath%\out\src\*.* %templatePath%\extension\out\src\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode\*.* %templatePath%\extension\node_modules\vscode\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-debugadapter\*.* %templatePath%\extension\node_modules\vscode-debugadapter\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-debugprotocol\*.* %templatePath%\extension\node_modules\vscode-debugprotocol\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-jsonrpc\*.* %templatePath%\extension\node_modules\vscode-jsonrpc\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-languageclient\*.* %templatePath%\extension\node_modules\vscode-languageclient\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-languageserver-protocol\*.* %templatePath%\extension\node_modules\vscode-languageserver-protocol\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-languageserver-types\*.* %templatePath%\extension\node_modules\vscode-languageserver-types\ > NUL
|
||||
xcopy /q /y /s /e %clientPath%\node_modules\vscode-nls\*.* %templatePath%\extension\node_modules\vscode-nls\ > NUL
|
|
@ -36,6 +36,7 @@ namespace Tool.CreateZipPackage {
|
|||
outputFileName: string;
|
||||
useUriEncoding?: boolean;
|
||||
fixUnixPermissions?: boolean;
|
||||
additionalDependencies?: Transformer.InputArtifact[];
|
||||
}
|
||||
|
||||
@@public
|
||||
|
@ -52,7 +53,12 @@ namespace Tool.CreateZipPackage {
|
|||
|
||||
const tool = CreateZipPackage.withQualifier(BuildXLSdk.TargetFrameworks.currentMachineQualifier).deployed;
|
||||
|
||||
const result = Transformer.execute({tool: tool, workingDirectory: wd, arguments: cmdLineArguments});
|
||||
const result = Transformer.execute({
|
||||
tool: tool,
|
||||
workingDirectory: wd,
|
||||
arguments: cmdLineArguments,
|
||||
dependencies: args.additionalDependencies
|
||||
});
|
||||
|
||||
return result.getOutputFile(outFile);
|
||||
}
|
||||
|
|
|
@ -552,7 +552,7 @@ if (!$skipFilter){
|
|||
|
||||
if ($Minimal) {
|
||||
# filtering by core deployment.
|
||||
$AdditionalBuildXLArguments += "/f:(output='$($useDeployment.buildDir)\*'or(output='out\bin\$DeployConfig\Sdk\*')or($CacheOutputFilter))and~($CacheLongRunningFilter)ortag='protobufgenerator'"
|
||||
$AdditionalBuildXLArguments += "/f:(output='$($useDeployment.buildDir)\*'or(output='out\bin\$DeployConfig\Sdk\*')or($CacheOutputFilter))and~($CacheLongRunningFilter)ortag='protobufgenerator'oroutput='cg\*'"
|
||||
}
|
||||
|
||||
if ($Cache) {
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/mocha": {
|
||||
"version": "2.2.44",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz",
|
||||
"integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==",
|
||||
"version": "2.2.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz",
|
||||
"integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "6.0.92",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.92.tgz",
|
||||
"integrity": "sha512-awEYSSTn7dauwVCYSx2CJaPTu0Z1Ht2oR1b2AD3CYao6ZRb+opb6EL43fzmD7eMFgMHzTBWSUzlWSD+S8xN0Nw==",
|
||||
"version": "6.14.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.7.tgz",
|
||||
"integrity": "sha512-YbPXbaynBTe0pVExPhL76TsWnxSPeFAvImIsmylpBWn/yfw+lHy+Q68aawvZHsgskT44ZAoeE67GM5f+Brekew==",
|
||||
"dev": true
|
||||
},
|
||||
"agent-base": {
|
||||
|
@ -508,9 +508,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
|
||||
"integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==",
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz",
|
||||
"integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
|
@ -659,9 +659,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
|
||||
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=",
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
|
||||
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
|
@ -684,9 +684,9 @@
|
|||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
||||
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
|
@ -721,20 +721,20 @@
|
|||
"integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o="
|
||||
},
|
||||
"vscode-languageclient": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.0.tgz",
|
||||
"integrity": "sha1-NtAswYaoNlpEZ3GaKQ+yAKmuSQo=",
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-3.5.1.tgz",
|
||||
"integrity": "sha512-GTQ+hSq/o4c/y6GYmyP9XNrVoIu0NFZ67KltSkqN+tO0eUNDIlrVNX+3DJzzyLhSsrctuGzuYWm3t87mNAcBmQ==",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "^3.5.0"
|
||||
"vscode-languageserver-protocol": "3.5.1"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0.tgz",
|
||||
"integrity": "sha1-Bnxcvidwl5U5jRGWksl+u6FFIgk=",
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz",
|
||||
"integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "^3.5.0",
|
||||
"vscode-languageserver-types": "^3.5.0"
|
||||
"vscode-jsonrpc": "3.5.0",
|
||||
"vscode-languageserver-types": "3.5.0"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
|
@ -645,6 +645,13 @@ config({
|
|||
isWritable: true,
|
||||
isReadable: true,
|
||||
},
|
||||
{
|
||||
name: a`CgNpmRoot`,
|
||||
path: p`cg/npm`,
|
||||
trackSourceFileChanges: true,
|
||||
isWritable: true,
|
||||
isReadable: true
|
||||
},
|
||||
{
|
||||
// Special scrubbable mount with the content that can be cleaned up by running bxl.exe /scrub
|
||||
name: a`ScrubbableDeployment`,
|
||||
|
|
Загрузка…
Ссылка в новой задаче