Skip to content

Commit

Permalink
ci: Fix symlinks on Windows (#243)
Browse files Browse the repository at this point in the history
* ci: provide a fix for broken lerna symlinks on windows
* Update appveyor.yml
  • Loading branch information
Jason3S committed Aug 5, 2020
1 parent 68f792d commit 4d225ab
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 4 deletions.
17 changes: 17 additions & 0 deletions .vscode/launch.json
@@ -0,0 +1,17 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${file}"
}
]
}
4 changes: 1 addition & 3 deletions appveyor.yml
Expand Up @@ -6,9 +6,7 @@
environment:
matrix:
# node.js
# - nodejs_version: "12"
# - nodejs_version: "Current"
- nodejs_version: "13"
- nodejs_version: "12"
- nodejs_version: "10"

# Install scripts. (runs after repo cloning)
Expand Down
115 changes: 115 additions & 0 deletions build_tools/bin/symlink.js
@@ -0,0 +1,115 @@
#!/usr/bin/env node

// See: https://github.com/microsoft/vscode-languageserver-node/blob/master/build/bin/linking.js

const path = require('path');
const shell = require('shelljs');

const fs = require('fs');
const promisify = require('util').promisify;
const mkdir = promisify(fs.mkdir);
const exists = promisify(fs.exists);
const readdir = promisify(fs.readdir);
const readFile = promisify(fs.readFile);

/**
* @param {string} module
* @param {string} name
* @param {string} source
*/
async function symlink(module, name, source) {
const current = process.cwd();
try {
const nodeModules = path.join(module, 'node_modules');
if (!await exists(nodeModules)) {
await mkdir(nodeModules);
}
process.chdir(nodeModules);
if (await exists(name)) {
shell.rm('-rf' , name);
}
shell.ln('-s', source, name);
} finally {
process.chdir(current);
}
}

/**
*
* @param {string} file
* @returns {Object|undefined}
*/
async function readPackage(file) {
if (!(await exists(file))) {
return undefined;
}

const json = await readFile(file, 'utf8');
return JSON.parse(json);
}

/**
*
* @param {string} dir
* @returns {Object[]} returns the contents of package.json keyed by the directory
*/
async function readPackages(dir) {
const packageDirs = await readdir(dir);

const packages = [];
for (const package of packageDirs) {
const packageDir = path.join(dir, package);
const p = await readPackage(path.join(packageDir, 'package.json'));
if (p) {
p._packageDir = packageDir;
packages.push(p);
}
}

return packages;
}

/**
* @param {Object[]} packages
* @returns {Map<string,string}
*/
function mapByPackageName(packages) {
const map = new Map(
packages
.filter(p => !!p.name)
.map(p => [p.name, p._packageDir])
);
return map;
}

function extractDependencies(package) {
return Object.keys(package.dependencies || {}).concat(Object.keys(package.devDependencies || {}));
}

/**
*
* @param {Object[]} packages
*/
async function symLinkPackages(packages) {
const mapByName = mapByPackageName(packages);

for (const package of packages) {
console.log('Linking ' + package.name)
const deps = extractDependencies(package);
for (dep of deps) {
const location = mapByName.get(dep);
if (location) {
console.log(' SymLink ' + dep)
await symlink(package._packageDir, dep, location)
}
}
}
}

async function main() {
const packagesRoot = path.resolve(process.argv[2] || 'packages');
const packages = await readPackages(packagesRoot);
symLinkPackages(packages);
}

main();
30 changes: 30 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -14,8 +14,9 @@
"gen-coverage": "lerna run coverage",
"install": "lerna bootstrap --ci",
"lint-travis": "lerna run lint-travis",
"prepare": "npm run clean-build",
"prepare": "npm run symlink && npm run clean-build",
"pub": "npm install && npm test && lerna publish",
"symlink": "node build_tools/bin/symlink.js packages",
"test-spec": "lerna run test-spec",
"test-ts": "lerna run test-ts",
"test-watch": "lerna run --parallel test-watch",
Expand Down Expand Up @@ -47,6 +48,7 @@
"@types/micromatch": "^3.1.1",
"@types/minimatch": "^3.0.3",
"@types/node": "^12.12.39",
"@types/shelljs": "^0.8.8",
"@types/xregexp": "^4.3.0",
"ajv-cli": "^3.1.0",
"chai": "^4.2.0",
Expand All @@ -59,6 +61,7 @@
"lerna": "^3.21.0",
"lorem-ipsum": "^1.0.6",
"rimraf": "^3.0.2",
"shelljs": "^0.8.4",
"source-map-support": "^0.5.16",
"ts-jest": "^25.3.1",
"ts-json-schema-generator": "^0.65.0",
Expand Down

0 comments on commit 4d225ab

Please sign in to comment.