|
|
1
|
+#!/usr/bin/env python3
|
|
|
2
|
+
|
|
|
3
|
+from pathlib import Path
|
|
|
4
|
+import subprocess
|
|
|
5
|
+import logging
|
|
|
6
|
+import re
|
|
|
7
|
+
|
|
|
8
|
+logging.basicConfig(level=logging.INFO)
|
|
|
9
|
+
|
|
|
10
|
+IGNORE = 1 # ignore submodule
|
|
|
11
|
+GITHUB_HASKELL = 2 # in the haskell github org
|
|
|
12
|
+ORIGIN = 3 # upstream remote == origin remote
|
|
|
13
|
+
|
|
|
14
|
+def github(owner: str, name: str) -> str:
|
|
|
15
|
+ return f'https://github.com/{owner}/{name}'
|
|
|
16
|
+
|
|
|
17
|
+def github_haskell(name: str) -> str:
|
|
|
18
|
+ return github('haskell', name)
|
|
|
19
|
+
|
|
|
20
|
+def gitlab_ssh(owner: str, name: str) -> str:
|
|
|
21
|
+ return f'git@gitlab.haskell.org:{owner}/{name}'
|
|
|
22
|
+
|
|
|
23
|
+upstreams = {
|
|
|
24
|
+ '.arc-linters/arcanist-external-json-linter': IGNORE,
|
|
|
25
|
+ 'libffi-tarballs': IGNORE,
|
|
|
26
|
+ 'libraries/array': GITHUB_HASKELL,
|
|
|
27
|
+ 'libraries/binary': GITHUB_HASKELL,
|
|
|
28
|
+ 'libraries/bytestring': GITHUB_HASKELL,
|
|
|
29
|
+ 'libraries/Cabal': GITHUB_HASKELL,
|
|
|
30
|
+ 'libraries/containers': GITHUB_HASKELL,
|
|
|
31
|
+ 'libraries/deepseq': GITHUB_HASKELL,
|
|
|
32
|
+ 'libraries/directory': GITHUB_HASKELL,
|
|
|
33
|
+ 'libraries/file-io': GITHUB_HASKELL,
|
|
|
34
|
+ 'libraries/filepath': GITHUB_HASKELL,
|
|
|
35
|
+ 'libraries/ghc-bignum/gmp/gmp-tarballs': ORIGIN,
|
|
|
36
|
+ 'libraries/ghc-internal/gmp/gmp-tarballs': ORIGIN,
|
|
|
37
|
+ 'libraries/haskeline': GITHUB_HASKELL,
|
|
|
38
|
+ 'libraries/hpc': ORIGIN,
|
|
|
39
|
+ 'libraries/integer-gmp/gmp/gmp-tarballs': ORIGIN,
|
|
|
40
|
+ 'libraries/mtl': GITHUB_HASKELL,
|
|
|
41
|
+ 'libraries/os-string': GITHUB_HASKELL,
|
|
|
42
|
+ 'libraries/parallel': GITHUB_HASKELL,
|
|
|
43
|
+ 'libraries/parsec': GITHUB_HASKELL,
|
|
|
44
|
+ 'libraries/pretty': GITHUB_HASKELL,
|
|
|
45
|
+ 'libraries/primitive': GITHUB_HASKELL,
|
|
|
46
|
+ 'libraries/process': GITHUB_HASKELL,
|
|
|
47
|
+ 'libraries/semaphore-compat': ORIGIN,
|
|
|
48
|
+ 'libraries/stm': GITHUB_HASKELL,
|
|
|
49
|
+ 'libraries/terminfo': GITHUB_HASKELL,
|
|
|
50
|
+ 'libraries/text': GITHUB_HASKELL,
|
|
|
51
|
+ 'libraries/time': GITHUB_HASKELL,
|
|
|
52
|
+ 'libraries/transformers': IGNORE, # darcs mirror
|
|
|
53
|
+ 'libraries/unix': GITHUB_HASKELL,
|
|
|
54
|
+ 'libraries/Win32': GITHUB_HASKELL,
|
|
|
55
|
+ 'nofib': 'https://gitlab.haskell.org/ghc/nofib',
|
|
|
56
|
+ 'utils/hpc': GITHUB_HASKELL,
|
|
|
57
|
+ 'utils/haddock': GITHUB_HASKELL,
|
|
|
58
|
+}
|
|
|
59
|
+
|
|
|
60
|
+all_submods = [
|
|
|
61
|
+ line.split()[1]
|
|
|
62
|
+ for line in subprocess.check_output(['git', 'submodule'], encoding='UTF-8').split('\n')
|
|
|
63
|
+ if len(line.split()) > 0
|
|
|
64
|
+]
|
|
|
65
|
+
|
|
|
66
|
+packages = {
|
|
|
67
|
+ line.split()[0]: line.split()[3]
|
|
|
68
|
+ for line in open('packages').read().split('\n')
|
|
|
69
|
+ if not line.startswith('#')
|
|
|
70
|
+ if len(line.split()) == 4
|
|
|
71
|
+ if line.split()[3] != '-'
|
|
|
72
|
+}
|
|
|
73
|
+
|
|
|
74
|
+def get_remote_url(submod: str, remote: str):
|
|
|
75
|
+ p = subprocess.run(['git', '-C', submod, 'remote', 'get-url', remote],
|
|
|
76
|
+ encoding='UTF-8',
|
|
|
77
|
+ stdout=subprocess.PIPE,
|
|
|
78
|
+ stderr=subprocess.DEVNULL)
|
|
|
79
|
+ if p.returncode == 0:
|
|
|
80
|
+ return p.stdout
|
|
|
81
|
+ else:
|
|
|
82
|
+ return None
|
|
|
83
|
+
|
|
|
84
|
+def add_remote(submod: str, remote: str, url: str):
|
|
|
85
|
+ old_url = get_remote_url(submod, remote)
|
|
|
86
|
+ if old_url is None:
|
|
|
87
|
+ logging.info(f'{submod}: adding remote {remote} = {url}')
|
|
|
88
|
+ subprocess.call(['git', '-C', submod, 'remote', 'add', remote, url])
|
|
|
89
|
+ elif old_url == url:
|
|
|
90
|
+ return
|
|
|
91
|
+ else:
|
|
|
92
|
+ logging.info(f'{submod}: updating remote {remote} = {url}')
|
|
|
93
|
+ subprocess.call(['git', '-C', submod, 'remote', 'set-url', remote, url])
|
|
|
94
|
+
|
|
|
95
|
+ #update_remote(submod, remote)
|
|
|
96
|
+
|
|
|
97
|
+def update_remote(submod: str, remote: str):
|
|
|
98
|
+ subprocess.check_call(['git', '-C', submod, 'remote', 'update', remote])
|
|
|
99
|
+
|
|
|
100
|
+def main():
|
|
|
101
|
+ for submod in all_submods:
|
|
|
102
|
+ print(submod)
|
|
|
103
|
+ upstream = None
|
|
|
104
|
+ if submod in upstreams:
|
|
|
105
|
+ upstream = upstreams[submod]
|
|
|
106
|
+ elif submod in packages:
|
|
|
107
|
+ upstream = packages[submod]
|
|
|
108
|
+
|
|
|
109
|
+ if upstream == ORIGIN:
|
|
|
110
|
+ upstream = subprocess.check_output(['git', '-C', submod, 'remote', 'get-url', 'origin'], encoding='UTF-8').strip()
|
|
|
111
|
+ elif upstream == GITHUB_HASKELL:
|
|
|
112
|
+ upstream = github_haskell(Path(submod).name)
|
|
|
113
|
+ elif upstream == IGNORE:
|
|
|
114
|
+ continue
|
|
|
115
|
+
|
|
|
116
|
+ if upstream is None:
|
|
|
117
|
+ print(f'Unknown upstream for {submod}')
|
|
|
118
|
+ raise ValueError('unknown upstream')
|
|
|
119
|
+ else:
|
|
|
120
|
+ print(f'Upstream of {submod} is {upstream}')
|
|
|
121
|
+ add_remote(submod, 'upstream', upstream)
|
|
|
122
|
+
|
|
|
123
|
+ origin = get_remote_url(submod, 'origin')
|
|
|
124
|
+ m = re.match('https://gitlab.haskell.org/(.*)', origin)
|
|
|
125
|
+ if m is not None:
|
|
|
126
|
+ push = f'git@gitlab.haskell.org:{m.group(1)}'
|
|
|
127
|
+ print(f'origin-push of {submod} is {push}')
|
|
|
128
|
+ add_remote(submod, 'origin-push', push)
|
|
|
129
|
+
|
|
|
130
|
+ name = Path(submod).name
|
|
|
131
|
+ add_remote(submod, 'teo', f'git@github.com:TeofilC/{name}')
|
|
|
132
|
+
|
|
|
133
|
+if __name__ == '__main__':
|
|
|
134
|
+ main()
|
|
|
135
|
+ |