oc-cdtapi 3.9.2__py3-none-any.whl → 3.9.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
oc_cdtapi/JenkinsAPI.py CHANGED
@@ -1,11 +1,12 @@
1
1
  # requires python-requests rpm package
2
+ from enum import Enum
2
3
  import requests
3
4
  from .API import HttpAPI, HttpAPIError
4
5
  from string import Template
5
6
  import json
6
7
  from collections import namedtuple, OrderedDict
7
8
  import re
8
- import xml.etree.ElementTree as ET;
9
+ import xml.etree.ElementTree as ET
9
10
  import posixpath
10
11
  import sys
11
12
 
@@ -42,10 +43,11 @@ class Jenkins(HttpAPI):
42
43
  _env_prefix = 'JENKINS'
43
44
 
44
45
  def re(self, req):
45
- if req and req[0] == '!':
46
- req = req[1:]
47
- return posixpath.join( self.root, req );
48
- return posixpath.join( self.root, req, 'api', 'json' );
46
+ if req and req.startswith('!'):
47
+ req = req.lstrip('!')
48
+ return posixpath.join(self.root, req)
49
+
50
+ return posixpath.join(self.root, req, 'api', 'json')
49
51
 
50
52
  def post(self, req, *vargs, **kvargs):
51
53
  # We need all post requests to be processed in a different way in re(),
@@ -57,127 +59,133 @@ class Jenkins(HttpAPI):
57
59
  jobs = self.get('', params={'tree': 'jobs[name]'})
58
60
  return filter(lambda x: (not prefix or x.startswith(prefix)) and (not suffix or x.endswith(suffix)),
59
61
  map(lambda x: x['name'], jobs.json().get('jobs', [])))
62
+
60
63
  def get_node(self, node):
61
64
  """Gets config.xml for specific slave"""
62
- config = self.get( posixpath.join( 'computer', node, 'config.xml') );
65
+ config = self.get(posixpath.join('computer', node, 'config.xml'))
63
66
  return config.text
64
67
 
65
68
  def put_node(self, node, config):
66
69
  """Saves config.xml for a node (or creates new node)"""
67
- request = posixpath.join( 'computer', node, 'config.xml' );
70
+ request = posixpath.join('computer', node, 'config.xml')
68
71
  params = None
69
- headers = {'content-type' : 'application/xml'}
72
+ headers = {'content-type': 'application/xml'}
70
73
 
71
74
  try:
72
75
  self.get_node(node)
73
76
  except JenkinsError as e:
74
- if e.code == 404: request = posixpath.join( 'computer', 'doCreateItem' );
77
+ if e.code == 404:
78
+ request = posixpath.join('computer', 'doCreateItem')
75
79
  params = {'name': node}
76
80
 
77
- if self.readonly: return None
81
+ if self.readonly:
82
+ return None
83
+
78
84
  put = self.post(request, data=config, params=params, headers=headers)
79
85
  return put
80
86
 
81
- def delete_node( self, node ):
87
+ def delete_node(self, node):
82
88
  """Deletes node from CI"""
83
- if self.readonly: return None
84
- return self.post( posixpath.join( 'computer', node, 'doDelete' ) );
89
+ if self.readonly:
90
+ return None
91
+ return self.post(posixpath.join('computer', node, 'doDelete'))
85
92
 
86
- def get_node_label_from_config( self, config ):
93
+ def get_node_label_from_config(self, config):
87
94
  """
88
95
  Get the exact XML tag value with XPATH: label
89
96
  :param self: self reference
90
97
  :param config: xml string with a configuration of node
91
98
  :return: <label> tag text
92
99
  """
93
- obj_xml = ET.fromstring( config );
94
- xml_tag = obj_xml.find( 'label' );
100
+ obj_xml = ET.fromstring(config)
101
+ xml_tag = obj_xml.find('label')
95
102
 
96
- if ( xml_tag is None ) or ( xml_tag.text is None ) or ( len( xml_tag.text.strip() ) == 0 ):
97
- return "";
103
+ if (xml_tag is None) or (xml_tag.text is None) or (len(xml_tag.text.strip()) == 0):
104
+ return ""
98
105
 
99
- return xml_tag.text;
106
+ return xml_tag.text
100
107
 
101
108
  def get_node_label(self, node, config=None):
102
- if not config: config = self.get_node(node)
103
- return self.get_node_label_from_config( config ).split(' ')
109
+ if not config:
110
+ config = self.get_node(node)
111
+ return self.get_node_label_from_config(config).split(' ')
104
112
 
105
- def set_node_label_in_config( self, config, label ):
113
+ def set_node_label_in_config(self, config, label):
106
114
  """
107
115
  set <label> tag in XML config
108
116
  :param self: self reference
109
117
  :param config: string with XML node configuration
110
118
  :return: string with edited 'config' with <lable> tag content set to 'label'
111
119
  """
112
- obj_xml = ET.fromstring( config );
113
- xml_tag = obj_xml.find( 'label' );
120
+ obj_xml = ET.fromstring(config)
121
+ xml_tag = obj_xml.find('label')
114
122
 
115
- if ( xml_tag is None ):
116
- xml_tag = ET.SubElement( obj_xml, 'label' );
123
+ if (xml_tag is None):
124
+ xml_tag = ET.SubElement(obj_xml, 'label')
117
125
 
118
- xml_tag.text = label;
126
+ xml_tag.text = label
119
127
 
120
- return ET.tostring( obj_xml, encoding='utf8' );
128
+ return ET.tostring(obj_xml, encoding='utf8')
121
129
 
122
130
  def set_node_label(self, node, label):
123
131
  config = self.get_node(node)
124
- config = self.set_node_label_in_config( config, ' '.join(label))
132
+ config = self.set_node_label_in_config(config, ' '.join(label))
125
133
  return self.put_node(node, config)
126
134
 
127
135
  def enable_node(self, job):
128
- if self.readonly: return None
129
- return self.post( posixpath.join( 'computer', job, 'enable') );
136
+ if self.readonly:
137
+ return None
138
+ return self.post(posixpath.join('computer', job, 'enable'))
130
139
 
131
140
  def disable_node(self, job):
132
- if self.readonly: return None
133
- return self.post( posixpath.join( 'computer', job, 'disable') )
141
+ if self.readonly:
142
+ return None
143
+ return self.post(posixpath.join('computer', job, 'disable'))
134
144
 
135
145
  def is_node_idle(self, node):
136
146
  """Retrieve 'idle' attribute of a node via newer JSON API (may require Jenkins 2.x)."""
137
- return json.loads(
138
- self.get("computer/{}/api/json".format(node)).content
139
- )['idle']
147
+ return self.get(posixpath.join("computer", node, "api", "json")).json().get('idle')
140
148
 
141
- def list_nodes( self ):
149
+ def list_nodes(self):
142
150
  """
143
151
  List all active nodes (except master one)
144
152
  :return: List of strings with node names, possible empty
145
153
  """
146
- raw_data = self.get( "computer", params = { "tree" : "computer[displayName]" } )
154
+ raw_data = self.get("computer", params={"tree": "computer[displayName]"})
147
155
  str_data = raw_data.text
148
156
 
149
157
  # return map( lambda x: x[ "displayName" ], json.loads( self.get( "computer", params = { "tree" : "computer[displayName]" } ).text )[ "computer" ] );
150
- return [x[ "displayName" ] for x in json.loads( str_data )[ "computer" ]];
151
-
158
+ return [x["displayName"] for x in json.loads(str_data)["computer"]]
152
159
 
153
- def job_xml_enable( self, config ):
160
+ def job_xml_enable(self, config):
154
161
  """
155
162
  Enables jenkins job by modifying XML tag (XPATH=) in the configuration
156
163
  :param self: self reference
157
164
  :param config: xml string from a config
158
165
  :return: xml string with <disabled> tag value modified to 'true'
159
166
  """
160
- obj_xml = ET.fromstring( config );
161
- xml_tag = obj_xml.find( 'disabled' );
167
+ obj_xml = ET.fromstring(config)
168
+ xml_tag = obj_xml.find('disabled')
162
169
 
163
170
  if xml_tag is None:
164
- return config;
171
+ return config
165
172
 
166
- xml_tag.text = "false";
173
+ xml_tag.text = "false"
167
174
 
168
- return ET.tostring( obj_xml, encoding='utf8' );
175
+ return ET.tostring(obj_xml, encoding='utf8')
169
176
 
170
177
  def copy_job(self, config, j_name, parameters={}, enabled=True, use_template=False):
171
178
  """Create or update job by template"""
172
179
 
173
- if config[0] != '<': config = self.get_job(config)
180
+ if config[0] != '<':
181
+ config = self.get_job(config)
174
182
  parameters['name'] = j_name
175
183
  if enabled:
176
- config = self.job_xml_enable( config );
184
+ config = self.job_xml_enable(config)
177
185
 
178
- cfg_type = str (type (config) )
186
+ cfg_type = str(type(config))
179
187
  if cfg_type.find('byte') != -1:
180
- config = str (config, 'UTF-8')
188
+ config = str(config, 'UTF-8')
181
189
 
182
190
  if use_template:
183
191
  config = Template(config).safe_substitute(parameters)
@@ -190,142 +198,149 @@ class Jenkins(HttpAPI):
190
198
 
191
199
  def get_job(self, job):
192
200
  """Gets config.xml for a job"""
193
- config = self.get( posixpath.join( 'job', job, 'config.xml') );
201
+ config = self.get(posixpath.join('job', job, 'config.xml'))
194
202
  return config.text
195
203
 
196
204
  def put_job(self, job, config):
197
205
  """Saves config.xml for a job (or creates new job)"""
198
- request = posixpath.join( 'job', job, 'config.xml' )
206
+ request = posixpath.join('job', job, 'config.xml')
199
207
  params = None
200
- headers = {'content-type' : 'application/xml'}
208
+ headers = {'content-type': 'application/xml'}
201
209
  try:
202
210
  self.get_job(job)
203
211
  except JenkinsError as e:
204
- if e.code == 404: request = 'createItem'
212
+ if e.code == 404:
213
+ request = 'createItem'
205
214
  params = {'name': job}
206
215
 
207
- if self.readonly: return None
216
+ if self.readonly:
217
+ return None
208
218
  put = self.post(request, data=config, params=params, headers=headers)
209
219
  return put
210
220
 
211
221
  def enable_job(self, job):
212
- if self.readonly: return None
213
- return self.post( posixpath.join( 'job', job, 'enable' ) );
222
+ if self.readonly:
223
+ return None
224
+ return self.post(posixpath.join('job', job, 'enable'))
214
225
 
215
226
  def disable_job(self, job):
216
- if self.readonly: return None
217
- return self.post( posixpath.join ( 'job', job, 'disable' ) );
227
+ if self.readonly:
228
+ return None
229
+ return self.post(posixpath.join('job', job, 'disable'))
218
230
 
219
231
  def delete_job(self, job):
220
- if self.readonly: return None
221
- return self.post( posixpath.join( 'job', job, 'doDelete' ) );
232
+ if self.readonly:
233
+ return None
234
+ return self.post(posixpath.join('job', job, 'doDelete'))
222
235
 
223
236
  def run_job(self, job, params=None):
224
- if self.readonly: return None
237
+ if self.readonly:
238
+ return None
225
239
  if params == None:
226
- response=self.post( posixpath.join( 'job', job, 'build') );
240
+ response = self.post(posixpath.join('job', job, 'build'))
227
241
  else:
228
- response=self.post( posixpath.join( 'job', job, 'buildWithParameters' ), data=params)
242
+ response = self.post(posixpath.join('job', job, 'buildWithParameters'), data=params)
229
243
 
230
- queue_item=QueueItem.from_jenkins_response(response, self)
244
+ queue_item = QueueItem.from_jenkins_response(response, self)
231
245
  return queue_item
232
246
 
233
- def list_builds( self, node = None ):
247
+ def list_builds(self, node=None):
234
248
  """
235
249
  Get list of Builds which are currently build on the node given
236
250
  :param node: list only jobs building on the node specified
237
251
  :type node: string
238
252
  :return: dictionary with node_names as a key and list of jobs dictionaries building on the node as { "job_name": ... , "build_number" : ... }, list may be None
239
253
  """
240
- str_request = "";
241
- dict_parms = { "tree" : "jobs[name,lastBuild[building,fullDisplayName,number,url,builtOn]]" };
254
+ str_request = ""
255
+ dict_parms = {"tree": "jobs[name,lastBuild[building,fullDisplayName,number,url,builtOn]]"}
242
256
 
243
257
  if node is not None:
244
- str_request = posixpath.join( "computer", node );
245
- dict_parms[ "tree" ] = "executors[idle,currentExecutable[idle,building,builtOn,number,fullDisplayName,url]]";
258
+ str_request = posixpath.join("computer", node)
259
+ dict_parms["tree"] = "executors[idle,currentExecutable[idle,building,builtOn,number,fullDisplayName,url]]"
246
260
 
247
- response = self.get( str_request, params = dict_parms );
248
- dict_resp = json.loads( response.text );
261
+ response = self.get(str_request, params=dict_parms)
262
+ dict_resp = json.loads(response.text)
249
263
 
250
264
  if node is not None:
251
- if len( dict_resp[ "executors" ] ) == 0:
252
- return { node: list() };
265
+ if len(dict_resp["executors"]) == 0:
266
+ return {node: list()}
253
267
 
254
- ls_jobs = map( lambda x: { "name" : None, "lastBuild" : ( None if x[ "idle" ] else x[ "currentExecutable" ] ) }, dict_resp[ "executors" ] );
255
-
256
- else :
257
- ls_jobs = dict_resp[ "jobs" ];
268
+ ls_jobs = map(lambda x: {"name": None, "lastBuild": (
269
+ None if x["idle"] else x["currentExecutable"])}, dict_resp["executors"])
258
270
 
271
+ else:
272
+ ls_jobs = dict_resp["jobs"]
259
273
 
260
- dict_result = dict();
274
+ dict_result = dict()
261
275
 
262
276
  for dict_job in ls_jobs:
263
- if "lastBuild" not in dict_job or dict_job[ "lastBuild" ] is None or not dict_job[ "lastBuild" ][ "building" ]:
264
- continue; # inactive build, out of interes
277
+ if "lastBuild" not in dict_job or dict_job["lastBuild"] is None or not dict_job["lastBuild"]["building"]:
278
+ continue # inactive build, out of interes
265
279
 
266
- str_job_name = dict_job[ "name" ];
280
+ str_job_name = dict_job["name"]
267
281
 
268
282
  if not str_job_name:
269
- str_job_name = dict_job[ "lastBuild" ][ "url" ].split( posixpath.sep + "job" + posixpath.sep, 1 )[1].split( posixpath.sep, 1 )[0];
283
+ str_job_name = dict_job["lastBuild"]["url"].split(
284
+ posixpath.sep + "job" + posixpath.sep, 1)[1].split(posixpath.sep, 1)[0]
270
285
 
271
- str_builder_node = dict_job[ "lastBuild" ][ "builtOn" ];
286
+ str_builder_node = dict_job["lastBuild"]["builtOn"]
272
287
 
273
288
  if str_builder_node not in dict_result:
274
- dict_result[ str_builder_node ] = list();
289
+ dict_result[str_builder_node] = list()
275
290
 
276
- dict_result[ str_builder_node ].append( { "job_name" : str_job_name, "build_nubmer" : dict_job[ "lastBuild" ][ "number" ] } );
291
+ dict_result[str_builder_node].append(
292
+ {"job_name": str_job_name, "build_nubmer": dict_job["lastBuild"]["number"]})
277
293
 
278
- return dict_result;
294
+ return dict_result
279
295
 
280
- def list_queue( self ):
296
+ def list_queue(self):
281
297
  """
282
298
  Get queue items, perhaps empty if no jobs queued
283
299
  :return: list of QueueItems, possible empty
284
300
  """
285
- ls_result = list();
286
- obj_resp = self.get( "queue" );
287
- dict_resp = json.loads( obj_resp.text or {} );
301
+ ls_result = list()
302
+ obj_resp = self.get("queue")
303
+ dict_resp = json.loads(obj_resp.text or {})
288
304
 
289
305
  if not 'items' in dict_resp:
290
- return ls_result;
306
+ return ls_result
291
307
 
292
- for dict_task in dict_resp[ 'items' ]:
308
+ for dict_task in dict_resp['items']:
293
309
  if not 'task' in dict_task:
294
- continue;
310
+ continue
295
311
 
296
- if not 'name' in dict_task[ 'task' ]:
297
- continue;
312
+ if not 'name' in dict_task['task']:
313
+ continue
298
314
 
299
315
  if not 'id' in dict_task:
300
- continue;
316
+ continue
301
317
 
302
- ls_result.append( QueueItem( dict_task[ 'id' ], self, dict_task ) );
303
-
304
- return ls_result;
318
+ ls_result.append(QueueItem(dict_task['id'], self, dict_task))
319
+
320
+ return ls_result
305
321
 
306
- def unqueue_item( self, int_id ):
322
+ def unqueue_item(self, int_id):
307
323
  """
308
324
  remove item with ID given from queue
309
325
  :param int_id: id
310
326
  :type int_id: integer
311
327
  """
312
- if int_id is None or not isinstance( int_id, int ):
313
- raise TypeError( "Wrong type of arguments: int_id is not integer" );
328
+ if int_id is None or not isinstance(int_id, int):
329
+ raise TypeError("Wrong type of arguments: int_id is not integer")
314
330
 
315
331
  try:
316
- self.post( posixpath.join( 'queue','cancelItem'), data = {}, params = { "id": int_id } );
332
+ self.post(posixpath.join('queue', 'cancelItem'), data={}, params={"id": int_id})
317
333
  except:
318
- pass; # since jenkins returns 404 code for this type of operation and it is normal
334
+ pass # since jenkins returns 404 code for this type of operation and it is normal
319
335
 
320
336
 
321
- from enum import Enum
322
337
  class BuildStatus(Enum):
323
- BUILDING=0
324
- SUCCESS=1
325
- FAILURE=2
326
- ABORTED=3
327
- UNSTABLE=4
328
- NOT_BUILD=5
338
+ BUILDING = 0
339
+ SUCCESS = 1
340
+ FAILURE = 2
341
+ ABORTED = 3
342
+ UNSTABLE = 4
343
+ NOT_BUILD = 5
329
344
 
330
345
 
331
346
  class Build(object):
@@ -334,31 +349,31 @@ class Build(object):
334
349
  """
335
350
 
336
351
  def __init__(self, job_name, build_number, jenkins_client):
337
- self.job_name=job_name
338
- self.build_number=build_number
339
- self.jenkins_client=jenkins_client
340
- self._build_status=BuildStatus.BUILDING
352
+ self.job_name = job_name
353
+ self.build_number = build_number
354
+ self.jenkins_client = jenkins_client
355
+ self._build_status = BuildStatus.BUILDING
341
356
 
342
357
  def get_status(self):
343
358
  self._update_build_status()
344
359
  return self._build_status
345
360
 
346
361
  def _update_build_status(self):
347
- if self._build_status!=BuildStatus.BUILDING:
362
+ if self._build_status != BuildStatus.BUILDING:
348
363
  return self._build_status
349
- build_path = posixpath.join( "job", self.job_name, str( self.build_number ), 'api', 'json' )
350
- response=self.jenkins_client.get(build_path)
351
- if response.status_code==404:
364
+ build_path = posixpath.join("job", self.job_name, str(self.build_number), 'api', 'json')
365
+ response = self.jenkins_client.get(build_path)
366
+ if response.status_code == 404:
352
367
  raise JenkinsError("No build exist at %s" % build_path)
353
- parsed_response=json.loads(response.text or "{}")
354
- status_value=parsed_response["result"]
368
+ parsed_response = json.loads(response.text or "{}")
369
+ status_value = parsed_response["result"]
355
370
  if not status_value:
356
- self._build_status=BuildStatus.BUILDING
371
+ self._build_status = BuildStatus.BUILDING
357
372
  else:
358
373
  if sys.version_info.major == 2:
359
374
  self._build_status = getattr(BuildStatus, status_value)
360
375
  else:
361
- self._build_status=BuildStatus[status_value]
376
+ self._build_status = BuildStatus[status_value]
362
377
 
363
378
 
364
379
  class QueueItem(object):
@@ -369,55 +384,55 @@ class QueueItem(object):
369
384
 
370
385
  @classmethod
371
386
  def from_jenkins_response(cls, response, jenkins_client):
372
- location_url=response.headers["Location"]
373
- search_result=re.search( r'' + posixpath.join( "queue", "item", "(?P<queue_id>\d+)" ), location_url)
374
- queue_id=int(search_result.group("queue_id"))
387
+ location_url = response.headers["Location"]
388
+ search_result = re.search(r'' + posixpath.join("queue", "item", "(?P<queue_id>\d+)"), location_url)
389
+ queue_id = int(search_result.group("queue_id"))
375
390
  return QueueItem(queue_id, jenkins_client)
376
-
377
- def __init__(self, queue_id, jenkins_client, dict_details = None):
391
+
392
+ def __init__(self, queue_id, jenkins_client, dict_details=None):
378
393
  """
379
394
  :param resource: id in build queue (assigned at build launch request)
380
395
  :param required: jenkins.Jenkins instance
381
396
  """
382
- self.queue_id=queue_id
383
- self.jenkins_client=jenkins_client
384
- self._build=None
385
- self._task=None;
397
+ self.queue_id = queue_id
398
+ self.jenkins_client = jenkins_client
399
+ self._build = None
400
+ self._task = None
386
401
 
387
402
  if not dict_details:
388
- return;
403
+ return
389
404
 
390
405
  if "task" in dict_details:
391
- self._task = dict_details[ "task" ];
406
+ self._task = dict_details["task"]
392
407
 
393
408
  @property
394
- def task( self ):
409
+ def task(self):
395
410
  """
396
411
  :return: dictionary with task parameters - job name, url, color - as it returned by Jenkins
397
412
  """
398
413
  if not self._task:
399
- self._try_update_queue_status();
400
- return self._task;
414
+ self._try_update_queue_status()
415
+ return self._task
401
416
 
402
417
  @property
403
- def job_name( self ):
418
+ def job_name(self):
404
419
  """
405
420
  :return: job name of the queue item
406
421
  """
407
422
 
408
423
  if not self._task:
409
- self._try_update_queue_status();
424
+ self._try_update_queue_status()
410
425
 
411
426
  if not self._task:
412
- return None;
427
+ return None
413
428
 
414
429
  if "url" not in self._task:
415
- self._try_update_queue_status();
430
+ self._try_update_queue_status()
416
431
 
417
432
  if "url" not in self._task:
418
- return None;
433
+ return None
419
434
 
420
- return self._task[ "url" ].split( posixpath.sep + "job" + posixpath.sep, 1 )[1].split( posixpath.sep, 1 )[0];
435
+ return self._task["url"].split(posixpath.sep + "job" + posixpath.sep, 1).pop().split(posixpath.sep, 1).pop(0)
421
436
 
422
437
  def is_running(self):
423
438
  self._try_update_queue_status()
@@ -425,33 +440,29 @@ class QueueItem(object):
425
440
 
426
441
  def get_build(self):
427
442
  self._try_update_queue_status()
443
+
428
444
  if self._build:
429
445
  return self._build
430
- else:
431
- raise BuildStatusException("Build is not started yet")
446
+
447
+ raise BuildStatusException("Build is not started yet")
432
448
 
433
449
  def _try_update_queue_status(self):
434
450
  if self._build:
435
451
  return
436
- item_path= posixpath.join( "queue", "item", str( self.queue_id ), "api", "json" );
437
- response=self.jenkins_client.get(item_path)
438
- if response.status_code==404:
452
+ item_path = posixpath.join("queue", "item", str(self.queue_id), "api", "json")
453
+ response = self.jenkins_client.get(item_path)
454
+ if response.status_code == 404:
439
455
  raise JenkinsError("No queue item exist at %s" % item_path)
440
- parsed_response=json.loads(response.text or "{}")
456
+ parsed_response = json.loads(response.text or "{}")
441
457
  if "executable" in parsed_response:
442
- self._build=Build(parsed_response["task"]["name"],
443
- parsed_response["executable"]["number"],
444
- self.jenkins_client)
458
+ self._build = Build(parsed_response["task"]["name"],
459
+ parsed_response["executable"]["number"],
460
+ self.jenkins_client)
445
461
 
446
462
  if not self._task and "task" in parsed_response:
447
- self._task = parsed_response[ "task" ];
448
-
463
+ self._task = parsed_response["task"]
464
+
449
465
 
450
466
  class BuildStatusException(Exception):
451
467
  pass
452
468
 
453
-
454
- if __name__ == "__main__":
455
- import doctest
456
-
457
- doctest.testmod()
oc_cdtapi/NexusAPI.py CHANGED
@@ -246,8 +246,7 @@ class NexusAPI(HttpAPI):
246
246
  :param repo: repo
247
247
  :type repo: str
248
248
  """
249
- # here is nice place to use 'urllib.urljoin'
250
- # but implemented ugly via 'posixpath' to get rid of extra dependencies
249
+ #urllib.urlparse.urljoin is not suitable for us since it joins only host part + relative part
251
250
  if not gav:
252
251
  raise ValueError("GAV is mandatory")
253
252
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oc-cdtapi
3
- Version: 3.9.2
3
+ Version: 3.9.5
4
4
  Summary: Custom Development python API libraries
5
5
  License: Apache2.0
6
6
  Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*
@@ -0,0 +1,15 @@
1
+ oc_cdtapi/API.py,sha256=hpdnzyirYT_wISeznRmoqr-umYRT6uqKVwhmCXyj8Nk,12398
2
+ oc_cdtapi/DevPIAPI.py,sha256=Nn63Ob0kA5XXuRZ3OIWG2rcnSsztKq9yPI6Lu2zX3Gk,1836
3
+ oc_cdtapi/DmsAPI.py,sha256=j2Bx4Sryc4R1knyNjQmZshVuCePeD2q4W-fxv7zOMFc,9481
4
+ oc_cdtapi/DmsGetverAPI.py,sha256=NIhWq2MDWaIBFLYJqkPCV9jZqM1HSZum6gIHquGHdQg,16085
5
+ oc_cdtapi/ForemanAPI.py,sha256=w6MN86vJxYtHIZQ5gCehghV0D-EisGpCcBXEvfuUk3M,39986
6
+ oc_cdtapi/JenkinsAPI.py,sha256=lZ8pe3a4eb_6h53JE7QLuzOSlu7Sqatc9PQwWhio9Vg,15748
7
+ oc_cdtapi/NexusAPI.py,sha256=uU12GtHvKlWorFaPAnFcQ5AGEc94MZ5SdmfM2Pw3F7A,26122
8
+ oc_cdtapi/TestServer.py,sha256=HV97UWg2IK4gOYAp9yaMdwFUWsw9v66MxyZdI3qQctA,2715
9
+ oc_cdtapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ oc_cdtapi-3.9.5.data/scripts/nexus.py,sha256=4teqZ_KtCSrwHDJVgA7lkreteod4Xt5XJFZNbwb7E6E,6858
11
+ oc_cdtapi-3.9.5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
12
+ oc_cdtapi-3.9.5.dist-info/METADATA,sha256=S64Fcjm0kP3W3bg7C5ENxYYtLdkQDKuyi0RVXqrswx8,276
13
+ oc_cdtapi-3.9.5.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
14
+ oc_cdtapi-3.9.5.dist-info/top_level.txt,sha256=d4-5-D-0CSeSXYuLCP7-nIFCpjkfmJr-Y_muzds8iVU,10
15
+ oc_cdtapi-3.9.5.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- oc_cdtapi/API.py,sha256=ScjpCC6bdEzJBc1Qgp6ODH8bfxwccBr3hI9I96UYmQk,8680
2
- oc_cdtapi/DevPIAPI.py,sha256=SvQWSpsgZEsxJmm-edTPqZ25fi8KyvxQ0X27vjhU3cI,2054
3
- oc_cdtapi/DmsAPI.py,sha256=NzXfJ9k1srTOWZYCwOhxzLN1deNGnPtJoUy22qjiGmQ,7841
4
- oc_cdtapi/DmsGetverAPI.py,sha256=SOFLSl8DOCblR-swdHeufRLMPKahf1rDbILfz-4_zbk,13948
5
- oc_cdtapi/ForemanAPI.py,sha256=wGYPEPYgeNUSp2SATk_pZ4FRIwX9lmkcAgZyIzM47_4,39979
6
- oc_cdtapi/JenkinsAPI.py,sha256=ZBMDRmR4K7rlpGzqaWL7vPjlwweP4AGi2bom31v5T8s,15862
7
- oc_cdtapi/NexusAPI.py,sha256=PsE6Lzh3WcmZkqlIo0zqi_VvpHjYciUYvCLEQtH4bzw,26153
8
- oc_cdtapi/TestServer.py,sha256=HV97UWg2IK4gOYAp9yaMdwFUWsw9v66MxyZdI3qQctA,2715
9
- oc_cdtapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- oc_cdtapi-3.9.2.data/scripts/nexus.py,sha256=4teqZ_KtCSrwHDJVgA7lkreteod4Xt5XJFZNbwb7E6E,6858
11
- oc_cdtapi-3.9.2.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
12
- oc_cdtapi-3.9.2.dist-info/METADATA,sha256=vvaNt2GXOnNYqCH8Pc6sHtIBI_XVCqZo34pk43zB9nQ,276
13
- oc_cdtapi-3.9.2.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
14
- oc_cdtapi-3.9.2.dist-info/top_level.txt,sha256=d4-5-D-0CSeSXYuLCP7-nIFCpjkfmJr-Y_muzds8iVU,10
15
- oc_cdtapi-3.9.2.dist-info/RECORD,,