From 5a60fc1bb24546a069fe4553468249efb205ae16 Mon Sep 17 00:00:00 2001 From: f-peverali Date: Mon, 8 Jan 2024 15:55:39 +0100 Subject: [PATCH] update scripts and version --- ImplementationGuide/markdown/Einfuehrung.md | 82 ++++----- Resources/input/fsh/ruleset.fsh | 64 +++---- Resources/sushi-config.yaml | 18 +- package.json | 26 +-- scripts/config.yaml | 26 +++ scripts/release_publish.py | 186 +++++++++----------- 6 files changed, 207 insertions(+), 195 deletions(-) create mode 100644 scripts/config.yaml diff --git a/ImplementationGuide/markdown/Einfuehrung.md b/ImplementationGuide/markdown/Einfuehrung.md index a649d55..84a3dcf 100644 --- a/ImplementationGuide/markdown/Einfuehrung.md +++ b/ImplementationGuide/markdown/Einfuehrung.md @@ -1,41 +1,41 @@ -gematik logo - ----- -Version: 3.0.0 - -Datum: 1.7.2023 - -Status: Aktiv - -Realm: Deutschland - ----- - -# Interoperabler Datenaustausch durch Informationssysteme im Krankenhaus (ISiK) - -Die gematik wurde vom Gesetzgeber beauftragt, im Benehmen mit der Deutschen Krankenhausgesellschaft (DKG) und den maßgeblichen Bundesverbänden der Industrie im Gesundheitswesen, verbindliche Standards für den Austausch von Gesundheitsdaten mit Informationssystemen im Krankenhaus zu erarbeiten. Dieser FHIR ImplementationGuide (IG) beschreibt die für diesen Zweck entwickelten FHIR Profile und das [REST](https://de.wikipedia.org/wiki/Representational_State_Transfer)-basierte Application Programming Interface (API). Die REST-API wird im Wesentlichen [vom FHIR Standard vorgegeben](https://www.hl7.org/fhir/R4/http.html). Dieser Leitfaden konkretisiert die ISiK-relevanten Funktionen der Standard-REST-API und trifft inhaltliche Festlegungen zu den ISiK-relevanten Ressourcen in Form von Ressourcen-Profilen. - -Hersteller bestätigungsrelevanter Systeme sollen durch diesen IG in die Lage versetzt werden, eine konforme Implementierung zu erstellen und das Bestätigungsverfahren der gematik erfolgreich zu absolvieren. - -Weitere Informationen siehe [§373 SGB V](https://www.gesetze-im-internet.de/sgb_5/__373.html). - -Hinweis: Sowohl für die Implementierung der ISiK-Spezifikation als auch für den Betrieb eines Produktes, das die ISiK-Spezifikation implementiert, ist eine SNOMED-CT-Lizenz notwendig. Diese kann beim [National Release Center für SNOMED CT in Deutschland](https://www.bfarm.de/DE/Kodiersysteme/Terminologien/SNOMED-CT/_node.html) beantragt werden. - -**Kontakt** - -Bringen Sie allgemeine Fragen und Anmerkungen gerne über unser Anfrageportal ein: [Anfragen ISiK + ISiP](https://service.gematik.de/servicedesk/customer/portal/16) - -Falls Sie keinen Zugang zum Anfrageportal haben und dieses nutzen wollen, senden Sie uns bitte eine Nachricht an die Adresse isik [ at ] gematik.de mit dem Betreff "Portalzugang". - -**Herausgeber** - -gematik GmbH - -[Impressum](https://www.gematik.de/impressum/) - -**Gender-Hinweis** - -Zugunsten des Leseflusses wird in dieser Publikation meist die -männliche Form verwendet. Wir bitten, dies nicht als Zeichen einer -geschlechtsspezifischen Wertung zu deuten. Diese Variante deckt auch alle -weiteren Geschlechter, neben männlich und weiblich, ab. +gematik logo + +---- +Version: 3.0.1 + +Datum: 08.01.2024 + +Status: Aktiv + +Realm: Deutschland + +---- + +# Interoperabler Datenaustausch durch Informationssysteme im Krankenhaus (ISiK) + +Die gematik wurde vom Gesetzgeber beauftragt, im Benehmen mit der Deutschen Krankenhausgesellschaft (DKG) und den maßgeblichen Bundesverbänden der Industrie im Gesundheitswesen, verbindliche Standards für den Austausch von Gesundheitsdaten mit Informationssystemen im Krankenhaus zu erarbeiten. Dieser FHIR ImplementationGuide (IG) beschreibt die für diesen Zweck entwickelten FHIR Profile und das [REST](https://de.wikipedia.org/wiki/Representational_State_Transfer)-basierte Application Programming Interface (API). Die REST-API wird im Wesentlichen [vom FHIR Standard vorgegeben](https://www.hl7.org/fhir/R4/http.html). Dieser Leitfaden konkretisiert die ISiK-relevanten Funktionen der Standard-REST-API und trifft inhaltliche Festlegungen zu den ISiK-relevanten Ressourcen in Form von Ressourcen-Profilen. + +Hersteller bestätigungsrelevanter Systeme sollen durch diesen IG in die Lage versetzt werden, eine konforme Implementierung zu erstellen und das Bestätigungsverfahren der gematik erfolgreich zu absolvieren. + +Weitere Informationen siehe [§373 SGB V](https://www.gesetze-im-internet.de/sgb_5/__373.html). + +Hinweis: Sowohl für die Implementierung der ISiK-Spezifikation als auch für den Betrieb eines Produktes, das die ISiK-Spezifikation implementiert, ist eine SNOMED-CT-Lizenz notwendig. Diese kann beim [National Release Center für SNOMED CT in Deutschland](https://www.bfarm.de/DE/Kodiersysteme/Terminologien/SNOMED-CT/_node.html) beantragt werden. + +**Kontakt** + +Bringen Sie allgemeine Fragen und Anmerkungen gerne über unser Anfrageportal ein: [Anfragen ISiK + ISiP](https://service.gematik.de/servicedesk/customer/portal/16) + +Falls Sie keinen Zugang zum Anfrageportal haben und dieses nutzen wollen, senden Sie uns bitte eine Nachricht an die Adresse isik [ at ] gematik.de mit dem Betreff "Portalzugang". + +**Herausgeber** + +gematik GmbH + +[Impressum](https://www.gematik.de/impressum/) + +**Gender-Hinweis** + +Zugunsten des Leseflusses wird in dieser Publikation meist die +männliche Form verwendet. Wir bitten, dies nicht als Zeichen einer +geschlechtsspezifischen Wertung zu deuten. Diese Variante deckt auch alle +weiteren Geschlechter, neben männlich und weiblich, ab. diff --git a/Resources/input/fsh/ruleset.fsh b/Resources/input/fsh/ruleset.fsh index 0bf956d..ac963c0 100644 --- a/Resources/input/fsh/ruleset.fsh +++ b/Resources/input/fsh/ruleset.fsh @@ -1,33 +1,33 @@ -RuleSet: Meta -* ^status = #active -* ^experimental = false -* ^publisher = "gematik GmbH" -* ^version = "3.0.0" -* ^date = "2023-07-01" - -RuleSet: Meta-CapabilityStatementInformation -* status = #active -* experimental = false -* version = "3.0.0" -* publisher = "gematik GmbH" -* date = "2023-07-01" -* implementationGuide = "https://gematik.de/fhir/isik/v3/Medikation/ImplementationGuide|3.0.0" -* url = "https://gematik.de/fhir/isik/v3/Medikation/CapabilityStatement/medikation-server/information" - -RuleSet: Meta-CapabilityStatementVerordnung -* status = #active -* experimental = false -* version = "3.0.0" -* publisher = "gematik GmbH" -* date = "2023-07-01" -* implementationGuide = "https://gematik.de/fhir/isik/v3/Medikation/ImplementationGuide|3.0.0" -* url = "https://gematik.de/fhir/isik/v3/Medikation/CapabilityStatement/medikation-server/verordnung" - -RuleSet: Meta-CapabilityStatementVerabreichung -* status = #active -* experimental = false -* version = "3.0.0" -* publisher = "gematik GmbH" -* date = "2023-07-01" -* implementationGuide = "https://gematik.de/fhir/isik/v3/Medikation/ImplementationGuide|3.0.0" +RuleSet: Meta +* ^status = #active +* ^experimental = false +* ^publisher = "gematik GmbH" +* ^version = "3.0.1" +* ^date = "2024-01-08" + +RuleSet: Meta-CapabilityStatementInformation +* status = #active +* experimental = false +* version = "3.0.1" +* publisher = "gematik GmbH" +* date = "2024-01-08" +* implementationGuide = "https://gematik.de/fhir/isik/v3/Medikation/ImplementationGuide|3.0.1" +* url = "https://gematik.de/fhir/isik/v3/Medikation/CapabilityStatement/medikation-server/information" + +RuleSet: Meta-CapabilityStatementVerordnung +* status = #active +* experimental = false +* version = "3.0.1" +* publisher = "gematik GmbH" +* date = "2024-01-08" +* implementationGuide = "https://gematik.de/fhir/isik/v3/Medikation/ImplementationGuide|3.0.1" +* url = "https://gematik.de/fhir/isik/v3/Medikation/CapabilityStatement/medikation-server/verordnung" + +RuleSet: Meta-CapabilityStatementVerabreichung +* status = #active +* experimental = false +* version = "3.0.1" +* publisher = "gematik GmbH" +* date = "2024-01-08" +* implementationGuide = "https://gematik.de/fhir/isik/v3/Medikation/ImplementationGuide|3.0.1" * url = "https://gematik.de/fhir/isik/v3/Medikation/CapabilityStatement/medikation-server/verabreichung" \ No newline at end of file diff --git a/Resources/sushi-config.yaml b/Resources/sushi-config.yaml index ee417dd..be342e6 100644 --- a/Resources/sushi-config.yaml +++ b/Resources/sushi-config.yaml @@ -1,9 +1,9 @@ -canonical: https://gematik.de/fhir/isik/v3/Medikation -fhirVersion: 4.0.1 -FSHOnly: true -applyExtensionMetadataToRoot: false -version: 3.0.0 -dependencies: - de.medizininformatikinitiative.kerndatensatz.medikation: 1.0.11 - hl7.fhir.r4.core: 4.0.1 - de.gematik.isik-basismodul: 3.0.0 +canonical: https://gematik.de/fhir/isik/v3/Medikation +fhirVersion: 4.0.1 +FSHOnly: true +applyExtensionMetadataToRoot: false +version: 3.0.1 +dependencies: + de.medizininformatikinitiative.kerndatensatz.medikation: 1.0.11 + hl7.fhir.r4.core: 4.0.1 + de.gematik.isik-basismodul: 3.0.0 diff --git a/package.json b/package.json index 4affa90..8a3c562 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ -{ - "name": "de.gematik.isik-medikation", - "version": "3.0.0", - "fhirVersions": [ - "4.0.1" - ], - "dependencies": { - "hl7.fhir.r4.core": "4.0.1", - "de.medizininformatikinitiative.kerndatensatz.medikation": "1.0.11", - "hl7.fhir.uv.ips": "1.0.0", - "de.gematik.isik-basismodul": "3.0.0" - } -} +{ + "name": "de.gematik.isik-medikation", + "version": "3.0.1", + "fhirVersions": [ + "4.0.1" + ], + "dependencies": { + "hl7.fhir.r4.core": "4.0.1", + "de.medizininformatikinitiative.kerndatensatz.medikation": "1.0.11", + "hl7.fhir.uv.ips": "1.0.0", + "de.gematik.isik-basismodul": "3.0.0" + } +} diff --git a/scripts/config.yaml b/scripts/config.yaml new file mode 100644 index 0000000..35ac342 --- /dev/null +++ b/scripts/config.yaml @@ -0,0 +1,26 @@ +package.json: + - type: version + regex: '("version":\s*")([\d\.]+.*)(")' +sushi-config.yaml: + - type: version + regex: '(version:\s*)(\d+\.\d+\.\d+.*)()' +ruleset.fsh: + - type: version + regex: + - '(\*\s*version\s*=\s*")([\d\.]+.*)(")' + - '(\*\s*\^version\s*=\s*")([\d\.]+.*)(")' + - '(\*\s*implementationGuide\s*=\s*".*\|)([\d\.]+.*)(")' + - type: date + regex: + - '(\*\s*date\s*=\s*")(\d+\-\d+\-\d+)(")' + - '(\*\s*\^date\s*=\s*")(\d+\-\d+\-\d+)(")' + format: '%Y-%m-%d' +Einfuehrung.md: + - type: version + regex: '(Version: \s*)(\d+\.\d+\.\d+.*)()' + - type: date + regex: '(Datum:\s*)(\d+\.\d+\.\d+.*)()' + format: '%d.%m.%Y' +ImplementierungsleitfadenIsiK_Dokumentenaustausch.json: + - type: version + regex: '("version":\s*")(\d+\.\d+\.\d+.*)(",)' \ No newline at end of file diff --git a/scripts/release_publish.py b/scripts/release_publish.py index 92e9cca..86adfa5 100644 --- a/scripts/release_publish.py +++ b/scripts/release_publish.py @@ -1,128 +1,104 @@ +import datetime import re import subprocess import os import argparse from datetime import date +import yaml -class FileWithVersionToUpdate: - def __init__(self, filename, version_regex) -> None: - self.filename = filename - self.version_regex = version_regex - self.location = None - - def set_file_location(self, location): - self.location = location -class FileWithDateToUpdate: - def __init__(self, filename, date_regex) -> None: +class FileTypeCombinationToUpdate: + def __init__(self, filename, content_type, regex_list, format=None) -> None: self.filename = filename - self.date_regex = date_regex + self.content_type = content_type + self.regex_list = regex_list + self.format = format self.location = None def set_file_location(self, location): self.location = location -# class FileWithDateToUpdate: -# def __init__(self, filename, date_regex, format) -> None: -# self.filename = filename -# self.date_regex = date_regex -# self.location = None -# self.format = format -# def set_file_location(self, location): -# self.location = location - - +def load_config_file(config_file_path): + with open(config_file_path, 'r') as config_file: + return yaml.safe_load(config_file) def get_new_release_version_from_branch_name() -> str: git_branch = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip().decode() return git_branch -def replace_version_in_files(files : list, new_release_version: str): - if files is None: - print("Error: No Files found!") - return - for file in files: - replace_version_in_file(file,new_release_version) +def create_files_to_update_list(config): + files_to_update = [] + for filename, replacements in config.items(): + for replacement in replacements: + files_to_update.append( + FileTypeCombinationToUpdate( + filename, + replacement["type"], + replacement["regex"] if isinstance(replacement["regex"], list) else [replacement["regex"]], + replacement.get("format", None), + ) + ) + return files_to_update -def replace_version_in_file(file: FileWithVersionToUpdate,new_release_version: str): - with open(file.location, 'r') as input_file: - input_text = input_file.read() - output_text = re.sub(file.version_regex, rf'\g<1>{new_release_version}\g<3>', input_text) - print(f"Info: Replaced version with '{new_release_version}' in file '{file.location}'.") +def locate_files_in_current_project(files: list): + located_files = [] + for current_file in files: + file_location = find_file(current_file.filename, ".") + if file_location is not None: + current_file.set_file_location(file_location) + located_files.append(current_file) + else: + print(f"Warning: File '{current_file.filename}' not found.") + return located_files - with open(file.location, 'w') as output_file: - output_file.write(output_text) -def replace_date_in_files(files : list, new_release_date: str): +def find_file(name, path="."): + for root, dirs, files in os.walk(path): + if name in files: + print(f"Info: Found '{name}' in {root}.") + return os.path.join(root, name) + return None + + +def replace_content_in_files(files: list, new_release_version: str, new_date: datetime): if files is None: - print("Error: No Files found!") + print("Error: No files found!") return - for file in files: - replace_date_in_file(file,new_release_date) + for FileTypeCombination in files: + if FileTypeCombination.content_type == "version": + replace_version_in_file(FileTypeCombination, new_release_version) + elif FileTypeCombination.content_type == "date": + replace_date_in_file(FileTypeCombination, new_date) + -def replace_date_in_file(file: FileWithVersionToUpdate, new_date: str): +def replace_version_in_file(file: FileTypeCombinationToUpdate, new_release_version: str): with open(file.location, 'r') as input_file: input_text = input_file.read() - #output_text = re.sub(file.date_regex, rf'\g<1>{new_date.strftime(file.format)}\g<3>', input_text) #see https://www.programiz.com/python-programming/datetime#:~:text=Python%20format%20datetime&text=It%27s%20more%20common%20to%20use,()%20methods%20to%20handle%20this. - output_text = re.sub(file.date_regex, rf'\g<1>{new_date}\g<3>', input_text) - print(f"Info: Replaced date with '{new_date}' in file '{file.location}'.") + for regex in file.regex_list: + input_text = re.sub(regex, rf'\g<1>{new_release_version}\g<3>', input_text) + + print(f"Info: Replaced version with '{new_release_version}' in file '{file.location}'.") with open(file.location, 'w') as output_file: - output_file.write(output_text) - -def get_file_to_update_version_list(): - file_list = [] - file_list.append(FileWithVersionToUpdate('package.json', r'("version":\s*")([\d\.]+.*)(")')) - file_list.append(FileWithVersionToUpdate('sushi-config.yaml', r'(version:\s*")(\d+\.\d+\.\d+.*)(")')) - file_list.append(FileWithVersionToUpdate('sushi-config.yaml', r'(version:\s*)(\d+\.\d+\.\d+.*)()')) - file_list.append(FileWithVersionToUpdate('ruleset.fsh', r'(\*\s*version\s*=\s*")([\d\.]+.*)(")')) - file_list.append(FileWithVersionToUpdate('ruleset.fsh', r'(\*\s*\^version\s*=\s*")([\d\.]+.*)(")')) - file_list.append(FileWithVersionToUpdate('Einfuehrung.md', r'(Version: \s*)(\d+\.\d+\.\d+.*)()')) - file_list.append(FileWithVersionToUpdate('ImplementierungsleitfadenIsiK_basismodul.json', r'("version":\s*")([\d\.]+.*)(")')) - file_list.append(FileWithVersionToUpdate('ImplementierungsleitfadenIsiK_Terminplanung.json', r'("version":\s*")([\d\.]+.*)(")')) - return file_list - -def get_file_to_update_date_list(): - file_list = [] - #file_list.append(FileWithDateToUpdate('ruleset.fsh', r'(date\s*=\s*")(\d+\-\d+\-\d+)(")'), '%m/%d/%Y' ) - #file_list.append(FileWithDateToUpdate('Einfuehrung.md', r'(Datum: \s*)(\d+\.\d+\.\d+)()') , '%m/%d/%Y') - file_list.append(FileWithDateToUpdate('ruleset.fsh', r'(\*\s*date\s*=\s*")(\d+\-\d+\-\d+)(")')) - file_list.append(FileWithDateToUpdate('ruleset.fsh', r'(\*\s*\^date\s*=\s*")(\d+\-\d+\-\d+)(")')) - file_list.append(FileWithDateToUpdate('Einfuehrung.md', r'(Datum:\s*)(\d+\.\d+\.\d+.*)()')) - return file_list + output_file.write(input_text) -def locate_files_in_current_project(files: list): - return_list = [] - for current_file in files: - file_location = find_file(current_file.filename, ".") - if file_location is not None: - current_file.set_file_location(file_location) - return_list.append(current_file) - else: - print(f"Warning: File '{current_file.filename}' not found.") - return return_list +def replace_date_in_file(file: FileTypeCombinationToUpdate, new_date: datetime): + with open(file.location, 'r') as input_file: + input_text = input_file.read() -def find_file(name, path="."): - for root, dirs, files in os.walk(path): + for regex in file.regex_list: + input_text = re.sub(regex, rf'\g<1>{new_date.strftime(file.format)}\g<3>', input_text) - if name in files: - print(f"Info: Found '{name}' in {root}.") - return os.path.join(root, name) - return None + print(f"Info: Replaced date with '{new_date.strftime(file.format)}' in file '{file.location}'.") -def get_latest_release_tag(): - cmd = 'git describe --abbrev=0 --tags --match "v*.*.*" HEAD' - try: - output = subprocess.check_output(cmd, shell=True) - return output.decode().strip() - except subprocess.CalledProcessError: - return None + with open(file.location, 'w') as output_file: + output_file.write(input_text) def output_commit_messages_since_last_release(): latest_release_tag = get_latest_release_tag() @@ -137,15 +113,22 @@ def output_commit_messages_since_last_release(): except subprocess.CalledProcessError: print("Warning: Failed to get commit messages.") -def main(): - today = date.today() +def get_latest_release_tag(): + cmd = 'git describe --abbrev=0 --tags --match "v*.*.*" HEAD' + try: + output = subprocess.check_output(cmd, shell=True) + return output.decode().strip() + except subprocess.CalledProcessError: + return None - parser = argparse.ArgumentParser(description='Update release version number') + +def main(): + parser = argparse.ArgumentParser(description='Update release version number and date') parser.add_argument('-b', '--branch', action='store_true', help='get new version from branch name') parser.add_argument('-v', '--version', type=str, help='specify new version number') + parser.add_argument('-d', '--date', type=str, help='specify custom date for release') + parser.add_argument('-c', '--config', type=str, default='config.yaml', help='specify config file') parser.add_argument('-o', '--output', action='store_true', help='output commit messages since last release') - # TODO new argument -d if not date_time now - args = parser.parse_args() if args.version: @@ -155,16 +138,19 @@ def main(): else: parser.error('No new release version specified. Please use either -v or -b to specify the new release version.') - if args.output: - output_commit_messages_since_last_release() + if args.date: + custom_date = datetime.datetime.strptime(args.date, '%d.%m.%Y').date() + else: + custom_date = date.today() - file_to_update_version_list = get_file_to_update_version_list() - file_version_list = locate_files_in_current_project(file_to_update_version_list) - replace_version_in_files(file_version_list, new_release_version) + config_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), args.config) + config = load_config_file(config_file_path) + files_to_update = create_files_to_update_list(config) + located_files = locate_files_in_current_project(files_to_update) + replace_content_in_files(located_files, new_release_version, custom_date) - file_to_update_date_list = get_file_to_update_date_list() - file_date_list = locate_files_in_current_project(file_to_update_date_list) - replace_date_in_files(file_date_list, today) + if args.output: + output_commit_messages_since_last_release() if __name__ == "__main__": main() \ No newline at end of file