Browse Source

first draft of cloning

Signed-off-by: Doug Hellmann <doug@doughellmann.com>
Doug Hellmann 1 year ago
parent
commit
39ed06cf55
2 changed files with 197 additions and 3 deletions
  1. 98
    0
      README.rst
  2. 99
    3
      git_nit/cmd.py

+ 98
- 0
README.rst View File

@@ -7,6 +7,104 @@ A git command for fixing nit-picky changes on gerrit reviews.
7 7
 git-nit is a tool that helps grabbing existing reviews on gerrit and
8 8
 layering on a new patch to fix nits.
9 9
 
10
+Installing
11
+==========
12
+
13
+Install git-nit with pip::
14
+
15
+  $ pip install --user git-nit
16
+
17
+Using
18
+=====
19
+
20
+To clone a patch to a local working directory, pass the URL of the
21
+patch as the first argument.
22
+
23
+::
24
+
25
+  $ git-nit https://review.openstack.org/#/c/564559/
26
+  release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
27
+  Cloning openstack-infra/release-tools into ./release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
28
+  git clone git://git.openstack.org/openstack-infra/release-tools release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
29
+  Cloning into 'release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it'...
30
+  remote: Counting objects: 2320, done.
31
+  remote: Compressing objects: 100% (995/995), done.
32
+  remote: Total 2320 (delta 1491), reused 2109 (delta 1312)
33
+  Receiving objects: 100% (2320/2320), 2.72 MiB | 1.50 MiB/s, done.
34
+  Resolving deltas: 100% (1491/1491), done.
35
+  Checking connectivity... done.
36
+
37
+  Configuring git-review
38
+  git review -s
39
+  Creating a git remote called 'gerrit' that maps to:
40
+     ssh://doug-hellmann@review.openstack.org:29418/openstack-infra/release-tools.git
41
+
42
+  Downloading https://review.openstack.org/#/c/564559/
43
+  git review -d 564559
44
+  Downloading refs/changes/59/564559/2 from gerrit
45
+  Switched to branch "review/doug_hellmann/announce-script-fixes"
46
+
47
+  Updating all remotes
48
+  git remote update
49
+  Fetching origin
50
+  remote: Counting objects: 1501, done.
51
+  remote: Compressing objects: 100% (659/659), done.
52
+  remote: Total 1501 (delta 842), reused 1501 (delta 842)
53
+  Receiving objects: 100% (1501/1501), 218.28 KiB | 0 bytes/s, done.
54
+  Resolving deltas: 100% (842/842), done.
55
+  From git://git.openstack.org/openstack-infra/release-tools
56
+   * [new ref]         refs/notes/review -> refs/notes/review
57
+  Fetching gerrit
58
+
59
+  Patch ready in ./release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
60
+
61
+The URL argument can use the /#/c "fragment" form or it can use the
62
+simplified form ``https://review.openstack.org/564559/``.
63
+
64
+It can also include a patchset number if the goal is to download a
65
+draft older than the most recent patchset.
66
+
67
+::
68
+
69
+  $ git-nit  https://review.openstack.org/#/c/564559/1/
70
+  release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
71
+  Cloning openstack-infra/release-tools into ./release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
72
+  git clone git://git.openstack.org/openstack-infra/release-tools release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
73
+  Cloning into 'release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it'...
74
+  remote: Counting objects: 2320, done.
75
+  remote: Compressing objects: 100% (991/991), done.
76
+  remote: Total 2320 (delta 1494), reused 2111 (delta 1316)
77
+  Receiving objects: 100% (2320/2320), 2.72 MiB | 2.23 MiB/s, done.
78
+  Resolving deltas: 100% (1494/1494), done.
79
+  Checking connectivity... done.
80
+
81
+  Configuring git-review
82
+  git review -s
83
+  Creating a git remote called 'gerrit' that maps to:
84
+     ssh://doug-hellmann@review.openstack.org:29418/openstack-infra/release-tools.git
85
+
86
+  Downloading https://review.openstack.org/#/c/564559/1/
87
+  git review -d 564559,1
88
+  Downloading refs/changes/59/564559/1 from gerrit
89
+  Switched to branch "review/doug_hellmann/announce-script-fixes-patch1"
90
+
91
+  Updating all remotes
92
+  git remote update
93
+  Fetching origin
94
+  remote: Counting objects: 1501, done.
95
+  remote: Compressing objects: 100% (659/659), done.
96
+  remote: Total 1501 (delta 842), reused 1501 (delta 842)
97
+  Receiving objects: 100% (1501/1501), 218.18 KiB | 0 bytes/s, done.
98
+  Resolving deltas: 100% (842/842), done.
99
+  From git://git.openstack.org/openstack-infra/release-tools
100
+   * [new ref]         refs/notes/review -> refs/notes/review
101
+  Fetching gerrit
102
+
103
+  Patch ready in ./release-tools-564559-finish-moving-announce.sh-to-releases-repo-by-deleting-it
104
+
105
+Resources
106
+=========
107
+
10 108
 * Free software: Apache license
11 109
 * Documentation: http://docs.openstack.org/git-nit/latest/
12 110
 * Source: https://git.openstack.org/cgit/openstack/git-nit

+ 99
- 3
git_nit/cmd.py View File

@@ -1,4 +1,4 @@
1
-#!/usr/bin/env python
1
+#!/usr/bin/env python3
2 2
 #
3 3
 # Licensed under the Apache License, Version 2.0 (the "License");
4 4
 # you may not use this file except in compliance with the License.
@@ -15,10 +15,14 @@
15 15
 from __future__ import print_function
16 16
 
17 17
 import argparse
18
+import json
18 19
 import os
20
+import subprocess
21
+import sys
22
+import urllib
19 23
 
20 24
 import pkg_resources
21
-from six.moves import urllib
25
+import requests
22 26
 
23 27
 
24 28
 def get_version():
@@ -27,6 +31,19 @@ def get_version():
27 31
     return provider.version
28 32
 
29 33
 
34
+def decode_json(raw):
35
+    "Trap JSON decoding failures and provide more detailed errors"
36
+
37
+    # Gerrit's REST API prepends a JSON-breaker to avoid XSS vulnerabilities
38
+    if raw.text.startswith(")]}'"):
39
+        trimmed = raw.text[4:]
40
+    else:
41
+        trimmed = raw.text
42
+
43
+    decoded = json.loads(trimmed)
44
+    return decoded
45
+
46
+
30 47
 def parse_review_id(review_id):
31 48
     "Given a review URL or ID return the review number and PS number, if any."
32 49
     parsed = urllib.parse.urlparse(review_id)
@@ -54,6 +71,16 @@ def parse_review_id(review_id):
54 71
     return (review, patchset)
55 72
 
56 73
 
74
+def get_review_data(review_id):
75
+    "Return what gerrit knows about the review."
76
+    parsed = urllib.parse.urlparse(review_id)
77
+    gerrit_url = '{}://{}'.format(parsed.scheme, parsed.netloc)
78
+    review, patchset = parse_review_id(review_id)
79
+    change_url = '{}/changes/{}'.format(gerrit_url, review)
80
+    response = requests.get(change_url)
81
+    return decode_json(response)
82
+
83
+
57 84
 def main():
58 85
     parser = argparse.ArgumentParser()
59 86
     parser.add_argument(
@@ -74,8 +101,77 @@ def main():
74 101
     )
75 102
     args = parser.parse_args()
76 103
 
104
+    data = get_review_data(args.review)
77 105
     review, patchset = parse_review_id(args.review)
78
-    print(review, patchset)
106
+
107
+    repo = data.get('project', '')
108
+    short_repo = repo.rsplit('/', 1)[-1]
109
+    if not repo:
110
+        raise ValueError('Could not determine the repository')
111
+
112
+    subject = data.get('subject', '')
113
+    for old, new in [(' ', '-'), (':', ''), ("'", ''), ('"', '')]:
114
+        subject = subject.replace(old, new)
115
+
116
+    clone_to = '{}-{}-{}'.format(short_repo, review, subject)
117
+    print(clone_to)
118
+
119
+    output_dir = os.path.join(args.project_dir, clone_to)
120
+    if os.path.exists(output_dir):
121
+        sys.exit('{} already exists'.format(output_dir))
122
+
123
+    if not os.path.exists(args.project_dir):
124
+        print('Creating project directory {}'.format(args.project_dir))
125
+        os.makedirs(args.project_dir)
126
+
127
+    git_cmd = [
128
+        'git',
129
+        'clone',
130
+        'git://git.openstack.org/{}'.format(repo),
131
+        clone_to,
132
+    ]
133
+    if args.project_dir != '.':
134
+        cwd = args.project_dir
135
+    else:
136
+        cwd = None
137
+    print('Cloning {} into {}'.format(repo, output_dir))
138
+    print(' '.join(git_cmd))
139
+    subprocess.run(git_cmd, cwd=cwd, check=True)
140
+
141
+    git_cmd = [
142
+        'git',
143
+        'review',
144
+        '-s',
145
+    ]
146
+    print('\nConfiguring git-review')
147
+    print(' '.join(git_cmd))
148
+    subprocess.run(git_cmd, cwd=output_dir, check=True)
149
+
150
+    git_cmd = [
151
+        'git',
152
+        'review',
153
+        '-d',
154
+    ]
155
+    if patchset is not None:
156
+        target = '{},{}'.format(review, patchset)
157
+    else:
158
+        target = review
159
+    git_cmd.append(target)
160
+    print('\nDownloading {}'.format(args.review))
161
+    print(' '.join(git_cmd))
162
+    subprocess.run(git_cmd, cwd=output_dir, check=True)
163
+
164
+    git_cmd = [
165
+        'git',
166
+        'remote',
167
+        'update',
168
+    ]
169
+    print('\nUpdating all remotes')
170
+    print(' '.join(git_cmd))
171
+    subprocess.run(git_cmd, cwd=output_dir, check=True)
172
+
173
+    print('\nPatch ready in {}'.format(output_dir))
174
+
79 175
 
80 176
 if __name__ == '__main__':
81 177
     main()

Loading…
Cancel
Save