309 строки
11 KiB
JavaScript
309 строки
11 KiB
JavaScript
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for details.
|
|
|
|
const gulp = require("gulp");
|
|
const log = require("fancy-log");
|
|
const istanbul = require("gulp-istanbul");
|
|
const isparta = require("isparta");
|
|
const sourcemaps = require("gulp-sourcemaps");
|
|
const path = require("path");
|
|
const preprocess = require("gulp-preprocess");
|
|
const ts = require("gulp-typescript");
|
|
const mocha = require("gulp-mocha");
|
|
const GulpExtras = require("./tools/gulp-extras");
|
|
const minimist = require("minimist");
|
|
const os = require("os");
|
|
const fs = require("fs");
|
|
const Q = require("q");
|
|
const es = require("event-stream");
|
|
const remapIstanbul = require("remap-istanbul/lib/gulpRemapIstanbul");
|
|
const nls = require("vscode-nls-dev");
|
|
const libtslint = require("tslint");
|
|
const tslint = require("gulp-tslint");
|
|
|
|
const copyright = GulpExtras.checkCopyright;
|
|
const imports = GulpExtras.checkImports;
|
|
const executeCommand = GulpExtras.executeCommand;
|
|
|
|
const translationProjectName = "vscode-extensions";
|
|
const translationExtensionName = "vscode-react-native";
|
|
const defaultLanguages = [
|
|
{ id: "zh-tw", folderName: "cht", transifexId: "zh-hant" },
|
|
{ id: "zh-cn", folderName: "chs", transifexId: "zh-hans" },
|
|
{ id: "ja", folderName: "jpn" },
|
|
{ id: "ko", folderName: "kor" },
|
|
{ id: "de", folderName: "deu" },
|
|
{ id: "fr", folderName: "fra" },
|
|
{ id: "es", folderName: "esn" },
|
|
{ id: "ru", folderName: "rus" },
|
|
{ id: "it", folderName: "ita" },
|
|
|
|
// These language-pack languages are included for VS but excluded from the vscode package
|
|
{ id: "cs", folderName: "csy" },
|
|
{ id: "tr", folderName: "trk" },
|
|
{ id: "pt-br", folderName: "ptb", transifexId: "pt-BR" },
|
|
{ id: "pl", folderName: "plk" }
|
|
];
|
|
|
|
const srcPath = "src";
|
|
const testPath = "test";
|
|
|
|
const sources = [srcPath, testPath].map((tsFolder) => tsFolder + "/**/*.ts");
|
|
|
|
const knownOptions = {
|
|
string: "env",
|
|
default: { env: "production" }
|
|
};
|
|
|
|
const options = minimist(process.argv.slice(2), knownOptions);
|
|
|
|
let lintSources = [srcPath, testPath].map((tsFolder) => tsFolder + "/**/*.ts");
|
|
lintSources = lintSources.concat([
|
|
"!src/typings/**",
|
|
"!test/resources/sampleReactNative022Project/**",
|
|
"!test/smoke/**",
|
|
"!/SmokeTestLogs/**"
|
|
]);
|
|
|
|
function build(failOnError, buildNls) {
|
|
const tsProject = ts.createProject("tsconfig.json");
|
|
const isProd = options.env === "production";
|
|
const preprocessorContext = isProd ? { PROD: true } : { DEBUG: true };
|
|
let gotError = false;
|
|
log(`Building with preprocessor context: ${JSON.stringify(preprocessorContext)}`);
|
|
const tsResult = tsProject.src()
|
|
.pipe(preprocess({ context: preprocessorContext })) //To set environment variables in-line
|
|
.pipe(sourcemaps.init())
|
|
.pipe(tsProject());
|
|
|
|
return tsResult.js
|
|
.pipe(buildNls ? nls.rewriteLocalizeCalls() : es.through())
|
|
.pipe(buildNls ? nls.createAdditionalLanguageFiles(defaultLanguages, "i18n", ".") : es.through())
|
|
.pipe(buildNls ? nls.bundleMetaDataFiles("msjsdiag.vscode-react-native", ".") : es.through())
|
|
.pipe(buildNls ? nls.bundleLanguageFiles() : es.through())
|
|
.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "." }))
|
|
.pipe(gulp.dest((file) => file.cwd))
|
|
.once("error", () => {
|
|
gotError = true;
|
|
})
|
|
.once("finish", () => {
|
|
if (failOnError && gotError) {
|
|
process.exit(1);
|
|
}
|
|
});
|
|
}
|
|
|
|
function test() {
|
|
// Check if arguments were passed
|
|
if (options.pattern) {
|
|
log(`\nTesting cases that match pattern: ${options.pattern}`);
|
|
} else {
|
|
log("\nTesting cases that don't match pattern: extensionContext|localizationContext");
|
|
}
|
|
|
|
const testResultsPath = path.join(__dirname, "test", "DebuggerTests.xml");
|
|
process.env.MOCHA_FILE = testResultsPath;
|
|
return gulp.src(["test/**/*.test.js", "!test/extension/**"])
|
|
.pipe(mocha({
|
|
ui: "tdd",
|
|
useColors: true,
|
|
invert: !options.pattern,
|
|
grep: options.pattern || "(extensionContext|localizationContext)",
|
|
reporter: "mocha-multi-reporters",
|
|
reporterOptions: {
|
|
configFile: path.resolve("test/mochaReporterConfig.json"),
|
|
},
|
|
}));
|
|
}
|
|
|
|
gulp.task("check-imports", () => {
|
|
const tsProject = ts.createProject("tsconfig.json");
|
|
return tsProject.src()
|
|
.pipe(imports());
|
|
});
|
|
|
|
gulp.task("check-copyright", () => {
|
|
return gulp.src([
|
|
"**/*.ts",
|
|
"**/*.js",
|
|
"!**/*.d.ts",
|
|
"!coverage/**",
|
|
"!node_modules/**",
|
|
"!test/**/*.js",
|
|
"!SampleApplication/**",
|
|
"!test/resources/sampleReactNative022Project/**/*.js",
|
|
"!test/smoke/node_modules/**",
|
|
"!test/smoke/resources/**"
|
|
])
|
|
.pipe(copyright());
|
|
});
|
|
|
|
gulp.task("tslint", () => {
|
|
const program = libtslint.Linter.createProgram("./tsconfig.json");
|
|
return gulp.src(lintSources, { base: "." })
|
|
.pipe(tslint({
|
|
formatter: "verbose",
|
|
program: program
|
|
}))
|
|
.pipe(tslint.report());
|
|
});
|
|
|
|
// TODO: The file property should point to the generated source (this implementation adds an extra folder to the path)
|
|
// We should also make sure that we always generate urls in all the path properties (We shouldn"t have \\s. This seems to
|
|
// be an issue on Windows platforms)
|
|
gulp.task("build", gulp.series("check-imports", "check-copyright", "tslint", function runBuild(done) {
|
|
build(true, true)
|
|
.once("finish", () => {
|
|
done();
|
|
});
|
|
}));
|
|
|
|
gulp.task("build-dev", gulp.series("check-imports", "check-copyright", function runBuild(done) {
|
|
build(false, false)
|
|
.once("finish", () => {
|
|
done();
|
|
});
|
|
}));
|
|
|
|
gulp.task("quick-build", gulp.series("build-dev"));
|
|
|
|
gulp.task("watch", gulp.series("build", function runWatch() {
|
|
log("Watching build sources...");
|
|
return gulp.watch(sources, gulp.series("build"));
|
|
}));
|
|
|
|
gulp.task("clean", () => {
|
|
const del = require("del");
|
|
const pathsToDelete = [
|
|
"src/**/*.js",
|
|
"src/**/*.js.map",
|
|
"test/**/*.js",
|
|
"test/**/*.js.map",
|
|
"out/",
|
|
"!test/resources/sampleReactNative022Project/**/*.js",
|
|
".vscode-test/",
|
|
"nls.*.json",
|
|
"!test/smoke/resources/ReactNativeSample/App.js",
|
|
"!test/smoke/resources/ExpoSample/App.js",
|
|
"!test/smoke/resources/PureRNExpoSample/App.js",
|
|
]
|
|
return del(pathsToDelete, { force: true });
|
|
});
|
|
|
|
gulp.task("default", gulp.series("clean", "build"));
|
|
|
|
gulp.task("test", gulp.series("build", "tslint", test));
|
|
|
|
gulp.task("coverage:instrument", () => {
|
|
return gulp.src(["src/**/*.js", "!test/**"])
|
|
.pipe(istanbul({
|
|
// Use the isparta instrumenter (code coverage for ES6)
|
|
instrumenter: isparta.Instrumenter,
|
|
includeUntested: true
|
|
}))
|
|
// Force `require` to return covered files
|
|
.pipe(istanbul.hookRequire());
|
|
});
|
|
|
|
gulp.task("coverage:report", () => {
|
|
return gulp.src(
|
|
["src/**/*.js", "!test/**"],
|
|
{ read: false }
|
|
)
|
|
.pipe(istanbul.writeReports({
|
|
reporters: ["json", "text-summary"]
|
|
}));
|
|
});
|
|
|
|
gulp.task("coverage:remap", () => {
|
|
return gulp.src("coverage/coverage-final.json")
|
|
.pipe(remapIstanbul({
|
|
reports: {
|
|
"json": "coverage/coverage.json",
|
|
"html": "coverage/html-report"
|
|
}
|
|
}));
|
|
});
|
|
|
|
gulp.task("test-no-build", test);
|
|
|
|
gulp.task("test:coverage", gulp.series("quick-build", "coverage:instrument", "test-no-build", "coverage:report", "coverage:remap"));
|
|
|
|
gulp.task("watch-build-test", gulp.series("build", "test", function runWatch() {
|
|
return gulp.watch(sources, gulp.series("build", "test"));
|
|
}));
|
|
|
|
gulp.task("package", (callback) => {
|
|
const command = path.join(__dirname, "node_modules", ".bin", "vsce");
|
|
const args = ["package"];
|
|
executeCommand(command, args, callback);
|
|
});
|
|
|
|
gulp.task("release", gulp.series("build", function prepareLicenses() {
|
|
const licenseFiles = ["LICENSE.txt", "ThirdPartyNotices.txt"];
|
|
const backupFolder = path.resolve(path.join(os.tmpdir(), "vscode-react-native"));
|
|
if (!fs.existsSync(backupFolder)) {
|
|
fs.mkdirSync(backupFolder);
|
|
}
|
|
|
|
return Q({})
|
|
.then(() => {
|
|
/* back up LICENSE.txt, ThirdPartyNotices.txt, README.md */
|
|
log("Backing up license files to " + backupFolder + "...");
|
|
licenseFiles.forEach((fileName) => {
|
|
fs.writeFileSync(path.join(backupFolder, fileName), fs.readFileSync(fileName));
|
|
});
|
|
|
|
/* copy over the release package license files */
|
|
log("Preparing license files for release...");
|
|
fs.writeFileSync("LICENSE.txt", fs.readFileSync("release/LICENSE.txt"));
|
|
fs.writeFileSync("ThirdPartyNotices.txt", fs.readFileSync("release/ThirdPartyNotices.txt"));
|
|
}).then(() => {
|
|
log("Creating release package...");
|
|
var deferred = Q.defer();
|
|
// NOTE: vsce must see npm 3.X otherwise it will not correctly strip out dev dependencies.
|
|
executeCommand("vsce", ["package"], (arg) => { if (arg) { deferred.reject(arg); } deferred.resolve() }, { cwd: path.resolve(__dirname) });
|
|
return deferred.promise;
|
|
}).finally(() => {
|
|
/* restore backed up files */
|
|
log("Restoring modified files...");
|
|
licenseFiles.forEach((fileName) => {
|
|
fs.writeFileSync(path.join(__dirname, fileName), fs.readFileSync(path.join(backupFolder, fileName)));
|
|
});
|
|
});
|
|
}));
|
|
|
|
// Creates package.i18n.json files for all languages from {workspaceRoot}/i18n folder into project root
|
|
gulp.task("add-i18n", () => {
|
|
return gulp.src(["package.nls.json"])
|
|
.pipe(nls.createAdditionalLanguageFiles(defaultLanguages, "i18n"))
|
|
.pipe(gulp.dest("."))
|
|
});
|
|
|
|
// Creates MLCP readable .xliff file and saves it locally
|
|
gulp.task("translations-export", gulp.series("build", function runTranslationExport() {
|
|
return gulp.src(["package.nls.json", "nls.metadata.header.json", "nls.metadata.json"])
|
|
.pipe(nls.createXlfFiles(translationProjectName, translationExtensionName))
|
|
.pipe(gulp.dest(path.join("..", `${translationProjectName}-localization-export`)));
|
|
}));
|
|
|
|
// Imports localization from raw localized MLCP strings to VS Code .i18n.json files
|
|
gulp.task("translations-import", (done) => {
|
|
var options = minimist(process.argv.slice(2), {
|
|
string: "location",
|
|
default: {
|
|
location: "../vscode-translations-import"
|
|
}
|
|
});
|
|
es.merge(defaultLanguages.map((language) => {
|
|
let id = language.transifexId || language.id;
|
|
log(path.join(options.location, id, 'vscode-extensions', `${translationExtensionName}.xlf`));
|
|
return gulp.src(path.join(options.location, id, 'vscode-extensions', `${translationExtensionName}.xlf`))
|
|
.pipe(nls.prepareJsonFiles())
|
|
.pipe(gulp.dest(path.join("./i18n", language.folderName)));
|
|
}))
|
|
.pipe(es.wait(() => {
|
|
done();
|
|
}));
|
|
});
|