Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc5679b7

Browse files
committed
Lint
1 parent6f9e5a5 commitc5679b7

File tree

7 files changed

+57
-22
lines changed

7 files changed

+57
-22
lines changed

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
#github-run-script
2+
23
Run a script on multiple repositories, cloning them if needed.

‎package-lock.json‎

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎src/cli.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const cli = sade("github-run-script <script>", true)
1515
"-s, --search-path",
1616
"A path to search for already-cloned repositories."
1717
)
18+
.option("-t, --terminate","Terminate any spawned processes on error.")
19+
.option("-s, --signal","The signal to terminate a process with.")
1820
.action(handler);
1921

2022
exportdefaultcli;

‎src/handler.ts‎

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
11
import{mkdtemp,readdir,stat,rm}from"fs/promises";
2-
import{spawn}from"child_process";
3-
import{CliFlags,RepoOwner}from"./types";
4-
import{getRepoAndOwner,waitOnChildProcessToExit}from"./utils";
2+
import{ChildProcess,spawnasactualSpawn}from"child_process";
53
importArrayStringMapfrom"array-string-map";
64
importfilterAsyncfrom"node-filter-async";
75
import{tmpdir}from"os";
6+
import{getRepoAndOwner,waitOnChildProcessToExit}from"./utils";
7+
import{CliFlags,RepoOwner}from"./types";
8+
9+
// We need to make a spawn cache. If an exception is thrown,
10+
// we need to be able to comply with the --terminate flag..
11+
constspawnedProcesses:Map<ChildProcess,null>=newMap();
12+
13+
asyncfunctionspawn(command:string,args?:string[],options?:object){
14+
constchildProcess=awaitactualSpawn(command,args,options);
15+
spawnedProcesses.set(childProcess,null);
16+
childProcess.on("exit",()=>spawnedProcesses.delete(childProcess));
17+
returnchildProcess;
18+
}
19+
20+
// eslint-disable-next-line no-undef -- NodeJS is a fake namespace by TypeScript.
21+
functionterminateSpawnCache(signal:NodeJS.Signals="SIGTERM"){
22+
for(constchildProcessofspawnedProcesses.keys()){
23+
childProcess.kill(signal);
24+
}
25+
}
826

927
exportdefaultasyncfunctionhandler(script:string,flags:CliFlags){
10-
console.log(script,flags);
1128
const{owner:defaultOwner,_:repoNames}=flags;
29+
let{ search}=flags;
1230
constrepos:RepoOwner[]=[];
1331
for(constrepoNameofrepoNames){
1432
try{
@@ -20,35 +38,39 @@ export default async function handler(script: string, flags: CliFlags) {
2038
process.exit(1);
2139
}
2240
}
41+
2342
consttempDir=awaitmkdtemp(`${tmpdir()}/github-run-script-`);
2443
try{
2544
constdirectoryMapping:ArrayStringMap<RepoOwner,string>=
2645
newArrayStringMap();
2746
constscanDirectories:Map<string,string[]>=newMap();
28-
if(flags.search){
47+
if(search){
2948
// If it's one path, it won't be in an array. This converts it into an array.
30-
if(typeofflags.search==="string"){
31-
flags.search=[flags.search];
49+
if(typeofsearch==="string"){
50+
search=[search];
3251
}
52+
3353
// What this code block does is simple. It stores in `scanDirectories`
3454
// a mapping of source path name to an array of directories in that directory.
3555
awaitPromise.all(
36-
flags.search.map(async(path)=>{
56+
search.map(async(path)=>{
3757
scanDirectories.set(
3858
path,
39-
awaitfilterAsync(awaitreaddir(path),async(item)=>{
40-
return(awaitstat(`${path}/${item}`)).isDirectory();
41-
})
59+
awaitfilterAsync(awaitreaddir(path),async(item)=>
60+
(awaitstat(`${path}/${item}`)).isDirectory()
61+
)
4262
);
4363
})
4464
);
4565
}
66+
4667
awaitPromise.all(
4768
repos.map(async([owner,repo])=>{
4869
// First, we need to check if the repository exists in `scanDirectories`.
49-
// TODO: Handle cases where the same repo is present multiple times in
50-
// TODO: different directories, or if two repos with the same name but
51-
// TODO: different owners is provided. (Maybe we can check `.git`.)
70+
// TODO:
71+
// Handle cases where the same repo is present multiple times in
72+
// different directories, or if two repos with the same name but
73+
// different owners is provided. (Maybe we can check `.git`.)
5274
for(const[path,directories]ofscanDirectories){
5375
for(constdirectoryofdirectories){
5476
if(repo===directory){
@@ -57,12 +79,14 @@ export default async function handler(script: string, flags: CliFlags) {
5779
break;
5880
}
5981
}
82+
6083
// If we already found a match earlier, no need to re-iterate over the other
6184
// directories.
6285
if(directoryMapping.has([owner,repo])){
6386
break;
6487
}
6588
}
89+
6690
// Deal wit the special case where we did not find a match. Time to clone.
6791
if(!directoryMapping.has([owner,repo])){
6892
constdestPath=`${tempDir}/${repo}`;
@@ -75,6 +99,7 @@ export default async function handler(script: string, flags: CliFlags) {
7599
awaitwaitOnChildProcessToExit(childProc);
76100
directoryMapping.set([owner,repo],destPath);
77101
}
102+
78103
// Time to execute the script!
79104
constpath=directoryMapping.get([owner,repo]);
80105
constchildProc=awaitspawn(script,[],{
@@ -92,6 +117,11 @@ export default async function handler(script: string, flags: CliFlags) {
92117
})
93118
);
94119
}finally{
120+
if(flags.terminate??true){
121+
// eslint-disable-next-line no-undef -- NodeJS is a fake namespace by TypeScript.
122+
terminateSpawnCache(flags.signalasNodeJS.Signals);
123+
}
124+
95125
// We need to clean up the temporary directory.
96126
awaitrm(tempDir,{recursive:true,force:true});
97127
}

‎src/types.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
exportinterfaceCliFlags{
22
owner?:string;
33
search?:string|string[];
4+
terminate?:string|boolean;
5+
signal?:string;
46
_:string[];
57
}
68

‎src/utils.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import{RepoOwner}from"./types";
21
import{ChildProcess}from"child_process";
2+
import{RepoOwner}from"./types";
33

44
exportfunctiongetRepoAndOwner(
55
input:string,

‎tsconfig.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"module":"commonjs",
55
"outDir":"dist",
66
"strict":true,
7-
"target":"es2019",
7+
"target":"es2019"
88
},
99
"include": ["src/**/*"]
1010
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp