Skip to content

Commit 5f2770c

Browse files
committed
build: add hashes to package map
1 parent d2c8281 commit 5f2770c

File tree

2 files changed

+52
-33
lines changed

2 files changed

+52
-33
lines changed

lib/packages.ts

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
'use strict';
99

1010
import { JsonObject } from '@angular-devkit/core';
11+
import * as crypto from 'crypto';
1112
import * as fs from 'fs';
1213
import * as path from 'path';
1314
import * as ts from 'typescript';
1415

16+
const glob = require('glob');
1517
const distRoot = path.join(__dirname, '../dist');
1618

1719

@@ -27,10 +29,44 @@ export interface PackageInfo {
2729
private: boolean;
2830
packageJson: JsonObject;
2931
dependencies: string[];
32+
33+
hash: string;
3034
}
3135
export type PackageMap = { [name: string]: PackageInfo };
3236

3337

38+
const hashCache: {[name: string]: string | null} = {};
39+
function _getHashOf(pkg: PackageInfo): string {
40+
if (!(pkg.name in hashCache)) {
41+
hashCache[pkg.name] = null;
42+
const md5Stream = crypto.createHash('md5');
43+
44+
// Update the stream with all files content.
45+
const files: string[] = glob.sync(path.join(pkg.root, '**'), { nodir: true });
46+
files.forEach(filePath => {
47+
md5Stream.write(`\0${filePath}\0`);
48+
md5Stream.write(fs.readFileSync(filePath));
49+
});
50+
// Update the stream with all versions of upstream dependencies.
51+
pkg.dependencies.forEach(depName => {
52+
md5Stream.write(`\0${depName}\0${_getHashOf(packages[depName])}\0`);
53+
});
54+
55+
md5Stream.end();
56+
57+
hashCache[pkg.name] = (md5Stream.read() as Buffer).toString('hex');
58+
}
59+
60+
if (!hashCache[pkg.name]) {
61+
// Protect against circular dependency.
62+
throw new Error('Circular dependency detected between the following packages: '
63+
+ Object.keys(hashCache).filter(key => hashCache[key] == null).join(', '));
64+
}
65+
66+
return hashCache[pkg.name] !;
67+
}
68+
69+
3470
function loadPackageJson(p: string) {
3571
const root = require('../package.json');
3672
const pkg = require(p);
@@ -108,8 +144,10 @@ const packageJsonPaths = _findAllPackageJson(path.join(__dirname, '..'), exclude
108144
// Remove the root package.json.
109145
.filter(p => p != path.join(__dirname, '../package.json'));
110146

111-
// All the supported packages. Go through the packages directory and create a _map of
112-
// name => fullPath.
147+
148+
// All the supported packages. Go through the packages directory and create a map of
149+
// name => PackageInfo. This map is partial as it lacks some information that requires the
150+
// map itself to finish building.
113151
export const packages: PackageMap =
114152
packageJsonPaths
115153
.map(pkgPath => ({ root: path.dirname(pkgPath) }))
@@ -136,12 +174,14 @@ export const packages: PackageMap =
136174
root: pkgRoot,
137175
relative: path.relative(path.dirname(__dirname), pkgRoot),
138176
main: path.resolve(pkgRoot, 'src/index.ts'),
139-
dependencies: [],
140177
private: packageJson.private,
141178
tar: path.join(distRoot, name.replace('/', '_') + '.tgz'),
142179
bin,
143180
name,
144181
packageJson,
182+
183+
dependencies: [],
184+
hash: '',
145185
};
146186

147187
return packages;
@@ -158,3 +198,9 @@ for (const pkgName of Object.keys(packages)) {
158198
|| name in (pkgJson.peerDependencies || {});
159199
});
160200
}
201+
202+
203+
// Update the hash values of each.
204+
for (const pkgName of Object.keys(packages)) {
205+
packages[pkgName].hash = _getHashOf(packages[pkgName]);
206+
}

scripts/release.ts

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,46 +10,19 @@ import * as fs from 'fs';
1010
import * as path from 'path';
1111
import * as semver from 'semver';
1212
import { ReleaseType } from 'semver';
13-
import { PackageInfo, packages } from '../lib/packages';
13+
import { packages } from '../lib/packages';
1414

15-
const crypto = require('crypto');
16-
const glob = require('glob');
1715
const { hashes, versions } = require('../versions.json');
1816

1917

20-
const hashCache: {[name: string]: string} = {};
21-
function _getHashOf(pkg: PackageInfo): string {
22-
if (!(pkg.name in hashCache)) {
23-
const md5Stream = crypto.createHash('md5');
24-
25-
// Update the stream with all files content.
26-
const files: string[] = glob.sync(path.join(pkg.root, '**'), { nodir: true });
27-
files.forEach(filePath => {
28-
md5Stream.write(`\0${filePath}\0`);
29-
md5Stream.write(fs.readFileSync(filePath));
30-
});
31-
// Update the stream with all versions of upstream dependencies.
32-
pkg.dependencies.forEach(depName => {
33-
md5Stream.write(`\0${depName}\0${_getHashOf(packages[depName])}\0`);
34-
});
35-
36-
md5Stream.end();
37-
38-
hashCache[pkg.name] = md5Stream.read().toString('hex');
39-
}
40-
41-
return hashCache[pkg.name];
42-
}
43-
44-
4518
function _showVersions(logger: Logger) {
4619
for (const pkg of Object.keys(versions)) {
4720
if (!(pkg in packages)) {
4821
logger.fatal(`"${pkg}" not an official package...`);
4922
}
5023

5124
const version = versions[pkg] || '???';
52-
const hash = _getHashOf(packages[pkg]);
25+
const hash = packages[pkg].hash;
5326
const diff = hashes[pkg] !== hash ? '!' : '';
5427

5528
const pad1 = ' '.slice(pkg.length);
@@ -70,7 +43,7 @@ function _upgrade(release: string, logger: Logger) {
7043
versions[pkg] = '0.0.0';
7144
}
7245

73-
const hash = _getHashOf(packages[pkg]);
46+
const hash = packages[pkg].hash;
7447
const version = versions[pkg];
7548
let newVersion: string = version;
7649

0 commit comments

Comments
 (0)