31
31
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
32
# POSSIBILITY OF SUCH DAMAGE.
33
33
34
- try :
35
- from urllib .request import urlopen , Request
36
- from urllib .error import URLError
37
- from urllib .parse import quote as urlquote
38
- except ImportError :
39
- from urllib2 import urlopen , Request
40
- from urllib2 import URLError
41
- from urllib2 .parse import quote as urlquote
42
-
43
34
import json
44
35
import os
45
36
import re
37
+ from urllib .request import urlopen , Request
38
+ from urllib .error import URLError
39
+ from urllib .parse import quote as urlquote
46
40
47
41
from catkin_pkg .package import parse_package_string
48
42
49
43
from rosdistro .source_repository_cache import SourceRepositoryCache
50
44
from rosdistro import logger
51
45
46
+ GITLAB_PRIVATE_TOKEN = os .getenv ('GITLAB_PRIVATE_TOKEN' , None )
47
+
48
+ def _gitlab_urlopen (url ):
49
+ req = Request (url )
50
+ if GITLAB_PRIVATE_TOKEN :
51
+ req .add_header ('Private-Token' , GITLAB_PRIVATE_TOKEN )
52
+ logger .warn ('Performing GitLab API query "%s"' % (url ,))
53
+ return urlopen (req )
54
+
55
+
56
+ def _gitlab_api_query (server , path , resource , attrs ):
57
+ url = 'https://%s/api/v4/projects/%s/%s' % (server , urlquote (path , safe = '' ), resource )
58
+ if attrs :
59
+ url += '?' + '&' .join (k + '=' + urlquote (str (v ), safe = '' ) for k , v in attrs .items ())
60
+ return _gitlab_urlopen (url )
52
61
53
- def _gitlab_paged_api_query (path , resource , attrs ):
54
- _attrs = {'per_page' : 50 }
55
- _attrs .update (attrs )
56
- _attrs .pop ('pagination' , None )
57
- _attrs .pop ('page' , None )
58
62
59
- url = 'https://gitlab.com/api/v4/projects/%s/%s?pagination=keyset' % (urlquote (path , safe = '' ), resource )
60
- for k , v in _attrs .items ():
61
- url += '&%s=%s' % (k , urlquote (str (v ), safe = '' ))
63
+ def _gitlab_paged_api_query (server , path , resource , attrs ):
64
+ _attrs = {
65
+ 'per_page' : 50 ,
66
+ ** attrs ,
67
+ 'pagination' : 'keyset' ,
68
+ 'page' : '1' ,
69
+ }
70
+
71
+ url = 'https://%s/api/v4/projects/%s/%s' % (server , urlquote (path , safe = '' ), resource )
72
+ if _attrs :
73
+ url += '?' + '&' .join (k + '=' + urlquote (str (v ), safe = '' ) for k , v in _attrs .items ())
62
74
63
75
while True :
64
- with urlopen (url ) as res :
76
+ with _gitlab_urlopen (url ) as res :
65
77
for result in json .loads (res .read ().decode ('utf-8' )):
66
78
yield result
67
79
@@ -78,37 +90,43 @@ def _gitlab_paged_api_query(path, resource, attrs):
78
90
def gitlab_manifest_provider (_dist_name , repo , pkg_name ):
79
91
assert repo .version
80
92
server , path = repo .get_url_parts ()
81
- if not server .endswith ('gitlab.com ' ):
93
+ if not server .startswith ('gitlab.' ):
82
94
logger .debug ('Skip non-gitlab url "%s"' % repo .url )
83
95
raise RuntimeError ('can not handle non gitlab urls' )
84
96
85
- release_tag = repo .get_release_tag (pkg_name )
86
-
87
- if not repo .has_remote_tag (release_tag ):
88
- raise RuntimeError ('specified tag "%s" is not a git tag' % release_tag )
89
-
90
- url = 'https://gitlab.com/%s/-/raw/%s/package.xml' % (path , release_tag )
97
+ resource = 'repository/files/package.xml/raw'
98
+ attrs = {
99
+ 'ref' : repo .get_release_tag (pkg_name ),
100
+ }
91
101
try :
92
- logger . debug ( 'Load package.xml file from url "%s"' % url )
93
- return urlopen ( url ) .read ().decode ('utf-8' )
102
+ with _gitlab_api_query ( server , path , resource , attrs ) as res :
103
+ return res .read ().decode ('utf-8' )
94
104
except URLError as e :
95
- logger .debug ('- failed (%s), trying "%s"' % (e , url ))
96
- raise RuntimeError ()
105
+ logger .debug ('- failed (%s), trying "%s"' % (e , e . filename ))
106
+ raise
97
107
98
108
99
109
def gitlab_source_manifest_provider (repo ):
100
110
assert repo .version
101
111
server , path = repo .get_url_parts ()
102
- if not server .endswith ('gitlab.com ' ):
112
+ if not server .startswith ('gitlab.' ):
103
113
logger .debug ('Skip non-gitlab url "%s"' % repo .url )
104
114
raise RuntimeError ('can not handle non gitlab urls' )
105
115
106
- # Resolve the version ref to a sha
107
- sha = next (_gitlab_paged_api_query (path , 'repository/commits' , {'per_page' : 1 , 'ref_name' : repo .version }))['id' ]
116
+ # Resolve the version ref to a sha since we need to make multiple queries
117
+ attrs = {
118
+ 'per_page' : 1 ,
119
+ 'ref_name' : repo .version ,
120
+ }
121
+ sha = next (_gitlab_paged_api_query (server , path , 'repository/commits' , attrs ))['id' ]
108
122
109
123
# Look for package.xml files in the tree
124
+ attrs = {
125
+ 'recursive' : 'true' ,
126
+ 'ref' : sha ,
127
+ }
110
128
package_xml_paths = set ()
111
- for obj in _gitlab_paged_api_query (path , 'repository/tree' , { 'recursive' : 'true' , 'ref' : sha } ):
129
+ for obj in _gitlab_paged_api_query (server , path , 'repository/tree' , attrs ):
112
130
if obj ['path' ].split ('/' )[- 1 ] == 'package.xml' :
113
131
package_xml_paths .add (os .path .dirname (obj ['path' ]))
114
132
@@ -127,10 +145,11 @@ def package_xml_in_parent(path):
127
145
128
146
cache = SourceRepositoryCache .from_ref (sha )
129
147
for package_xml_path in package_xml_paths :
130
- url = 'https://gitlab.com/%s/-/raw/%s/%s' % \
131
- (path , sha , package_xml_path + '/package.xml' if package_xml_path else 'package.xml' )
132
- logger .debug ('- load package.xml from %s' % url )
133
- package_xml = urlopen (url ).read ().decode ('utf-8' )
148
+ resource_path = urlquote (
149
+ package_xml_path + '/package.xml' if package_xml_path else 'package.xml' , safe = '' )
150
+ resource = 'repository/files/' + resource_path + '/raw'
151
+ with _gitlab_api_query (server , path , resource , {'ref' : sha }) as res :
152
+ package_xml = res .read ().decode ('utf-8' )
134
153
name = parse_package_string (package_xml ).name
135
154
cache .add (name , package_xml_path , package_xml )
136
155
0 commit comments