microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
1.5.2

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

gulpfile.js

584lines · modeblame

b8ecee4ddigeff10 years ago1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
8ba55f4cJimmy Thomson10 years ago3
74dba829Yuri Skorokhodov7 years ago4const gulp = require("gulp");
5fd423caYuri Skorokhodov7 years ago5const log = require("fancy-log");
74dba829Yuri Skorokhodov7 years ago6const sourcemaps = require("gulp-sourcemaps");
7const path = require("path");
8const preprocess = require("gulp-preprocess");
9const ts = require("gulp-typescript");
10const mocha = require("gulp-mocha");
11const GulpExtras = require("./tools/gulp-extras");
12const minimist = require("minimist");
13const os = require("os");
14const fs = require("fs");
5fd423caYuri Skorokhodov7 years ago15const es = require("event-stream");
16const nls = require("vscode-nls-dev");
2d8af448Yuri Skorokhodov6 years ago17const webpack = require("webpack");
4bb0956eRedMickey5 years ago18const TerserPlugin = require("terser-webpack-plugin");
d55f3c22Yuri Skorokhodov5 years ago19const filter = require("gulp-filter");
2d8af448Yuri Skorokhodov6 years ago20const del = require("del");
de838bbfJiglioNero6 years ago21const vscodeTest = require("vscode-test");
4f8669f9JiglioNero6 years ago22const cp = require("child_process");
8ba55f4cJimmy Thomson10 years ago23
74dba829Yuri Skorokhodov7 years ago24const copyright = GulpExtras.checkCopyright;
25const imports = GulpExtras.checkImports;
26const executeCommand = GulpExtras.executeCommand;
2d8af448Yuri Skorokhodov6 years ago27const tsProject = ts.createProject("tsconfig.json");
74dba829Yuri Skorokhodov7 years ago28
17bf2e64Yuri Skorokhodov6 years ago29/**
30* Whether we're running a nightly build.
31*/
2d8af448Yuri Skorokhodov6 years ago32const isNightly = process.argv.includes("--nightly");
17bf2e64Yuri Skorokhodov6 years ago33
f311755cRedMickey5 years ago34const vscodeVersionForTests = "1.48.0";
35
9928222cYuri Skorokhodov5 years ago36const fullExtensionName = isNightly
34472878RedMickey5 years ago37? "msjsdiag.vscode-react-native-preview"
38: "msjsdiag.vscode-react-native";
9928222cYuri Skorokhodov5 years ago39
34472878RedMickey5 years ago40const extensionName = isNightly ? "vscode-react-native-preview" : "vscode-react-native";
9928222cYuri Skorokhodov5 years ago41
d55f3c22Yuri Skorokhodov5 years ago42const translationProjectName = "vscode-extensions";
74dba829Yuri Skorokhodov7 years ago43const defaultLanguages = [
34472878RedMickey5 years ago44{ id: "zh-tw", folderName: "cht", transifexId: "zh-hant" },
45{ id: "zh-cn", folderName: "chs", transifexId: "zh-hans" },
46{ id: "ja", folderName: "jpn" },
47{ id: "ko", folderName: "kor" },
48{ id: "de", folderName: "deu" },
49{ id: "fr", folderName: "fra" },
50{ id: "es", folderName: "esn" },
51{ id: "ru", folderName: "rus" },
52{ id: "it", folderName: "ita" },
53
54// These language-pack languages are included for VS but excluded from the vscode package
55{ id: "cs", folderName: "csy" },
56{ id: "tr", folderName: "trk" },
57{ id: "pt-br", folderName: "ptb", transifexId: "pt-BR" },
58{ id: "pl", folderName: "plk" },
74dba829Yuri Skorokhodov7 years ago59];
936ae21cmax-mironov8 years ago60
f6ac01ceRuslan Bikkinin7 years ago61const srcPath = "src";
62const testPath = "test";
2d8af448Yuri Skorokhodov6 years ago63const buildDir = "src";
64const distDir = "dist";
65const distSrcDir = `${distDir}/src`;
89973b41dlebu10 years ago66
34472878RedMickey5 years ago67const sources = [srcPath, testPath].map(tsFolder => tsFolder + "/**/*.ts");
8ba55f4cJimmy Thomson10 years ago68
f6ac01ceRuslan Bikkinin7 years ago69const knownOptions = {
34472878RedMickey5 years ago70string: "env",
71default: { env: "production" },
572cd3badigeff10 years ago72};
73
f6ac01ceRuslan Bikkinin7 years ago74const options = minimist(process.argv.slice(2), knownOptions);
3aa3017bDmitry Zinovyev9 years ago75
34472878RedMickey5 years ago76let lintSources = [srcPath, testPath].map(tsFolder => tsFolder + "/**/*.ts");
f6ac01ceRuslan Bikkinin7 years ago77lintSources = lintSources.concat([
34472878RedMickey5 years ago78"!src/typings/**",
79"!test/resources/sampleReactNative022Project/**",
80"!test/smoke/**",
81"!/SmokeTestLogs/**",
f6ac01ceRuslan Bikkinin7 years ago82]);
5fd423caYuri Skorokhodov7 years ago83
2d8af448Yuri Skorokhodov6 years ago84async function runWebpack({
34472878RedMickey5 years ago85packages = [],
86devtool = false,
87compileInPlace = false,
88mode = process.argv.includes("watch") ? "development" : "production",
d55f3c22Yuri Skorokhodov5 years ago89} = options) {
34472878RedMickey5 years ago90let configs = [];
91for (const { entry, library, filename } of packages) {
92const config = {
93mode,
94target: "node",
95entry: path.resolve(entry),
96output: {
97path: compileInPlace ? path.resolve(path.dirname(entry)) : path.resolve(distDir),
98filename: filename || path.basename(entry).replace(".js", ".bundle.js"),
99devtoolModuleFilenameTemplate: "../[resource-path]",
100},
101devtool: devtool,
102resolve: {
103extensions: [".js", ".ts", ".json"],
104},
105module: {
106rules: [
107{
108test: /\.ts$/,
109exclude: /node_modules/,
110use: [
111{
112// vscode-nls-dev loader:
113// * rewrite nls-calls
114loader: "vscode-nls-dev/lib/webpack-loader",
115options: {
116base: path.join(__dirname),
117},
118},
119{
120// configure TypeScript loader:
121// * enable sources maps for end-to-end source maps
122loader: "ts-loader",
123options: {
124compilerOptions: {
125sourceMap: true,
126},
127},
128},
129],
130},
131],
132},
4bb0956eRedMickey5 years ago133optimization: {
134minimize: true,
135minimizer: [
136new TerserPlugin({
137terserOptions: {
138format: {
139comments: /^\**!|@preserve/i,
140},
141},
142extractComments: false,
143}),
144],
145},
34472878RedMickey5 years ago146node: {
147__dirname: false,
148__filename: false,
149},
150externals: {
151vscode: "commonjs vscode",
152},
153};
154
155if (library) {
156config.output.libraryTarget = "commonjs2";
157}
158
159if (process.argv.includes("--analyze-size")) {
160config.plugins = [
161new (require("webpack-bundle-analyzer").BundleAnalyzerPlugin)({
162analyzerMode: "static",
163reportFilename: path.resolve(distSrcDir, path.basename(entry) + ".html"),
164}),
165];
166}
167
168configs.push(config);
d55f3c22Yuri Skorokhodov5 years ago169}
2d8af448Yuri Skorokhodov6 years ago170
34472878RedMickey5 years ago171await new Promise((resolve, reject) =>
172webpack(configs, (err, stats) => {
173if (err) {
174reject(err);
175} else if (stats.hasErrors()) {
176reject(stats);
177} else {
178resolve();
179}
d55f3c22Yuri Skorokhodov5 years ago180}),
34472878RedMickey5 years ago181);
2d8af448Yuri Skorokhodov6 years ago182}
183
184// Generates ./dist/nls.bundle.<language_id>.json from files in ./i18n/** *//<src_path>/<filename>.i18n.json
185// Localized strings are read from these files at runtime.
186const generateSrcLocBundle = () => {
34472878RedMickey5 years ago187// Transpile the TS to JS, and let vscode-nls-dev scan the files for calls to localize.
188return tsProject
189.src()
190.pipe(sourcemaps.init())
191.pipe(tsProject())
192.js.pipe(nls.createMetaDataFiles())
193.pipe(nls.createAdditionalLanguageFiles(defaultLanguages, "i18n"))
194.pipe(nls.bundleMetaDataFiles(fullExtensionName, "dist"))
195.pipe(nls.bundleLanguageFiles())
196.pipe(
197filter([
198"**/nls.bundle.*.json",
199"**/nls.metadata.header.json",
200"**/nls.metadata.json",
201"!src/**",
202]),
203)
204.pipe(gulp.dest("dist"));
2d8af448Yuri Skorokhodov6 years ago205};
206
5fd423caYuri Skorokhodov7 years ago207function build(failOnError, buildNls) {
34472878RedMickey5 years ago208const isProd = options.env === "production";
209const preprocessorContext = isProd ? { PROD: true } : { DEBUG: true };
210let gotError = false;
211log(`Building with preprocessor context: ${JSON.stringify(preprocessorContext)}`);
212const tsResult = tsProject
213.src()
214.pipe(preprocess({ context: preprocessorContext })) //To set environment variables in-line
215.pipe(sourcemaps.init())
216.pipe(tsProject());
217
218return tsResult.js
219.pipe(buildNls ? nls.rewriteLocalizeCalls() : es.through())
220.pipe(
221buildNls
222? nls.createAdditionalLanguageFiles(defaultLanguages, "i18n", ".")
223: es.through(),
224)
225.pipe(buildNls ? nls.bundleMetaDataFiles(fullExtensionName, ".") : es.through())
226.pipe(buildNls ? nls.bundleLanguageFiles() : es.through())
227.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "." }))
228.pipe(gulp.dest(file => file.cwd))
229.once("error", () => {
230gotError = true;
231})
232.once("finish", () => {
233if (failOnError && gotError) {
234process.exit(1);
235}
236});
3aa3017bDmitry Zinovyev9 years ago237}
8ba55f4cJimmy Thomson10 years ago238
f311755cRedMickey5 years ago239async function test(inspectCodeCoverage = false) {
34472878RedMickey5 years ago240// Check if arguments were passed
241if (options.pattern) {
242log(`\nTesting cases that match pattern: ${options.pattern}`);
243} else {
244log(`\nTesting cases that don't match pattern: extensionContext|localizationContext`);
245}
246
247try {
248// The folder containing the Extension Manifest package.json
249// Passed to `--extensionDevelopmentPath`
250const extensionDevelopmentPath = __dirname;
251
252// The path to the extension test runner script
253// Passed to --extensionTestsPath
254const extensionTestsPath = path.resolve(__dirname, "test", "index");
255console.log(extensionTestsPath);
256// Download VS Code, unzip it and run the integration test
f311755cRedMickey5 years ago257
258const testOptions = {
34472878RedMickey5 years ago259extensionDevelopmentPath,
260extensionTestsPath,
f311755cRedMickey5 years ago261version: vscodeVersionForTests,
262};
263
264// Activate inspection of code coverage with unit tests
265if (inspectCodeCoverage) {
266testOptions.extensionTestsEnv = {
267COVERAGE: "true",
268};
269}
270
271await vscodeTest.runTests(testOptions);
34472878RedMickey5 years ago272} catch (err) {
273console.error(err);
274console.error("Failed to run tests");
275process.exit(1);
276}
f6ac01ceRuslan Bikkinin7 years ago277}
278
279gulp.task("check-imports", () => {
34472878RedMickey5 years ago280const tsProject = ts.createProject("tsconfig.json");
281return tsProject.src().pipe(imports());
f6ac01ceRuslan Bikkinin7 years ago282});
283
284gulp.task("check-copyright", () => {
34472878RedMickey5 years ago285return gulp
286.src([
287"**/*.ts",
288"**/*.js",
289"!**/*.d.ts",
290"!coverage/**",
291"!node_modules/**",
292"!test/**/*.js",
293"!SampleApplication/**",
294"!test/resources/sampleReactNative022Project/**/*.js",
295"!test/smoke/package/node_modules/**",
296"!test/smoke/automation/node_modules/**",
297"!test/smoke/resources/**",
298"!test/smoke/vscode/**",
299"!dist/**",
300])
301.pipe(copyright());
f6ac01ceRuslan Bikkinin7 years ago302});
303
34472878RedMickey5 years ago304const runPrettier = (onlyStaged, fix, callback) => {
305const child = cp.fork(
306"./node_modules/@mixer/parallel-prettier/dist/index.js",
307[
308fix ? "--write" : "--list-different",
309"src/**/*.ts",
310"test/**/*.ts",
311"gulpfile.js",
312"*.md",
313"!CHANGELOG.md",
314"!test/smoke/**",
315"!src/**/*.d.ts",
316],
317{
318stdio: "inherit",
319},
320);
321
322child.on("exit", code => (code ? callback(`Prettier exited with code ${code}`) : callback()));
323};
324
4f8669f9JiglioNero6 years ago325const runEslint = (fix, callback) => {
41d17648RedMickey5 years ago326let args = ["--color", "src/**/*.ts"];
327if (fix) {
328args.push("--fix");
329}
330const child = cp.fork("./node_modules/eslint/bin/eslint.js", args, {
331stdio: "inherit",
332cwd: __dirname,
333});
34472878RedMickey5 years ago334
335child.on("exit", code => (code ? callback(`Eslint exited with code ${code}`) : callback()));
d55f3c22Yuri Skorokhodov5 years ago336};
4f8669f9JiglioNero6 years ago337
34472878RedMickey5 years ago338gulp.task("format:prettier", callback => runPrettier(false, true, callback));
339gulp.task("format:eslint", callback => runEslint(true, callback));
340gulp.task("format", gulp.series("format:prettier", "format:eslint"));
341
342gulp.task("lint:prettier", callback => runPrettier(false, false, callback));
343gulp.task("lint:eslint", callback => runEslint(false, callback));
344gulp.task("lint", gulp.parallel("lint:prettier", "lint:eslint"));
fc602bb6Yuri Skorokhodov7 years ago345
2d8af448Yuri Skorokhodov6 years ago346/** Run webpack to bundle the extension output files */
347gulp.task("webpack-bundle", async () => {
34472878RedMickey5 years ago348const packages = [
349{
350entry: `${buildDir}/extension/rn-extension.ts`,
351filename: "rn-extension.js",
352library: true,
353},
354];
355return runWebpack({ packages });
2d8af448Yuri Skorokhodov6 years ago356});
357
358gulp.task("clean", () => {
34472878RedMickey5 years ago359const pathsToDelete = [
360"src/**/*.js",
361"src/**/*.js.map",
362"test/**/*.js",
363"test/**/*.js.map",
364"out/",
365"dist",
366"!test/resources/sampleReactNative022Project/**/*.js",
367".vscode-test/",
368"nls.*.json",
369"!test/smoke/**/*",
370];
371return del(pathsToDelete, { force: true });
2d8af448Yuri Skorokhodov6 years ago372});
373
5fd423caYuri Skorokhodov7 years ago374// TODO: The file property should point to the generated source (this implementation adds an extra folder to the path)
375// We should also make sure that we always generate urls in all the path properties (We shouldn"t have \\s. This seems to
376// be an issue on Windows platforms)
d55f3c22Yuri Skorokhodov5 years ago377gulp.task(
34472878RedMickey5 years ago378"build",
379gulp.series("check-imports", "lint", function runBuild(done) {
380build(true, true).once("finish", () => {
381done();
382});
383}),
d55f3c22Yuri Skorokhodov5 years ago384);
385
386gulp.task(
34472878RedMickey5 years ago387"build-dev",
388gulp.series("check-imports", "lint", function runBuild(done) {
389build(false, false).once("finish", () => {
390done();
391});
392}),
d55f3c22Yuri Skorokhodov5 years ago393);
5fd423caYuri Skorokhodov7 years ago394
fc602bb6Yuri Skorokhodov7 years ago395gulp.task("quick-build", gulp.series("build-dev"));
5fd423caYuri Skorokhodov7 years ago396
d55f3c22Yuri Skorokhodov5 years ago397gulp.task(
34472878RedMickey5 years ago398"watch",
399gulp.series("build", function runWatch() {
400log("Watching build sources...");
401return gulp.watch(sources, gulp.series("build"));
402}),
d55f3c22Yuri Skorokhodov5 years ago403);
8ba55f4cJimmy Thomson10 years ago404
34472878RedMickey5 years ago405gulp.task("prod-build", gulp.series("clean", "webpack-bundle", generateSrcLocBundle));
8ba55f4cJimmy Thomson10 years ago406
2d8af448Yuri Skorokhodov6 years ago407gulp.task("default", gulp.series("prod-build"));
5fd423caYuri Skorokhodov7 years ago408
34472878RedMickey5 years ago409gulp.task("test", gulp.series("build", "lint", test));
28d84585Vladimir Kotikov8 years ago410
62b110e3Dmitry Zinovyev9 years ago411gulp.task("test-no-build", test);
8ba55f4cJimmy Thomson10 years ago412
d55f3c22Yuri Skorokhodov5 years ago413gulp.task(
34472878RedMickey5 years ago414"test:coverage",
f311755cRedMickey5 years ago415gulp.series("quick-build", async function () {
416await test(true);
417}),
d55f3c22Yuri Skorokhodov5 years ago418);
419
420gulp.task(
34472878RedMickey5 years ago421"watch-build-test",
422gulp.series("build", "test", function runWatch() {
423return gulp.watch(sources, gulp.series("build", "test"));
424}),
d55f3c22Yuri Skorokhodov5 years ago425);
7212311dDaniel Lebu10 years ago426
34472878RedMickey5 years ago427gulp.task("package", callback => {
428const command = path.join(__dirname, "node_modules", ".bin", "vsce");
429const args = ["package"];
430executeCommand(command, args, callback);
92f13422Jimmy Thomson9 years ago431});
432
17bf2e64Yuri Skorokhodov6 years ago433function readJson(file) {
34472878RedMickey5 years ago434const contents = fs.readFileSync(path.join(__dirname, file), "utf-8").toString();
435return JSON.parse(contents);
17bf2e64Yuri Skorokhodov6 years ago436}
437
438function writeJson(file, jsonObj) {
34472878RedMickey5 years ago439const content = JSON.stringify(jsonObj, null, 2);
440fs.writeFileSync(path.join(__dirname, file), content);
17bf2e64Yuri Skorokhodov6 years ago441}
442
2d8af448Yuri Skorokhodov6 years ago443/**
444* Generate version number for a nightly build.
445*/
17bf2e64Yuri Skorokhodov6 years ago446const getVersionNumber = () => {
34472878RedMickey5 years ago447const date = new Date(new Date().toLocaleString("en-US", { timeZone: "America/Los_Angeles" }));
448
449return [
450// YY
451date.getFullYear(),
452// MM,
453date.getMonth() + 1,
454//DDHH
455`${date.getDate()}${String(date.getHours()).padStart(2, "0")}`,
456].join(".");
17bf2e64Yuri Skorokhodov6 years ago457};
458
2d8af448Yuri Skorokhodov6 years ago459gulp.task("release", function prepareLicenses() {
34472878RedMickey5 years ago460const backupFiles = [
461"LICENSE.txt",
d55f3c22Yuri Skorokhodov5 years ago462"ThirdPartyNotices.txt",
34472878RedMickey5 years ago463"package.json",
464"package-lock.json",
465];
466const backupFolder = path.resolve(path.join(os.tmpdir(), "vscode-react-native"));
467if (!fs.existsSync(backupFolder)) {
468fs.mkdirSync(backupFolder);
469}
470
471return Promise.resolve()
472.then(() => {
473/* back up LICENSE.txt, ThirdPartyNotices.txt, README.md */
474log("Backing up license files to " + backupFolder + "...");
475backupFiles.forEach(fileName => {
476fs.writeFileSync(path.join(backupFolder, fileName), fs.readFileSync(fileName));
477});
478
479/* copy over the release package license files */
480log("Preparing license files for release...");
481fs.writeFileSync("LICENSE.txt", fs.readFileSync("release/LICENSE.txt"));
482fs.writeFileSync(
483"ThirdPartyNotices.txt",
484fs.readFileSync("release/ThirdPartyNotices.txt"),
485);
486})
487.then(() => {
488let packageJson = readJson("package.json");
489packageJson.main = "./dist/rn-extension";
490if (isNightly) {
491log("Performing nightly release...");
492packageJson.version = getVersionNumber();
493packageJson.name = extensionName;
494packageJson.preview = true;
495packageJson.displayName += " (Preview)";
17bf2e64Yuri Skorokhodov6 years ago496}
34472878RedMickey5 years ago497writeJson("package.json", packageJson);
498log("Creating release package...");
499return new Promise((resolve, reject) => {
500// NOTE: vsce must see npm 3.X otherwise it will not correctly strip out dev dependencies.
501executeCommand(
502"vsce",
503["package"],
504arg => {
505if (arg) {
506reject(arg);
507}
508resolve();
509},
510{ cwd: path.resolve(__dirname) },
511);
512});
513})
514.finally(() => {
515/* restore backed up files */
516log("Restoring modified files...");
517backupFiles.forEach(fileName => {
518fs.writeFileSync(
519path.join(__dirname, fileName),
520fs.readFileSync(path.join(backupFolder, fileName)),
521);
522});
523});
2d8af448Yuri Skorokhodov6 years ago524});
74dba829Yuri Skorokhodov7 years ago525
fc602bb6Yuri Skorokhodov7 years ago526// Creates package.i18n.json files for all languages from {workspaceRoot}/i18n folder into project root
f6ac01ceRuslan Bikkinin7 years ago527gulp.task("add-i18n", () => {
34472878RedMickey5 years ago528return gulp
529.src(["package.nls.json"])
530.pipe(nls.createAdditionalLanguageFiles(defaultLanguages, "i18n"))
531.pipe(gulp.dest("."));
74dba829Yuri Skorokhodov7 years ago532});
533
b6c68212Yuri Skorokhodov7 years ago534// Creates MLCP readable .xliff file and saves it locally
d55f3c22Yuri Skorokhodov5 years ago535gulp.task(
34472878RedMickey5 years ago536"translations-export",
537gulp.series("build", function runTranslationExport() {
538return gulp
539.src(["package.nls.json", "nls.metadata.header.json", "nls.metadata.json"])
540.pipe(nls.createXlfFiles(translationProjectName, fullExtensionName))
541.pipe(gulp.dest(path.join("..", `${translationProjectName}-localization-export`)));
542}),
d55f3c22Yuri Skorokhodov5 years ago543);
74dba829Yuri Skorokhodov7 years ago544
b6c68212Yuri Skorokhodov7 years ago545// Imports localization from raw localized MLCP strings to VS Code .i18n.json files
d55f3c22Yuri Skorokhodov5 years ago546gulp.task(
34472878RedMickey5 years ago547"translations-import",
548gulp.series(done => {
549var options = minimist(process.argv.slice(2), {
550string: "location",
551default: {
552location: "../vscode-translations-import",
553},
554});
555es.merge(
556defaultLanguages.map(language => {
557let id = language.transifexId || language.id;
558log(
559path.join(
560options.location,
561id,
562"vscode-extensions",
563`${fullExtensionName}.xlf`,
564),
565);
566return gulp
567.src(
568path.join(
569options.location,
570id,
571"vscode-extensions",
572`${fullExtensionName}.xlf`,
573),
574)
575.pipe(nls.prepareJsonFiles())
576.pipe(gulp.dest(path.join("./i18n", language.folderName)));
577}),
578).pipe(
579es.wait(() => {
580done();
581}),
d55f3c22Yuri Skorokhodov5 years ago582);
34472878RedMickey5 years ago583}, "add-i18n"),
d55f3c22Yuri Skorokhodov5 years ago584);