This repository was archived by the owner on Aug 23, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.js
158 lines (142 loc) · 4.58 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
/**
* Created by francesco on 2016-09-22.
*/
'use strict';
// internal libs
const fs = require('fs');
const path = require('path');
// external libs
const _ = require('lodash');
/**
* Execute `cmd` synchronously.
*
* @param {string} cmd command to execute
* @param {boolean} [silent] whether to not print output to stdout/err but return it instead
* @param {object} [options] options to pass to child_process.execSync
* @returns {Buffer | String} stdout from the command
*/
const exec = (cmd, silent, options) => {
if (silent) {
return require('child_process').execSync(cmd,
_.defaults(options, {stdio: null, encoding: 'utf8', shell: '/bin/bash'}));
} else {
console.log('\x1b[32m$ \x1b[0m' + cmd);
return require('child_process').execSync(cmd,
_.defaults(options, {stdio: [0, 1, 2], shell: '/bin/bash'}));
}
};
/**
* Execute `cmd` asynchronously.
*
* @param {string} cmd command to execute
* @param {object} [options] options to pass to child_process.exec
* @returns {ChildProcess} ChildProcess
*/
const execAsync = (cmd, options) => {
console.log('\x1b[32m$ \x1b[0m' + cmd);
return require('child_process').exec(cmd,
_.defaults(options, {shell: '/bin/bash'}));
};
/**
* Execute `nRetry` times `cmd` synchronously.
*
* @param {string} cmd command to execute
* @param {number} nRetry number of retries before throwing an error
* @param {boolean} [silent] whether to not print output to stdout/err but return it instead
* @param {object} [options] options to pass to child_process.execSync
* @returns {Buffer | String} stdout from the command
*/
const execRetry = (cmd, nRetry, silent, options) => {
if (nRetry <= 0) {
return exec(cmd, silent, options);
} else {
try {
return exec(cmd, silent, options);
} catch(e) {
return execRetry(cmd, nRetry - 1, silent, options);
}
}
};
/**
* Return the array of subdirectories.
*
* @param {string} srcDir root directory
* @returns {string[]} subdirectories
*/
const getSubDirectories = srcDir => {
return fs.readdirSync(srcDir).filter(file => {
return fs.statSync(path.join(srcDir, file)).isDirectory();
});
};
/**
* Execute a synchronous function under another directory.
*
* @param {string} dir directory
* @param {function} func function to execute under `dir`
* @returns {*} whatever was returned by `func`
*/
const changeDir = (dir, func) => {
const currentDir = process.cwd();
process.chdir(dir);
const res = func();
process.chdir(currentDir);
return res;
};
/**
* Delete all null properties from an object recursively.
*
* @param {object} obj object
* @returns {undefined}
*/
const deleteNullPropertiesDeep = obj => {
for (let key of Object.keys(obj)) {
if (obj[key] === null) {
delete obj[key];
} else if (typeof obj[key] === 'object') {
deleteNullPropertiesDeep(obj[key]);
}
}
};
/**
* Return the name of the current branch in the current working directory.
*
* @returns {string} name of the current branch
*/
const getCurrentBranch = () => {
let currentBranch = exec('git rev-parse --abbrev-ref HEAD', true);
if (currentBranch.indexOf('HEAD') !== -1) { // we are in a detached head
const gitBranchOutput = exec('git branch', true).split('\n');
if (gitBranchOutput.length !== 3) {
console.log('\x1b[31mCritical error: impossible to detect branch name among these:\x1b[0m');
exec('git branch');
process.exit(1);
}
if (gitBranchOutput[0].indexOf('* (HEAD detached at') !== -1) {
// we use the second line
currentBranch = gitBranchOutput[1];
} else {
// we use the first line
currentBranch = gitBranchOutput[0];
}
}
return currentBranch.replace(/[\s]+/g, '');
};
/**
* Return the name of the repository in the current working directory.
*
* @returns {string} name of the repository
*/
const getRepositoryName = () => {
let remoteOriginUrl = exec('git config --get remote.origin.url', true).trim();
if (remoteOriginUrl.indexOf('https://github.com/') === 0 &&
remoteOriginUrl.lastIndexOf('.git') === remoteOriginUrl.length - 4) {
return remoteOriginUrl.slice(19, remoteOriginUrl.length - 4);
} else if (remoteOriginUrl.indexOf('[email protected]:') === 0 &&
remoteOriginUrl.lastIndexOf('.git') === remoteOriginUrl.length - 4) {
return remoteOriginUrl.slice(15, remoteOriginUrl.length - 4);
} else {
throw new Error(remoteOriginUrl + ' is not a valid GitHub repository URL');
}
};
module.exports = {exec, execAsync, execRetry, getSubDirectories, changeDir,
deleteNullPropertiesDeep, getCurrentBranch, getRepositoryName};