annotate sync.py @ 10:460a2cf8b22b

hg push fails upon success
author drewp@bigasterisk.com
date Fri, 16 Jul 2021 00:30:53 -0700
parents 2c4d383d464c
children 19a699305c29
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
drewp@bigasterisk.com
parents:
diff changeset
1 #!bin/python
drewp@bigasterisk.com
parents:
diff changeset
2
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
3 import os, subprocess, json, logging, traceback, time, re
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
4 from pathlib import Path
1
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
5 from github import Github, GithubException
0
drewp@bigasterisk.com
parents:
diff changeset
6 logging.basicConfig(level=logging.INFO)
drewp@bigasterisk.com
parents:
diff changeset
7 log = logging.getLogger()
drewp@bigasterisk.com
parents:
diff changeset
8
9
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
9
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
10 class Project:
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
11 def __init__(self, projRoot: Path):
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
12 self.config = json.load(open(Path(__file__).parent / "config.json"))
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
13 self.config['SSH_AUTH_SOCK'] = getSshAuthSock()
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
14
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
15 self.gh = Github(self.config['githubToken']).get_user()
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
16 self.projRoot = projRoot
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
17 self.name = projRoot.name
2
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
18
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
19 def darcsTime(self):
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
20 j = os.path.join
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
21 darcsPriv = j(self.config['darcsDir'], self.name, '_darcs')
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
22 for n in ['inventory', 'hashed_inventory']:
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
23 if os.path.exists(j(darcsPriv, n)):
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
24 return os.path.getmtime(j(darcsPriv, n))
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
25 raise ValueError("can't find a darcs time")
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
26
0
drewp@bigasterisk.com
parents:
diff changeset
27 def gitDir(self):
drewp@bigasterisk.com
parents:
diff changeset
28 gitDir = os.path.join(self.config['gitSyncDir'], self.name)
drewp@bigasterisk.com
parents:
diff changeset
29 try:
drewp@bigasterisk.com
parents:
diff changeset
30 os.mkdir(gitDir)
drewp@bigasterisk.com
parents:
diff changeset
31 except OSError: pass
drewp@bigasterisk.com
parents:
diff changeset
32 return gitDir
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
33
0
drewp@bigasterisk.com
parents:
diff changeset
34 def syncToLocalGit(self):
drewp@bigasterisk.com
parents:
diff changeset
35 darcsDir = os.path.join(self.config['darcsDir'], self.name)
drewp@bigasterisk.com
parents:
diff changeset
36 try:
drewp@bigasterisk.com
parents:
diff changeset
37 os.rmdir(os.path.join(darcsDir, 'darcs_testing_for_nfs'))
drewp@bigasterisk.com
parents:
diff changeset
38 except OSError: pass
3
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
39 self.runGitCommand([self.config['darcsToGitCmd'], '--verbose', darcsDir])
0
drewp@bigasterisk.com
parents:
diff changeset
40
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
41 def runGitCommand(self, args, callKw={}):
1
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
42 try:
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
43 subprocess.check_call(args, cwd=self.gitDir(),
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
44 env={'SSH_AUTH_SOCK': self.config['SSH_AUTH_SOCK'],
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
45 'HOME': os.environ['HOME'], # darcs-to-git uses this
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
46 }, **callKw)
1
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
47 except:
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
48 log.error("in %s" % self.gitDir())
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
49 raise
0
drewp@bigasterisk.com
parents:
diff changeset
50
8
cc3321b8adc1 fix silly case
drewp@bigasterisk.com
parents: 7
diff changeset
51 def makeGithubRepo(self):
0
drewp@bigasterisk.com
parents:
diff changeset
52 try:
1
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
53 self.gh.create_repo(self.name)
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
54 except GithubException as e:
3
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
55 assert e.data['errors'][0]['message'].startswith('name already exists'), (e, self.name)
0
drewp@bigasterisk.com
parents:
diff changeset
56 return
drewp@bigasterisk.com
parents:
diff changeset
57 self.runGitCommand(['git', 'remote', 'add', 'origin',
1
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
58 'git@github.com:%s/%s.git' % (self.gh.login,
0
drewp@bigasterisk.com
parents:
diff changeset
59 self.name)])
drewp@bigasterisk.com
parents:
diff changeset
60
8
cc3321b8adc1 fix silly case
drewp@bigasterisk.com
parents: 7
diff changeset
61 def pushToGithub(self):
0
drewp@bigasterisk.com
parents:
diff changeset
62 self.runGitCommand(['git', 'push', 'origin', 'master'])
drewp@bigasterisk.com
parents:
diff changeset
63
8
cc3321b8adc1 fix silly case
drewp@bigasterisk.com
parents: 7
diff changeset
64 def hgToGithub(self):
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
65 subprocess.check_call(['hg', 'bookmark', '-r', 'default', 'main'],
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
66 cwd=self.projRoot)
10
460a2cf8b22b hg push fails upon success
drewp@bigasterisk.com
parents: 9
diff changeset
67 push = subprocess.run(['hg', 'push',
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
68 f'git+ssh://git@github.com/{self.gh.login}/{self.name}'
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
69 ],
10
460a2cf8b22b hg push fails upon success
drewp@bigasterisk.com
parents: 9
diff changeset
70 check=False,
460a2cf8b22b hg push fails upon success
drewp@bigasterisk.com
parents: 9
diff changeset
71 capture_output=True,
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
72 cwd=self.projRoot,
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
73 env={'SSH_AUTH_SOCK': self.config['SSH_AUTH_SOCK']})
10
460a2cf8b22b hg push fails upon success
drewp@bigasterisk.com
parents: 9
diff changeset
74 if not push.stdout.endswith(b'no changes found\n'):
460a2cf8b22b hg push fails upon success
drewp@bigasterisk.com
parents: 9
diff changeset
75 raise ValueError(f'hg push failed with {push.stdout!r}')
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
76
3
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
77 def getSshAuthSock():
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
78 keychain = subprocess.check_output([
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
79 "keychain", "--noask", "--quiet", "--eval", "id_rsa"]).decode('ascii')
3
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
80 m = re.search(r'SSH_AUTH_SOCK=([^; \n]+)', keychain)
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
81 if m is None:
3
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
82 raise ValueError("couldn't find SSH_AUTH_SOCK in output "
4077903a9520 upgrade PyGithub. use keychain for ssh sock path
drewp@bigasterisk.com
parents: 2
diff changeset
83 "from keychain: %r" % keychain)
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
84 return m.group(1)
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
85
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
86 if __name__ == '__main__':
1
1da34eecdfd8 port to PyGithub so repo creates work again
drewp@bigasterisk.com
parents: 0
diff changeset
87
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
88 # to get this token:
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
89 # curl -u drewp https://api.github.com/authorizations -d '{"scopes":["repo"]}'
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
90 # --new:
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
91 # from https://docs.github.com/en/developers/apps/building-oauth-apps/authorizing-oauth-apps#non-web-application-flow -> https://github.com/settings/tokens to make one
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
92
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
93 for proj in os.listdir(config['darcsDir']):
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
94 if not os.path.isdir(os.path.join(config['darcsDir'], proj)):
2
22ccc05756de don't waste time scanning repos that appear to have no recent activity
drewp@bigasterisk.com
parents: 1
diff changeset
95 continue
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
96 try:
9
2c4d383d464c move config stuff into Project
drewp@bigasterisk.com
parents: 8
diff changeset
97 p = Project(proj)
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
98
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
99 if p.darcsTime() < time.time() - 86400*config['tooOldDays']:
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
100 continue
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
101
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
102 log.info("syncing %s", proj)
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
103 p.syncToLocalGit()
8
cc3321b8adc1 fix silly case
drewp@bigasterisk.com
parents: 7
diff changeset
104 p.makeGithubRepo()
cc3321b8adc1 fix silly case
drewp@bigasterisk.com
parents: 7
diff changeset
105 p.pushToGithub()
7
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
106 except Exception as e:
7f479502a8ab wip sync_to_github (from hg)
drewp@bigasterisk.com
parents: 3
diff changeset
107 traceback.print_exc()