Skip to content

Commit 878fadc

Browse files
ROMAIN BARTHROMAIN BARTH
authored andcommitted
Merge branch 'master' into DevRomain
2 parents 766ed3f + 2f7d5fa commit 878fadc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+23185
-22753
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[bumpversion]
2-
current_version = 0.32.0
2+
current_version = 0.34.0
33
commit = True
44
tag = True
55

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@
88

99
SPDX-License-Identifier: MIT
1010

11-
version="0.32.0"
11+
version="0.34.0"
1212

1313
What's New?
1414
===========
1515

16+
01-Aug-2025 0.34
17+
* New - first attempt at support for resources - for DN only at the moment. The aim is to simplify accessing and modifying properties of an artifact: you can get a python object for an artifact and access its properties as attributes of the object, e.g. req.Identifier. See dn_resource_test.py. Print the resource to see the modifiable and unmodifiable attributes. If you modify an (modifiable) attribute you can put() the resource to update it in DOORS Next. Modules can be resources but no possibility to modify the structure. You can add (DN->DN) links. You can see and modify the folder a core artifact is in.
18+
* New query methods (see resource.py) to simplify querying and get resources back.
19+
* Also fixed smaller bugs like the one introduced by Python 13 accepting quotes inside f-strings, which only showed up if you used Python <13
20+
* An attribute name can now be used in the oslcquery -s option, like -s "'Child Of'" (Windows) which used to give an error
21+
1622
16-Dec-2024
1723
* Authentication using Application passwords now works - for OIDC and SAML-backed authentication providers (OP) - but note below how this has been implemented to perhaps work around the fact that application passwords only work with a single app, os if you want to talk to more than one app, e.g. rm and gc, you have to acquire and specify a password per app. Not extensively tested, please let me know if it works/doesn't work for you!.
1824

elmclient/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
# scan for extensions to import and extend the specified class
3232
# extensions are .py file with a name like <classname>-something.py e.g RMApp-extension.py
33-
# the classes in the file are added as base classes to the extended class
33+
# the classes in the file are added as base classes (i.e. additional mixins) to the extended class
3434
# so it's dynamic mixins :-)
3535
# A mixin may override existing methods but the main aim is to add new methods for that class
3636
def load_extensions( *, path=None, folder=None ):
@@ -65,8 +65,9 @@ def load_extensions( *, path=None, folder=None ):
6565
# add them to the extended class so they precede (i.e. may override) the previous base classes
6666
for n,c in extenderclasses.items():
6767
# add to bases
68+
print( f"Extending {extendedclass} with {c}" )
6869
extendedclass.__bases__ = (c,)+extendedclass.__bases__
6970

7071
## load any local extensions
71-
#load_extensions()
72+
load_extensions()
7273

elmclient/__meta__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
app = 'elmoslcquery'
1111
description = 'Commandline OSLC query for ELM'
12-
version = '0.32.0'
12+
version = '0.34.0'
1313
license = 'MIT'
1414
author_name = 'Ian Barnard'
1515
author_mail = 'ian.barnard@uk.ibm.com'

elmclient/_ccm.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from . import rdfxml
1919
from . import server
2020
from . import utils
21+
from . import resource
2122

2223
#################################################################################################
2324

@@ -39,7 +40,7 @@ def callers():
3940

4041
#################################################################################################
4142

42-
class CCMProject(_project._Project):
43+
class CCMProject( _project._Project , resource.Resources_Mixin):
4344
def __init__(self, name, project_uri, app, is_optin,singlemode):
4445
super().__init__(name, project_uri, app, is_optin,singlemode)
4546
self.default_query_resource = 'oslc_cm1:ChangeRequest'
@@ -130,7 +131,7 @@ def _load_type_from_resource_shape(self, el, supershape=None):
130131
altname = None
131132

132133
logger.info( f"Defining property {title}.{property_title} {altname=} {propuri=} +++++++++++++++++++++++++++++++++++++++" )
133-
self.register_property(property_title,propuri, shape_uri=uri, altname=altname,property_definition_uri=property_definition_uri)
134+
self.register_property(property_title,propuri, altname=altname,property_definition_uri=property_definition_uri, shape_uri=uri)
134135

135136
allowedvaluesu = rdfxml.xmlrdf_get_resource_uri(real_propel, ".//oslc:allowedValues" )
136137
if allowedvaluesu is not None:
@@ -175,7 +176,7 @@ def _load_type_from_resource_shape(self, el, supershape=None):
175176
# register this shape as an rtc_cm:type enum
176177
logger.info( f"Defining category rtc_cm:type {enum_value_name} {enum_id} {category} {enum_uri}" )
177178
# ensure the rtc_cm:type property is defined (but don't overwrite existing definition)
178-
self.register_property( 'rtc_cm:type', 'rtc_cm:type', do_not_overwrite=True )
179+
self.register_property( 'rtc_cm:type', 'rtc_cm:type', do_not_overwrite=True, shape_uri=uri )
179180
# add the shape to it using the shape's URI as an enum URI
180181
# NOTE the use of the id - this id is used when comparing values with rtc_cm_type to see workaround https://jazz.net/forum/questions/86619/oslc-20-query-with-oslcwhere-parameter-dctermstype-returns-400-unknown-attribute-id
181182
self.register_enum( enum_value_name, enum_uri, 'rtc_cm:type',id=enum_id )

elmclient/_customScenarios.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def getRunningScenarios( self ):
128128
LOGLEVEL = os.environ.get("QUERY_LOGLEVEL" ,None )
129129

130130
# setup arghandler
131-
parser = argparse.ArgumentParser(description="Perform OSLC query on a Jazz application, with results output to CSV (and other) formats - use -h to get some basic help")
131+
parser = argparse.ArgumentParser(description="Test harness for CusgtomScenarios")
132132

133133
parser.add_argument('action', choices=['start','stop','status'], help=f'start/stop/status')
134134
parser.add_argument('name', default=None, nargs='?', help=f'The anme of the scenario - only relevant for the start and stop actions')

elmclient/_gcm.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ def _generic_load_type_from_resource_shape(self, el, supershape=None):
610610

611611
if pd_u is not None:
612612
if not pd_u.startswith( self.baseurl ):
613-
self.register_property(property_title,pd_u, shape_uri=uri, altname=altname)
613+
self.register_property(property_title,pd_u, altname=altname, shape_uri=uri)
614614
logger.debug( f"+++++++Skipping non-local Property Definition {pd_u}" )
615615
continue
616616
else:
@@ -620,7 +620,7 @@ def _generic_load_type_from_resource_shape(self, el, supershape=None):
620620
logger.debug( f"ALREADY KNOWN2" )
621621
continue
622622
logger.info( f"Defining property {title}.{property_title} {altname=} {pd_u=} +++++++++++++++++++++++++++++++++++++++" )
623-
self.register_property(property_title,pd_u, shape_uri=uri, altname=altname)
623+
self.register_property(property_title,pd_u, altname=altname, shape_uri=uri)
624624
# check for any allowed value
625625
allowedvalueu = rdfxml.xmlrdf_get_resource_uri(real_propel, ".//oslc:allowedValue" )
626626
if allowedvalueu is not None:
@@ -707,8 +707,8 @@ def resolve_uri_to_name(self, uri, prefer_same_as=True, dontpreferhttprdfrui=Tru
707707

708708
# for OSLC query, given an attribute (property) name return its type URI
709709
# the context is the shape definition - can be None, needed to be specified ultimately by the user when property names aren't unique
710-
def resolve_property_name_to_uri(self, name, shapeuri=None, exception_if_not_found=True):
711-
logger.info( f"resolve_property_name_to_uri {name=} {shapeuri=}" )
712-
result = self.get_property_uri(name,shape_uri=shapeuri)
713-
logger.info( f"resolve_property_name_to_uri {name=} {shapeuri=} {result=}" )
710+
def resolve_property_name_to_uri(self, name, exception_if_not_found=True):
711+
logger.info( f"resolve_property_name_to_uri {name=} " )
712+
result = self.get_property_uri(name)
713+
logger.info( f"resolve_property_name_to_uri {name=} {result=}" )
714714
return result

elmclient/_newtypesystem.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,10 @@ def load_ot( self, serverconnection, url, iscacheable=True, isused=False ):
285285
print( f"OT definition for {url} already present!" )
286286
return
287287
# get the URI and process all the attributes
288-
content_x = serverconnection.execute_get_xml( url, params={'oslc_config.context':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
288+
content_x = serverconnection.execute_get_xml( url, params={'vvc.configuration':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
289289
if content_x is None:
290-
burp
290+
raise Exception( "No XML!" )
291+
291292
modified = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:modified', exceptionifnotfound=True )
292293
modifiedBy = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:contributor', exceptionifnotfound=True )
293294
# component = rdfxml.xmlrdf_get_resource_uri( content_x,'.//oslc_config:component', exceptionifnotfound=True )
@@ -313,9 +314,10 @@ def load_ad( self, serverconnection, url, iscacheable=True, isused=False ):
313314
# print( f"AD definition for {url} already present!" )
314315
return
315316
# get the URI and process all the attributes
316-
content_x = serverconnection.execute_get_xml( url, params={'oslc_config.context':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
317+
content_x = serverconnection.execute_get_xml( url, params={'vvc.configuration':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
317318
if content_x is None:
318-
burp
319+
raise Exception( "No XML!" )
320+
319321
modified = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:modified', exceptionifnotfound=True )
320322
modifiedBy = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:contributor', exceptionifnotfound=True )
321323
# component = rdfxml.xmlrdf_get_resource_uri( content_x,'.//oslc_config:component', exceptionifnotfound=True )
@@ -340,9 +342,9 @@ def load_at( self, serverconnection, url, iscacheable=True, isused=False ):
340342
if not serverconnection.app.is_server_uri( url ):
341343
# print( f"AT Ignoring non-server URL {url}" )
342344
return
343-
content_x = serverconnection.execute_get_xml( url, params={'oslc_config.context':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
345+
content_x = serverconnection.execute_get_xml( url, params={'vvc.configuration':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
344346
if content_x is None:
345-
burp
347+
raise Exception( "No XML!" )
346348
modified = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:modified', exceptionifnotfound=True )
347349
modifiedBy = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:contributor', exceptionifnotfound=True )
348350
# component = rdfxml.xmlrdf_get_resource_uri( content_x,'.//oslc_config:component', exceptionifnotfound=True )
@@ -386,9 +388,9 @@ def load_lt( self, serverconnection, url, iscacheable=True, isused=False ):
386388
if url in self.lts:
387389
# print( f"LT definition for {url} already present!" )
388390
return
389-
content_x = serverconnection.execute_get_xml( url, params={'oslc_config.context':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
391+
content_x = serverconnection.execute_get_xml( url, params={'vvc.configuration':serverconnection.local_config},headers={'Configuration-Context': None}, cacheable=iscacheable )
390392
if content_x is None:
391-
burp
393+
raise Exception( "No XML!" )
392394
modified = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:modified', exceptionifnotfound=True )
393395
modifiedBy = rdfxml.xmlrdf_get_resource_uri( content_x,'.//dcterms:contributor', exceptionifnotfound=True )
394396
# component = rdfxml.xmlrdf_get_resource_uri( content_x,'.//oslc_config:component', exceptionifnotfound=True )

0 commit comments

Comments
 (0)