-
-
Notifications
You must be signed in to change notification settings - Fork 269
/
utils.js
181 lines (172 loc) · 5.45 KB
/
utils.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
const {spawn} = require('child_process');
const core = require('@actions/core');
/**
* Executes a command and returns its result as promise
* @param cmd {string} command to execute
* @param args {array} command line args
* @param options {Object} extra options
* @return {Promise<Object>}
*/
const exec = (cmd, args = [], options = {}) => new Promise((resolve, reject) => {
let outputData = '';
const optionsToCLI = {
...options
};
if (!optionsToCLI.stdio) {
Object.assign(optionsToCLI, {stdio: ['inherit', 'inherit', 'inherit']});
}
const app = spawn(cmd, args, optionsToCLI);
if (app.stdout) {
// Only needed for pipes
app.stdout.on('data', function (data) {
outputData += data.toString();
});
}
app.on('close', (code) => {
if (code !== 0) {
return reject({code, outputData});
}
return resolve({code, outputData});
});
app.on('error', () => reject({code: 1, outputData}));
});
/**
* Builds the new readme by replacing the readme's <!-- BLOG-POST-LIST:START --><!-- BLOG-POST-LIST:END --> tags
* @param previousContent {string} actual readme content
* @param newContent {string} content to add
* @return {string}: content after combining previousContent and newContent
*/
const buildReadme = (previousContent, newContent) => {
const tagNameInput = core.getInput('comment_tag_name');
const tagToLookFor = tagNameInput ? `<!-- ${tagNameInput}:` : `<!-- BLOG-POST-LIST:`;
const closingTag = '-->';
const tagNewlineFlag = core.getInput('tag_post_pre_newline') === 'true';
const startOfOpeningTagIndex = previousContent.indexOf(
`${tagToLookFor}START`,
);
const endOfOpeningTagIndex = previousContent.indexOf(
closingTag,
startOfOpeningTagIndex,
);
const startOfClosingTagIndex = previousContent.indexOf(
`${tagToLookFor}END`,
endOfOpeningTagIndex,
);
if (
startOfOpeningTagIndex === -1 ||
endOfOpeningTagIndex === -1 ||
startOfClosingTagIndex === -1
) {
// Exit with error if comment is not found on the readme
core.error(
`Cannot find the comment tag on the readme:\n${tagToLookFor}START -->\n${tagToLookFor}END -->`
);
process.exit(1);
}
return [
previousContent.slice(0, endOfOpeningTagIndex + closingTag.length),
tagNewlineFlag ? '\n' : '',
newContent,
tagNewlineFlag ? '\n' : '',
previousContent.slice(startOfClosingTagIndex),
].join('');
};
/**
* Unicode aware javascript truncate
* @param str {string} string to truncated
* @param length {number} length to truncate
* @return {string} truncated value
*/
const truncateString = (str, length) => {
const trimmedString = str.trim();
const truncatedString = [...trimmedString].slice(0, length).join('');
return truncatedString === trimmedString ?
trimmedString : truncatedString.trim() + '...';
};
/**
* Code to do git commit
* @param githubToken {string} github token
* @param readmeFilePaths {string[]} path to the readme file
* @return {Promise<void>}
*/
const commitReadme = async (githubToken, readmeFilePaths) => {
// Getting config
const committerUsername = core.getInput('committer_username');
const committerEmail = core.getInput('committer_email');
const commitMessage = core.getInput('commit_message');
// Doing commit and push
await exec('git', [
'config',
'--global',
'user.email',
committerEmail,
]);
if (githubToken) {
// git remote set-url origin
await exec('git', ['remote', 'set-url', 'origin',
`https://${githubToken}@github.com/${process.env.GITHUB_REPOSITORY}.git`]);
}
await exec('git', ['config', '--global', 'user.name', committerUsername]);
await exec('git', ['add', ...readmeFilePaths]);
await exec('git', ['commit', '-m', commitMessage]);
await exec('git', ['push']);
core.info('Readme updated successfully in the upstream repository');
};
/**
* Compound parameter parser, Updates obj with compound parameters and returns item name
* @param sourceWithParam filter source with compound param eg: stackoverflow/Comment by $author/
* @param obj {Object} object to update
* @return {string} actual source name eg: stackoverflow
*/
const updateAndParseCompoundParams = (sourceWithParam, obj) => {
const param = sourceWithParam.split('/'); // Reading params ['stackoverflow','Comment by $author', '']
if (param.length === 3) {
Object.assign(obj, {[param[0]]: param[1]});
return param[0];// Returning source name
} else {
return sourceWithParam;
}
};
/**
* Returns parsed parameterised templates as array or return null
* @param template
* @param keyName
* @return {null|string[]}
*/
const getParameterisedTemplate = (template, keyName) => {
const key = '$' + keyName + '(';
if (template.indexOf(key) > -1) {
const startIndex = template.indexOf(key) + key.length;
const endIndex = template.indexOf(')', startIndex);
if (endIndex === -1) {
return null;
}
return template.slice(startIndex, endIndex).split(',').map(item => item.trim());
} else {
return null;
}
};
/***
* Returns html encoded version of some of the conflicting markdown special characters
* @param str {string} string to escape
* @return string
*/
const escapeHTML = str => str.replace(/[&<>')("]/g,
(tag) => ({
'&': '&',
'<': '<',
'>': '>',
'\'': ''',
'"': '"',
')': ')',
'(': '('
}[tag]));
module.exports = {
updateAndParseCompoundParams,
commitReadme,
truncateString,
buildReadme,
exec,
getParameterisedTemplate,
escapeHTML
};