Skip to content

Commit 0ffe990

Browse files
authored
Print who has access to a set of repos (#124)
* Print who has access to a set of repos * Added more explanations on how to run this script * three command line execution examples * more info what dependencies are needed and how to install
1 parent 6d3783c commit 0ffe990

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed

api/PrintRepoAccess.groovy

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env groovy
2+
3+
/**
4+
* groovy script to show all users that can access a given repository in a GitHub Enterprise instance
5+
*
6+
* Run 'groovy PrintRepoAccess.groovy' to see the list of command line options
7+
*
8+
* Example on how to list access rights for repos foo/bar and bar/foo on GitHub Enterprise instance https://foobar.com:
9+
*
10+
* groovy PrintRepoAccess.groovy -u https://foobar.com -t <access token> foo/bar bar/foo
11+
*
12+
* Example on how to list access rights for repos stored in <org-name>/<repo-name.git> in directory local:
13+
* groovy PrintRepoAccess.groovy -u https://foobar.com -t <access token> -l local
14+
*
15+
* Example that combines the two examples above but uses environmental variables instead of explicit parameters:
16+
*
17+
* export GITHUB_TOKEN="<personal access token>"
18+
* export GITHUB_URL="https://foobar.com"
19+
* groovy PrintRepoAccess.groovy -l local foo/bar bar/foo
20+
*
21+
* Apart from Groovy (and Java), you do not need to install any libraries on your system as the script will download them when you first start it
22+
* The first run may take some time as required dependencies have to get downloaded, then it should be quite fast
23+
*
24+
* If you do not have groovy yet, run 'brew install groovy' on a Mac, for Windows and Linux follow the instructions here:
25+
* http://groovy-lang.org/install.html
26+
*
27+
*/
28+
29+
@Grab(group='org.kohsuke', module='github-api', version='1.75')
30+
import org.kohsuke.github.GitHub
31+
32+
// parsing command line args
33+
cli = new CliBuilder(usage: 'groovy PrintRepoAccess.groovy [options] [repos]\nPrint out users that can access the repos specified, ALL if public repo')
34+
cli.t(longOpt: 'token', 'personal access token of a GitHub Enterprise site admin with repo scope (or use GITHUB_TOKEN env variable)', required: false , args: 1 )
35+
cli.u(longOpt: 'url', 'GitHub Enterprise URL (or use GITHUB_URL env variable), e.g. https://myghe.com', required: false , args: 1 )
36+
cli.l(longOpt: 'localDirectory', 'Directory with org/repo directory structure (show access for all contained repos)', required: false, args: 1)
37+
cli.h(longOpt: 'help', 'Print this usage info', required: false , args: 0 )
38+
39+
OptionAccessor opt = cli.parse(args)
40+
41+
token = opt.t?opt.t:System.getenv("GITHUB_TOKEN")
42+
url = opt.u?opt.u:System.getenv("GITHUB_URL")
43+
44+
// bail out if help parameter was supplied or not sufficient input to proceed
45+
if (opt.h || !token || !url ) {
46+
cli.usage()
47+
return
48+
}
49+
50+
// chop potential trailing slash from GitHub Enterprise URL
51+
url = url.replaceAll('/\$', "")
52+
53+
// connect to GitHub Enterprise
54+
client=GitHub.connectToEnterprise("${url}/api/v3", token)
55+
56+
// printing CSV header
57+
println "REPOSITORY,USER_WITH_ACCESS"
58+
59+
// iterate over all supplied repos
60+
printAccessRightsForCommandLineRepos(opt)
61+
62+
if (opt.l) {
63+
localRepoStore = new File(opt.l)
64+
if (!localRepoStore.isDirectory()) {
65+
printErr "${localRepoStore.canonicalPath} is not a directory"
66+
return
67+
}
68+
printAccessRightsForStoredRepos(localRepoStore)
69+
}
70+
71+
// END OF MAIN
72+
73+
def printAccessRightsForRepo(org, repo) {
74+
if (repo.endsWith(".git")) {
75+
repo=repo.take(repo.length()-4)
76+
}
77+
78+
try {
79+
ghRepo=client.getRepository("${org}/${repo}")
80+
isPublic=!ghRepo.isPrivate()
81+
if (isPublic) {
82+
println "${org}/${repo},ALL"
83+
} else {
84+
ghRepo.getCollaboratorNames().each {
85+
println "${org}/${repo},${it}"
86+
}
87+
}
88+
} catch (Exception e) {
89+
printErr "Could not access repo ${org}/${repo}, skipping ..."
90+
printErr "Reason: ${e.message}"
91+
return
92+
}
93+
}
94+
95+
def printAccessRightsForCommandLineRepos(opt) {
96+
opt.arguments().each {
97+
parsed=it.tokenize("/")
98+
if (parsed.size!=2 || parsed[1] == 0) {
99+
printErr "Could not parse new repo ${it}, please use org/repo format, skipping ..."
100+
return
101+
}
102+
printAccessRightsForRepo(parsed[0], parsed[1])
103+
}
104+
}
105+
106+
def printAccessRightsForStoredRepos(localRepoStore) {
107+
localRepoStore.eachDir { org ->
108+
org.eachDir { repo ->
109+
printAccessRightsForRepo(org.name,repo.name)
110+
}
111+
}
112+
}
113+
114+
def printErr (msg) {
115+
System.err.println "ERROR: ${msg}"
116+
}

0 commit comments

Comments
 (0)