Skip to content

Commit

Permalink
lobster-codebeamer supports refs upstream reference (bmw-software-eng…
Browse files Browse the repository at this point in the history
…ineering#68)

* lobster-codebeamer supports refs upstream reference

An optional config file as argument has been added to lobster-codebeamer.
This config file should include a list of upstream references and respective cb-fieldNames

Resolves bmw-software-engineering#45
  • Loading branch information
TannazVhdBMWExt authored Sep 2, 2024
1 parent 68a8b59 commit 1676333
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### 0.9.18-dev

* The `lobster-codebeamer` tool now supports `refs` as an upstream reference

* The `lobster-online-report` tool now works with config files located in
main- and submodules of a repository. This feature needs `git 1.7.8` or higher.

Expand Down
89 changes: 89 additions & 0 deletions lobster/tools/codebeamer/codebeamer.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
import argparse
import netrc
from urllib.parse import quote
from enum import Enum
import json
import requests

from lobster.items import Tracing_Tag, Requirement
Expand All @@ -49,6 +51,26 @@
from lobster.io import lobster_read, lobster_write


class References(Enum):
REFS = "refs"


SUPPORTED_REFERENCES = [References.REFS.value]


def add_refs_refrences(req, flat_values_list):
# refs
for value in flat_values_list:
if value.get("id"):
ref_id = value.get("id")
req.add_tracing_target(Tracing_Tag("req", str(ref_id)))


map_reference_name_to_function = {
References.REFS.value: add_refs_refrences
}


def query_cb_single(cb_config, url):
assert isinstance(cb_config, dict)
assert isinstance(url, str)
Expand Down Expand Up @@ -193,6 +215,30 @@ def to_lobster(cb_config, cb_item):
text = None,
status = status)

if cb_config.get('references'):
for reference_name, displayed_chosen_names in (
cb_config['references'].items()):
if reference_name not in map_reference_name_to_function:
continue

for displayed_name in displayed_chosen_names:
if cb_item.get(displayed_name):
flat_values_list = cb_item.get(displayed_name) if (
isinstance(cb_item.get(displayed_name), list)) \
else [cb_item.get(displayed_name)]
else:
flat_values_list = (
list(value for custom_field
in cb_item["customFields"]
if custom_field["name"] == displayed_name and
custom_field.get("values")
for value in custom_field["values"]))
if not flat_values_list:
continue

(map_reference_name_to_function[reference_name]
(req, flat_values_list))

return req


Expand All @@ -210,17 +256,54 @@ def import_tagged(mh, cb_config, items_to_import):
return rv


def ensure_array_of_strings(instance):
if (isinstance(instance, list) and
all(isinstance(item, str)
for item in instance)):
return instance
else:
return [str(instance)]


def parse_cb_config(file_name):
assert isinstance(file_name, str)
assert os.path.isfile(file_name)

with open(file_name, "r", encoding='utf-8') as file:
data = json.loads(file.read())

provided_config_keys = set(data.keys())
supported_references = set(SUPPORTED_REFERENCES)

if not provided_config_keys.issubset(supported_references):
raise KeyError("The provided references are not supported! "
"supported referenes: '%s'" %
', '.join(SUPPORTED_REFERENCES))

json_config = {}
for key, value in data.items():
json_config[key] = ensure_array_of_strings(value)
return json_config


def main():
ap = argparse.ArgumentParser()

modes = ap.add_mutually_exclusive_group(required=True)
modes.add_argument("--import-tagged",
metavar="LOBSTER_FILE",
default=None)

modes.add_argument("--import-query",
metavar="CB_QUERY_ID",
default=None)

ap.add_argument("--config",
help=("name of codebeamer "
"config file, supported references: '%s'" %
', '.join(SUPPORTED_REFERENCES)),
default=None)

ap.add_argument("--ignore-ssl-errors",
action="store_true",
default=False,
Expand Down Expand Up @@ -254,6 +337,12 @@ def main():
"timeout" : options.timeout,
}

if options.config:
if os.path.isfile(options.config):
cb_config["references"] = parse_cb_config(options.config)
else:
ap.error("cannot open config file '%s'" % options.config)

if cb_config["root"] is None:
ap.error("please set CB_ROOT or use --cb-root")

Expand Down
27 changes: 27 additions & 0 deletions packages/lobster-tool-codebeamer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,30 @@ requirements management tool

* `lobster-codebeamer`: Extrat requirements from codebeamer.

## Configuration
This tool works with an optional config file. In it you can declare which
codebeamer fields should be used as 'refs' reference in the codebeamer file.

For the 'refs' reference in config file you can write:

```
{
"refs" : "cb-fieldname"
}
```
or
```
{
"refs" : ["cb-fieldname"]
}
```
or
```
{
"refs" : ["cb-fieldname1", "cb-fieldname2"]
}
```

## Usage

There are two ways you can use this tool:
Expand All @@ -23,6 +47,9 @@ There are two ways you can use this tool:
* Download all requirements generated by a saved codebeamer query
(using `--import-query`)

* Configure the 'refs' upstream reference (this argument is optional)
(using `--config`)

## Limitations

The key limitation is item text, which is currently not
Expand Down

0 comments on commit 1676333

Please sign in to comment.