forked from exercism/javascript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchecksum
More file actions
executable file
·132 lines (108 loc) · 3.68 KB
/
Copy pathchecksum
File metadata and controls
executable file
·132 lines (108 loc) · 3.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/env node
/**
* Run this script (from root directory): npx babel-node scripts/checksum
*
* This will check root `package.json` matches each exercise's `package.json`.
* But the catch is there are some dependencies used for build but not served to end users
* We skip those dependencies while performing checksum.
* See `SKIP_PACKAGES_FOR_CHECKSUM` in helpers.js for list of skipped packages.
*/
const path = require('path');
const shell = require('shelljs');
const helpers = require('./helpers');
/**
* Compares the file of the assignment with some known value
*
* @param filename file to check (local to the assignment directory)
* @param assignment slug with type, eg. practice/two-fer
* @param baseFile the file path that {filename} must be compared against
* @param expectedSha known value of {baseFile}
*/
function checksumAssignment(assignment, filename, baseFile, expectedSha) {
if (!assignment) {
return;
}
const filePath = path.join('exercises', assignment, filename);
let fileSha;
if (filename == 'package.json') {
const packageJson = helpers.prepareExercisePackageJson(filePath, false);
fileSha = helpers.shaPackageJson(packageJson);
} else {
const fileContents = shell.cat(filePath).toString();
fileSha = helpers.sha(fileContents);
}
if (fileSha !== expectedSha) {
const chalk = require('chalk');
const diff = require('diff');
// prettier-ignore
shell.echo(
`[Failure] ${filename} did not match for ${assignment} (${chalk.red(expectedSha)} != ${chalk.green(fileSha)})\n`,
`! Expected ${chalk.red(baseFile)} to match ${chalk.green(filePath)}\n`,
`! Did you forget to run ${chalk.bold(`npx babel-node scripts/sync`)}?\n`
);
if (chalk.supportsColor) {
const diffParts = diff.diffLines(
shell.cat(filePath).toString(),
shell.cat(baseFile).toString(),
{ newlineIsToken: false }
);
const output = diffParts
.map((part) => {
const color = part.added
? chalk.green
: part.removed
? chalk.red
: chalk.gray;
return color(part.value);
})
.join('');
shell.echo(output);
}
shell.exit(1);
}
}
/**
* Check all the exercises, or given, {filename} against {rootFileName}
*
* @param filename filename in the exercise directory
* @param rootFileName filename in the root directory
*/
function checksumAll(filename, rootFileName = filename) {
const assignments = [shell.env['ASSIGNMENT']].filter(Boolean);
let expectedSha;
if (rootFileName == 'exercise-package.json') {
expectedSha = shell.cat('exercise-package.json.sha').toString();
} else {
const fileContents = shell.cat(rootFileName).toString();
expectedSha = helpers.sha(fileContents);
}
if (assignments.length > 0) {
if (
!assignments.every((assignment) => helpers.assertAssignment(assignment))
) {
shell.exit();
}
return assignments.every((assignment) => {
shell.echo(`Checking integrity of ${assignment}/${filename}...`);
return checksumAssignment(
assignment,
filename,
rootFileName,
expectedSha
);
});
}
shell.echo(
`Checking integrity of ${filename} in all ${helpers.assignments.length} exercises`
);
helpers.assignments.forEach((assignment) =>
checksumAssignment(assignment, filename, rootFileName, expectedSha)
);
}
helpers.registerExitHandler();
helpers.createExercisePackageJson(true);
checksumAll('package.json', 'exercise-package.json');
['.eslintrc', '.npmrc', 'babel.config.js', 'LICENSE'].forEach((fileToCheck) => {
checksumAll(fileToCheck);
});
shell.echo('All files passed the checksum test');