This repository has been archived by the owner on Jul 9, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
danger.js
126 lines (110 loc) · 3.92 KB
/
danger.js
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
// @flow
// Removed import
import { danger, fail, warn } from "danger";
import { any } from "ramda";
import fs from "fs";
// Takes a list of file paths, and converts it into clickable links
const linkableFiles = paths => {
const repoURL = danger.github.pr.head.repo.html_url;
const ref = danger.github.pr.head.ref;
const links = paths.map(path => {
return createLink(`${repoURL}/blob/${ref}/${path}`, path);
});
return toSentence(links);
};
// ["1", "2", "3"] to "1, 2 and 3"
const toSentence = (array: Array<string>): string => {
if (array.length === 1) {
return array[0];
}
return array.slice(0, array.length - 1).join(", ") + " and " + array.pop();
};
// ("/href/thing", "name") to "<a href="/href/thing">name</a>"
const createLink = (href: string, text: string): string =>
`<a href='${href}'>${text}</a>`;
// Raise about missing code inside files
const raiseIssueAboutPaths = (
type: Function,
paths: string[],
codeToInclude: string,
) => {
if (paths.length > 0) {
const files = linkableFiles(paths);
const strict = "<code>" + codeToInclude + "</code>";
type(`Please ensure that ${strict} is enabled on: ${files}`);
}
};
// make sure someone else reviews these changes
const someoneAssigned = danger.github.pr.assignee;
if (someoneAssigned === null) {
warn(
"Please assign someone to merge this PR, and optionally include people who should review.",
);
}
// Make sure there are changelog entries
const hasChangelog = danger.git.modified_files.includes("changelog.md") ||
danger.git.created_files.includes("changelog.md");
if (!hasChangelog) {
fail("No Changelog changes!");
}
// only look in the /src/ folder
const jsModifiedFiles = danger.git.created_files
.filter(path => any(x => x.includes("src/"), path))
.filter(path => path.endsWith("js"));
const hasAppChanges = jsModifiedFiles.length > 0;
const jsTestChanges = jsModifiedFiles.filter(filepath =>
filepath.includes("__tests__"));
const hasTestChanges = jsTestChanges.length > 0;
// Warn when there is a big PR
const bigPRThreshold = 500;
if (danger.github.pr.additions + danger.github.pr.deletions > bigPRThreshold) {
warn(":exclamation: Big PR");
}
// XXX add in License header
// https://github.com/facebook/jest/blob/master/dangerfile.js#L58
// Warn if there are library changes, but not tests
if (hasAppChanges && !hasTestChanges) {
warn(
"There are library changes, but not tests. That's OK as long as you're refactoring existing code",
);
}
// new js files should have `@flow` at the top
const unFlowedFiles = jsModifiedFiles.filter(filepath => {
// don't required flow for tests
if (filepath.match(/__tests__\/$/gmi)) return true;
const content = fs.readFileSync(filepath);
return !content.includes("@flow");
});
raiseIssueAboutPaths(warn, unFlowedFiles, "@flow");
// Be careful of leaving testing shortcuts in the codebase
const onlyTestFiles = jsTestChanges.filter(x => {
const content = fs.readFileSync(x).toString();
return content.includes("it.only") || content.includes("describe.only");
});
raiseIssueAboutPaths(fail, onlyTestFiles, "an `only` was left in the test");
// Politely ask for their name on the entry too
if (hasChangelog) {
const changelogDiff = danger.git.diffForFile("changelog.md");
const contributorName = danger.github.pr.user.login;
if (changelogDiff && changelogDiff.indexOf(contributorName) === -1) {
warn(
'Please add your GitHub name ("' +
contributorName +
'") to the changelog entry.',
);
}
}
// Warns if there are changes to package.json without changes to yarn.lock.
const packageChanged = any(
x => x.includes("package.json"),
danger.git.modified_files,
);
const lockfileChanged = any(
x => x.includes("yarn.lock"),
danger.git.modified_files,
);
if (packageChanged && !lockfileChanged) {
const message = "Changes were made to package.json, but not to yarn.lock";
const idea = "Perhaps you need to run `yarn install`?";
warn(`${message} - <i>${idea}</i>`);
}