Skip to content

Commit

Permalink
further macros for reqs and trace handling. allowing more than one de…
Browse files Browse the repository at this point in the history
…rived_to req. needs to be done for derived_from too. further examples.
  • Loading branch information
DrMarkusVoss committed Feb 22, 2025
1 parent 05f2bd6 commit 19d5fbc
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 26 deletions.
105 changes: 94 additions & 11 deletions pumla_macros_reqs.puml
Original file line number Diff line number Diff line change
@@ -1,28 +1,111 @@
' ############################################
' ---------------------------------------------
' create a req as an object with reduced number
' of attributes.
' Hint: objects are parts of class diagrams.
' in order to mix them or use them on other
' diagrams, "allowmixing" needs to be used.
!unquoted procedure _PUMLACreateReqObject($alias)
object $r.alias {
|= type | $r.type |
|= content | $r.content |
|= status | $r.status |
}
!endprocedure

' ############################################
' ---------------------------------------------
' create the reqs trace starting with the
' requirement with the given alias in a
' recursive way.
!unquoted procedure PUMLAPutReqsBreakdownTraceFor($alias)
' recursive way with an iteration counter to
' make sure we do not consider elements up the
' trace, only down.
!unquoted procedure _PUMLARecursivePutReqsBreakdownTraceFor($alias, $itcnt)
!$r = null
!$cnt = %intval($itcnt)

!foreach $r in $allreqs.reqs
!if $r.alias == $alias
object $r.alias {
|= Type | $r.type |
|= Content | $r.content |
|= Status | $r.status |
}
_PUMLACreateReqObject($r.alias)

!if %not($r.derived_from==null)
' do not go the trace up on the first element, only down
!if %not($r.derived_from==null) && %not($cnt==0)
$r.derived_from <|-- $r.alias
!endif

!$cnt = $cnt + 1
!if %not($r.derived_to==null)
PUMLAPutReqsBreakdownTraceFor($r.derived_to)
!foreach $dtra in $r.derived_to
_PUMLARecursivePutReqsBreakdownTraceFor($dtra,$cnt)
!endfor
!endif

!endif
!endfor

!endprocedure


' ############################################
' ---------------------------------------------
' create the reqs trace starting with the
' requirement with the given alias in a
' recursive way.
!unquoted procedure PUMLAPutReqsBreakdownTraceFor($alias)
_PUMLARecursivePutReqsBreakdownTraceFor($alias,0)
!endprocedure



' ############################################
' ---------------------------------------------
' put a requirement with a given alias onto
' the diagram
!unquoted procedure PUMLAPutReq($alias)
!foreach $r in $allreqs.reqs
!if $r.alias == $alias
json $r.alias $r
!endif
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' put a requirement with reduced number of
' attributes for a given alias onto
' the diagram
!unquoted procedure PUMLAPutReqBrief($alias)
!foreach $r in $allreqs.reqs
!if $r.alias == $alias
_PUMLACreateReqObject($r.alias)
!endif
!endfor
!endprocedure

!endprocedure
' ############################################
' ---------------------------------------------
' put a requirement with a given alias onto
' the diagram wrapped into a note
!unquoted procedure PUMLAPutReqAsNote($alias)
!foreach $r in $allreqs.reqs
!if $r.alias == $alias
note as $r.alias #white
{{
PUMLAPutReqBrief($alias)
}}
end note
!endif
!endfor
!endprocedure

' ############################################
' ---------------------------------------------
' put all requirements with reduced number of
' attributes and trace onto the diagram
!unquoted procedure PUMLAPutAllReqsBrief()
!foreach $r in $allreqs.reqs
_PUMLACreateReqObject($r.alias)
!if %not($r.derived_from==null)
$r.derived_from <|-- $r.alias
!endif
!endfor
!endprocedure
2 changes: 2 additions & 0 deletions src/pumla/control/cmd_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ def createPumlaMacrosFile(mainpath):
pm_comment = pm_comment + "' IN THE FOLDER OF THIS FILE HERE!\n"
pm_include_macros = "!include " + pumla_macros_path + "pumla_macros_global.puml\n"
pm_include_tv = "!include " + pumla_macros_path + "pumla_tagged_values.puml\n"
pm_include_reqs = "!include " + pumla_macros_path + "pumla_macros_reqs.puml\n"
pm_include_project_cfg = '\n!if %file_exists("' + curpath + '/pumla_project_config.puml")\n'
pm_include_project_cfg = pm_include_project_cfg + "!include pumla_project_config.puml\n"
pm_include_project_cfg = pm_include_project_cfg + "!endif\n"
Expand All @@ -142,6 +143,7 @@ def createPumlaMacrosFile(mainpath):
fil.write(pm_include_project_cfg)
fil.write(pm_include_macros)
fil.write(pm_include_tv)
fil.write(pm_include_reqs)
fil.write(pm_include_c4int)
fil.close()
else:
Expand Down
6 changes: 4 additions & 2 deletions src/pumla/control/reqparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def updatePUMLAReqRepo(path, mrefilename):
for f in pumlareqfiles:
reqs = parsePUMLAReqFile(f)
for r in reqs:
r.update({"derived_to": None})
r.update({"derived_to": []})
r.update({"in_file": f})
if not r.get("derived_from")==None:
derived_table.append({"from": r["derived_from"], "to": r.get("alias")})
Expand All @@ -71,7 +71,9 @@ def updatePUMLAReqRepo(path, mrefilename):
for e in derived_table:
for r in pumlareqslist:
if r.get("alias") == e.get("from"):
r.update({"derived_to": e.get("to")})
der_to = r.get("derived_to")
der_to.append(e.get("to"))
r.update({"derived_to": der_to})


# make it accessible from within PlantUML.
Expand Down
12 changes: 12 additions & 0 deletions test/examples/WeatherStation/CWeather/req.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#PUMLARR
- type: Requirement
alias: REQ_SW_CWeather1
status: decided
derived_from: REQ_WS1
taggedvalues:
- tag: "Level"
values: "Software"
- tag: "Variant"
values: [SysA, SysB]
content:
There shall be one central class to manage all data regarding weather.
2 changes: 2 additions & 0 deletions test/examples/WeatherStation/allElements.puml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@startuml
!include modelrepo_json.puml
!include reqsrepo_json.puml
!include pumla_macros.puml
!include ./../../../templates/sysml/skin.puml

Expand All @@ -20,6 +21,7 @@ title Overview of all elements and their relations of the model repo
'put all elements of json-repo onto the diagram
PUMLAPutAllElements()

PUMLAPutReq(REQ_WS1)
'put all relations between static elements
'of the json-repo onto the diagram
PUMLAPutAllStaticRelations()
Expand Down
3 changes: 2 additions & 1 deletion test/examples/WeatherStation/arch_level_overview.puml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
!include pumla_macros.puml
!include modelrepo_json.puml


!$PUMVarShowBodyInternals = %false()
!$PUMVarShowBodyInternalsDyn = %false()
!$PUMVarShowInterfaces = %false()
Expand All @@ -16,4 +17,4 @@ rectangle "Level 1 Elements" as l1 {
PUMLAPutAllElementsWithTagValue("Arch Level", "1")
}

@enduml
@enduml
9 changes: 9 additions & 0 deletions test/examples/WeatherStation/exampleAllReqs.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@startuml
!include reqsrepo_json.puml
!include pumla_macros.puml

' put all requirement onto a diagram
' and show the trace among them.
PUMLAPutAllReqsBrief()

@enduml
16 changes: 16 additions & 0 deletions test/examples/WeatherStation/exampleArchRealizesReq.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@startuml
!include reqsrepo_json.puml
!include modelrepo_json.puml
!include pumla_macros.puml

!$PUMVarShowBodyInternals = %false()
!$PUMVarShowInterfaces = %false()

allowmixing

PUMLAPutElement(tempSys)
PUMLAPutReqBrief(REQ_WS1)

tempSys <|-- REQ_WS1

@enduml
7 changes: 7 additions & 0 deletions test/examples/WeatherStation/exampleReqTrace.puml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,12 @@
' "realizing" trace.
PUMLAPutReqsBreakdownTraceFor(REQ_WS1)

PUMLAPutReq(REQ_WS2)

PUMLAPutReqBrief(REQ_WS3)

' these arrows don't make sense, just to test
REQ_WS2 --> REQ_WS3
REQ_WS1 --> REQ_WS2

@enduml
14 changes: 8 additions & 6 deletions test/examples/WeatherStation/reqs_json_diagram.puml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
@startjson
{"reqsrepopath": ".", "reqsrepofile": "./reqsrepo_json.puml", "reqs": [{"type": "Requirement", "alias": "REQ_WS1", "status": "decided", "derived_from": null, "taggedvalues": [{"tag": "Vendor", "values": ["A Inc.", "C Ltd."]},
{"tag": "Variant", "values": ["SysA", "SysB"]}], "content": "This is a requirement towards my Weather Station. The Weather Station shall be able to measure the temperature.", "derived_to": "REQ_SensorA1", "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS2", "status": "new", "derived_from": null, "content": "This is another requirement. The Weather Station housing shall be blue.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS3", "status": "aligned", "derived_from": null, "content": "The Weather Station shall display the measured temperature so that it is conveniently readable by a human looking at it in a distance of up to 3m.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS4", "status": "aligned", "derived_from": null, "content": "It shall be possible to switch the unit of the displayed temperature between degree Celsius and Fahrenheit.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS5", "status": "aligned", "derived_from": null, "content": "The unit in which the temperature is displayed shall stay as it is even after the batteries and/or the power supply has been removed.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_SensorA1", "status": "aligned", "derived_from": "REQ_WS1", "content": "The sensor shall be able to measure the temperature of the surrounding air in the room.", "derived_to": null, "in_file": "./tempSensorA/req.yaml"}]}
{"tag": "Variant", "values": ["SysA", "SysB"]}], "content": "This is a requirement towards my Weather Station. The Weather Station shall be able to measure the temperature.", "derived_to": ["REQ_SW_CWeather1", "REQ_SensorA1"], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS2", "status": "new", "derived_from": null, "content": "This is another requirement. The Weather Station housing shall be blue.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS3", "status": "aligned", "derived_from": null, "content": "The Weather Station shall display the measured temperature so that it is conveniently readable by a human looking at it in a distance of up to 3m.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS4", "status": "aligned", "derived_from": null, "content": "It shall be possible to switch the unit of the displayed temperature between degree Celsius and Fahrenheit.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS5", "status": "aligned", "derived_from": null, "content": "The unit in which the temperature is displayed shall stay as it is even after the batteries and/or the power supply has been removed.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_SW_CWeather1", "status": "decided", "derived_from": "REQ_WS1", "taggedvalues": [{"tag": "Level", "values": "Software"},
{"tag": "Variant", "values": ["SysA", "SysB"]}], "content": "There shall be one central class to manage all data regarding weather.", "derived_to": [], "in_file": "./CWeather/req.yaml"},
{"type": "Requirement", "alias": "REQ_SensorA1", "status": "aligned", "derived_from": "REQ_WS1", "content": "The sensor shall be able to measure the temperature of the surrounding air in the room.", "derived_to": [], "in_file": "./tempSensorA/req.yaml"}]}
@endjson


14 changes: 8 additions & 6 deletions test/examples/WeatherStation/reqsrepo_json.puml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
!$allreqs = {"reqsrepopath": ".", "reqsrepofile": "./reqsrepo_json.puml", "reqs": [{"type": "Requirement", "alias": "REQ_WS1", "status": "decided", "derived_from": null, "taggedvalues": [{"tag": "Vendor", "values": ["A Inc.", "C Ltd."]},
{"tag": "Variant", "values": ["SysA", "SysB"]}], "content": "This is a requirement towards my Weather Station. The Weather Station shall be able to measure the temperature.", "derived_to": "REQ_SensorA1", "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS2", "status": "new", "derived_from": null, "content": "This is another requirement. The Weather Station housing shall be blue.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS3", "status": "aligned", "derived_from": null, "content": "The Weather Station shall display the measured temperature so that it is conveniently readable by a human looking at it in a distance of up to 3m.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS4", "status": "aligned", "derived_from": null, "content": "It shall be possible to switch the unit of the displayed temperature between degree Celsius and Fahrenheit.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS5", "status": "aligned", "derived_from": null, "content": "The unit in which the temperature is displayed shall stay as it is even after the batteries and/or the power supply has been removed.", "derived_to": null, "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_SensorA1", "status": "aligned", "derived_from": "REQ_WS1", "content": "The sensor shall be able to measure the temperature of the surrounding air in the room.", "derived_to": null, "in_file": "./tempSensorA/req.yaml"}]}
{"tag": "Variant", "values": ["SysA", "SysB"]}], "content": "This is a requirement towards my Weather Station. The Weather Station shall be able to measure the temperature.", "derived_to": ["REQ_SW_CWeather1", "REQ_SensorA1"], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS2", "status": "new", "derived_from": null, "content": "This is another requirement. The Weather Station housing shall be blue.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS3", "status": "aligned", "derived_from": null, "content": "The Weather Station shall display the measured temperature so that it is conveniently readable by a human looking at it in a distance of up to 3m.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS4", "status": "aligned", "derived_from": null, "content": "It shall be possible to switch the unit of the displayed temperature between degree Celsius and Fahrenheit.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_WS5", "status": "aligned", "derived_from": null, "content": "The unit in which the temperature is displayed shall stay as it is even after the batteries and/or the power supply has been removed.", "derived_to": [], "in_file": "./req.yaml"},
{"type": "Requirement", "alias": "REQ_SW_CWeather1", "status": "decided", "derived_from": "REQ_WS1", "taggedvalues": [{"tag": "Level", "values": "Software"},
{"tag": "Variant", "values": ["SysA", "SysB"]}], "content": "There shall be one central class to manage all data regarding weather.", "derived_to": [], "in_file": "./CWeather/req.yaml"},
{"type": "Requirement", "alias": "REQ_SensorA1", "status": "aligned", "derived_from": "REQ_WS1", "content": "The sensor shall be able to measure the temperature of the surrounding air in the room.", "derived_to": [], "in_file": "./tempSensorA/req.yaml"}]}

0 comments on commit 19d5fbc

Please sign in to comment.