Explorar el Código

Extract the package graph tool

Steven Silvester hace 5 años
padre
commit
1e947ede98
Se han modificado 4 ficheros con 79 adiciones y 88 borrados
  1. 17 17
      buildutils/src/build.ts
  2. 0 44
      buildutils/src/css-dependency.ts
  3. 6 27
      buildutils/src/ensure-repo.ts
  4. 56 0
      buildutils/src/utils.ts

+ 17 - 17
buildutils/src/build.ts

@@ -125,7 +125,6 @@ export namespace Build {
           cssImports.push(name + '/' + data.style);
         }
       }
-      cssImports = cssImports.sort((a, b) => a.localeCompare(b));
 
       // Handle schemas.
       if (schemaDir) {
@@ -163,22 +162,6 @@ export namespace Build {
         );
       }
 
-      // Template the CSS index file.
-      let cssContents = '/* This is a generated file of CSS imports */';
-      cssContents +=
-        '\n/* It was generated by @jupyterlab/buildutils in Build.ensureAssets() */';
-      cssContents += `\n@import url('~${appCSS}');`;
-      cssImports.forEach(cssImport => {
-        cssContents += `\n@import url('~${cssImport}');`;
-      });
-      const indexCSSPath = path.join(output, 'imports.css');
-
-      // Make sure the output dir exists before writing to it.
-      if (!fs.existsSync(output)) {
-        fs.mkdirSync(output);
-      }
-      fs.writeFileSync(indexCSSPath, cssContents, { encoding: 'utf8' });
-
       if (!themePath) {
         return;
       }
@@ -222,6 +205,23 @@ export namespace Build {
       });
     });
 
+    // Template the CSS index file.
+    cssImports = cssImports.sort((a, b) => a.localeCompare(b));
+    let cssContents = '/* This is a generated file of CSS imports */';
+    cssContents +=
+      '\n/* It was generated by @jupyterlab/buildutils in Build.ensureAssets() */';
+    cssContents += `\n@import url('~${appCSS}');`;
+    cssImports.forEach(cssImport => {
+      cssContents += `\n@import url('~${cssImport}');`;
+    });
+    const indexCSSPath = path.join(output, 'imports.css');
+
+    // Make sure the output dir exists before writing to it.
+    if (!fs.existsSync(output)) {
+      fs.mkdirSync(output);
+    }
+    fs.writeFileSync(indexCSSPath, cssContents, { encoding: 'utf8' });
+
     return themeConfig;
   }
 

+ 0 - 44
buildutils/src/css-dependency.ts

@@ -1,44 +0,0 @@
-/*-----------------------------------------------------------------------------
-| Copyright (c) Jupyter Development Team.
-| Distributed under the terms of the Modified BSD License.
-|----------------------------------------------------------------------------*/
-
-import fs = require('fs-extra');
-
-/**
- * Get the name of the packages imported by a file.
- */
-export function getCssPackageImports(filePath: string): string[] {
-  try {
-    const content = fs.readFileSync(filePath, 'utf8');
-    const cssImportRe = /\@import url\('~([^']+)'\);/gm;
-    const deps = [];
-    while (true) {
-      const match = cssImportRe.exec(content);
-      if (match === null) {
-        break;
-      }
-      deps.push(match[1]);
-    }
-    return deps;
-  } catch {
-    return [];
-  }
-}
-
-/**
- * Get the CSS dependencies of a file as a list of package names (without the scope).
- */
-export function getCssDependencies(filePath: string): string[] {
-  return getCssPackageImports(filePath).reduce((pkgs, m) => {
-    let slashSearchStart = 0;
-    if (m[0] === '@') {
-      slashSearchStart = m.indexOf('/') + 1;
-    }
-    const pkg = m.slice(0, m.indexOf('/', slashSearchStart));
-    if (pkgs.indexOf(pkg) === -1) {
-      pkgs.push(pkg);
-    }
-    return pkgs;
-  }, []);
-}

+ 6 - 27
buildutils/src/ensure-repo.ts

@@ -13,7 +13,6 @@
  */
 import * as path from 'path';
 import * as utils from './utils';
-import { DepGraph } from 'dependency-graph';
 import { ensurePackage, IEnsurePackageOptions } from './ensure-package';
 
 type Dict<T> = { [key: string]: T };
@@ -230,6 +229,9 @@ export async function ensureIntegrity(): Promise<boolean> {
 
   const cssImports: Dict<Array<string>> = {};
 
+  // Get the package graph.
+  const graph = utils.getPackageGraph();
+
   // Gather all of our package data.
   paths.forEach(pkgPath => {
     // Read in the package.json.
@@ -241,36 +243,12 @@ export async function ensureIntegrity(): Promise<boolean> {
       return;
     }
 
-    pkgData[data.name] = data;
+    pkgData[data.name] = graph.getNodeData(data.name);
     pkgPaths[data.name] = pkgPath;
     pkgNames[pkgPath] = data.name;
     locals[data.name] = pkgPath;
   });
 
-  // Create a shared dependency graph.
-  const graph = new DepGraph();
-  const recurseDeps = (depName: string) => {
-    const deps: Dict<Array<string>> = pkgData[depName].dependencies || {};
-    graph.addNode(depName);
-    Object.keys(deps).forEach(subDepName => {
-      const hadNode = graph.hasNode(subDepName);
-      graph.addNode(subDepName);
-      graph.addDependency(depName, subDepName);
-      // Add external deps to the cache if needed.
-      if (!(subDepName in pkgData)) {
-        pkgData[subDepName] = require(`${subDepName}/package.json`);
-      }
-      if (!hadNode && !(depName in locals)) {
-        recurseDeps(subDepName);
-      }
-    });
-  };
-
-  // Build up a dependency graph from all our local packages.
-  Object.keys(locals).forEach(name => {
-    recurseDeps(name);
-  });
-
   // Build up an ordered list of CSS imports for each local package.
   Object.keys(locals).forEach(name => {
     const data = pkgData[name];
@@ -289,7 +267,8 @@ export async function ensureIntegrity(): Promise<boolean> {
       if (skip.indexOf(depName) !== -1 || depName in cssData) {
         return;
       }
-      if (pkgData[depName].style) {
+      const depData = graph.getNodeData(depName);
+      if (depData.style) {
         cssData[depName] = [pkgData[depName].style];
       }
     });

+ 56 - 0
buildutils/src/utils.ts

@@ -2,9 +2,12 @@ import path = require('path');
 import glob = require('glob');
 import fs = require('fs-extra');
 import childProcess = require('child_process');
+import { DepGraph } from 'dependency-graph';
 import sortPackageJson = require('sort-package-json');
 import coreutils = require('@phosphor/coreutils');
 
+type Dict<T> = { [key: string]: T };
+
 /**
  * Get all of the lerna package paths.
  */
@@ -181,3 +184,56 @@ export function run(
     .replace(/(\r\n|\n)$/, '')
     .trim();
 }
+
+/**
+ * Get a graph that has all of the package data for the local packages and thier
+ * first order depencies.
+ */
+export function getPackageGraph(): DepGraph<Dict<any>> {
+  // Create a shared dependency graph.
+  const graph = new DepGraph();
+
+  // Pick up all the package versions.
+  const paths = getLernaPaths();
+  const locals: Dict<string> = {};
+
+  // Gather all of our package data.
+  paths.forEach(pkgPath => {
+    // Read in the package.json.
+    let data: any;
+    try {
+      data = readJSONFile(path.join(pkgPath, 'package.json'));
+    } catch (e) {
+      console.error(e);
+      return;
+    }
+    graph.addNode(data.name, data);
+    locals[data.name] = data;
+  });
+
+  const recurseDeps = (data: any) => {
+    const deps: Dict<Array<string>> = data.dependencies || {};
+    graph.addNode(data.name);
+    Object.keys(deps).forEach(depName => {
+      const hadNode = graph.hasNode(depName);
+      graph.addNode(depName);
+      graph.addDependency(data.name, depName);
+      // Get external deps if needed.
+      let depData = locals[depName];
+      if (!(depName in locals)) {
+        depData = require(`${depName}/package.json`);
+      }
+      // Only recursive if we haven't yet recursed and this is a local pkg.
+      if (!hadNode && !(depName in locals)) {
+        recurseDeps(depData);
+      }
+    });
+  };
+
+  // Build up a dependency graph from all our local packages.
+  Object.keys(locals).forEach(name => {
+    recurseDeps(name);
+  });
+
+  return graph;
+}