Stream: shorthand
Topic: SUSHI Configuration
Chris Moesel (Feb 28 2020 at 20:36):
SUSHI currently uses the following files for configuration: package.json
, ig-data/ig.ini
, and ig-data/package-list.json
. Despite using three different config files, SUSHI still provides no way for the user to supply custom configuration that would go into the ImplementationGuide
instance representing the IG. Rather than add a fourth place to put configuration, we propose replacing these all with a single config file.
The idea is that this config would be loosely based on the ImplementationGuide
resource, but also provide the necessary aspects of the other files (ig.ini
, package-list.json
) and other concerns like defining the menu. In other words, it's a one-stop-shop for all config SUSHI needs. For ease of use, this file would be written using YAML, would streamline some of the more verbose syntaxes of ImplementationGuide
, and would allow for "sparse" sections where SUSHI can insert generated content when building the IG source.
I've pasted a proposed annotated version of this file below. Note that a minimal config would likely contain about 10 key properties, but we show more in the file below to demonstrate the possible entries. Also note that we plan to implement a command in sushi to initialize a project and generate a configuration file with default values that authors would then edit. We welcome any and all feedback!
# This IG YML file is inspired by the ImplementationGuide resource # and also draws from package.json, package-list.json, and ig.ini. # That said, it is structured for ease-of-use, so it is not strictly # conformant to any of those existing configuration formats. # SUSHI will use id as both id and packageId in the IG unless a # specific packageId is also provided in this file. id: fhir.us.mcode url: http://hl7.org/fhir/us/mcode name: mCODE IG title: "HL7 FHIR Implementation Guide: minimal Common Oncology Data Elements (mCODE) Release 1 - US Realm | STU1" description: mCODE™ (short for Minimal Common Oncology Data Elements) is an initiative intended to assemble a core set of structured data elements for oncology electronic health records. status: active license: CC0-1.0 date: 2020-02-26 version: 1.0.0 # Although fhirVersions is 0..* in the ImplementationGuide resource # it can be a single item OR and array here (but so far SUSHI only # support 4.0.1 anyway). fhirVersion: 4.0.1 # The template property will be copied into the ig.ini file. # If the value of template is "none", then only the resources will be # generated (with no supporting ImplementationGuide sources). template: hl7.fhir.template#0.0.5 # The following two lines correspond to items that used to be in # ig.ini but were recently moved to IG.definition.parameter. For # consistency within this file, the names are represented using # camelcase, but if authors use the formal parameter names, SUSHI # will recognize them as well. In either case, they'll be copied # to the IG JSON using the formal names. copyrightYear: 2019+ releaseLabel: STU1 # The publisher can be a single item or a list, each with a name and # optional url and/or email. The first publisher's name will be used # as IG.publisher. The contact details and/or additional publishers # will be translated into IG.contact values. publisher: name: HL7 International Clinical Interoperability Council url: http://www.hl7.org/Special/committees/cic email: ciclist@lists.HL7.org # Those who need more control or want to add additional details # to the contact values can use contact directly and follow the # format outlined in the ImplementationGuide resource and # ContactDetail. E.g., # contact: # - name: Bob Smith # - telecom: # system: email # value: bobsmith@example.org # use: work # The jurisdiction can be a single item or a list. The FHIR Shorthand # code syntax can be used here. jurisdiction: urn:iso:std:iso:3166#US "United States of America" # The dependencies property corresponds to IG.dependsOn. They key is the # package id and the value is the version (or dev/current). dependencies: hl7.fhir.us.core: 3.1.0 # The global property corresponds to the IG.global property, but it # uses the type as the YAML key and the profile as its value. Since # FHIR does not explicitly disallow more than one profile per type, # neither do we; the value can be a single profile URL or an array # of profile URLs. global: Patient: http://example.org/fhir/StructureDefinition/my-patient-profile Encounter: http://example.org/fhir/StructureDefinition/my-encounter-profile # The resources property corresponds to IG.definition.resource. # SUSHI can auto-generate all of the resource entries based on # the FSH definitions and/or information in any user-provided # JSON resource files. If the generated entries are not # sufficient or complete, however, the author can add entries # here. If the reference matches a generated entry, it will # replace the generated entry. If it doesn't match any generated # entries, it will be added to the generated entries. The format # follows IG.definition.resource with the following differences: # * use IG.definition.resource.reference.reference as the YAML key # * specify "omit" to omit a FSH-generated resource from the # resource list. # * groupingId can be used, but top-level groups syntax may be a # better option (see below). # The following are simple examples to demonstrate what this might # look like: resources: Patient/my-example-patient: name: My Example Patient description: An example Patient exampleBoolean: true Patient/bad-example: omit # Groups can control certain aspects of the IG generation. The IG # documentation recommends that authors use the default groups that # are provided by the templating framework, but if authors want to # use their own instead, they can use the mechanism below. This will # create IG.definition.grouping entries and associate the individual # resource entries with the corresponding groupIds. groups: GroupA: description: The Alpha Group resources: - StructureDefinition/animal-patient - StructureDefinition/arm-procedure GroupB: description: The Beta Group resources: - StructureDefinition/bark-control - StructureDefinition/bee-sting # The pages property corresponds to IG.definition.page. SUSHI can # auto-generate the page list, but if the author includes pages in # this file, it is assumed that the author will fully manage the # pages section and SUSHI will not generate any page entries. # The page file name is used as the key. If title is not provided, # then the title will be generated from the file name. If a # generation value is not provided, it will be inferred from the # file name extension. Any subproperties that are valid filenames # with supported extensions (e.g., .md/.xml) will be treated as # sub-pages. pages: index.md: title: mCODE Home implementation.xml: examples.xml: title: Examples Overview simpleExamples.xml: complexExamples.xml: # The menu property will be used to generate the input/menu.xml file. # The menu is represented as a simple structure where the YAML key # is the menu item name and the value is the URL. The IG publisher # currently only supports one level deep on sub-menus. # TO CONSIDER: If no menu data is provided, can we generate the menu # based on the pages order or should we just generate a very standard # menu (since there may be too many pages to fit in a menu). menu: Home: index.html Artifacts: Profiles: artifacts.html#2 Extensions: artifacts.html#3 Value Sets: artifacts.html#4 Downloads: downloads.html History: http://hl7.org/fhir/us/mcode/history.html # The parameters property represents IG.definition.parameter. Rather # than a list of code/value pairs (as in the ImplementationGuide # resource, the code is the YAML key. If a parameter allows repeating # values, the value in the YAML should be a sequence/array. For a # partial list of allowed parameters see: # https://confluence.hl7.org/display/FHIR/Implementation+Guide+Parameters parameters: excludettl: true validation: [allow-any-extensions, no-broken-links] # The history property corresponds to package-list.json. SUSHI will # use the existing top-level properties in its config to populate the # top-level package-list.json properties: packageId, canonical, title, # and introduction. Authors that wish to provide different values can # supply them as properties under history. All other properties under # history are assumed to be versions. history: # The current version is special. If the author provides only a # single value, it is assumed to be the URL path to the current # build. The following default values will then be used: # desc: Continuous Integration Build (latest in version control) # status: ci-build # current: true current: http://build.fhir.org/ig/HL7/fhir-mCODE-ig/ # All other versions need each of their values fully specified. # See: https://confluence.hl7.org/pages/viewpage.action?pageId=66928420#FHIRIGPackageListdoco-PublicationObject 1.0.0: fhirversion: 4.0.1 date: 2020-03-06 desc: STU 1 Release path: https://hl7.org/fhir/us/mcode/STU1/ status: trial-use sequence: STU 1 current: true 0.9.1: fhirversion: 4.0.0 date: 2019-06-10 desc: Initial STU ballot (Sep 2019 Ballot) path: https://hl7.org/fhir/us/mcode/2019Sep/ status: ballot sequence: STU 1 # The ImplementationGuide resource defines several other properties # not represented above. These properties can be used as-is and # should follow the format defined in ImplementationGuide: # * experimental # * useContext # * copyright # * definition.template (but use a top-level "templates" property)
Jens Villadsen (Feb 28 2020 at 21:13):
Keith Boone (Feb 28 2020 at 21:22):
+1 on use of YAML
David Hay (Feb 29 2020 at 18:22):
I do like the idea of one config file to rule them all...
David Hay (Feb 29 2020 at 19:32):
I also use the IG resource for my own stuff so would be nice use a similar format to define them. In particular, what about extensions? for example:
resources: Patient/my-example-patient: name: My Example Patient description: An example Patient exampleBoolean: true extension: http://clinfhir.com/StructureDefinition/igEntryType: logical Patient/my-nextexample-patient: name: My Example Patient description: An example Patient exampleBoolean: true
Would work for strings (which is all I use) - not sure about other datatypes
David Hay (Feb 29 2020 at 21:54):
BTW - why is 'title' (in the example) quoted?
Mint Thompson (Mar 01 2020 at 18:34):
The title is quoted because it contains a :
character followed by a space, so it has to be escaped by quoting the whole string.
David Hay (Mar 01 2020 at 18:54):
but so is description...
Chris Moesel (Mar 01 2020 at 21:01):
Hi @David Hay -- as @Mint Thompson noted, the reason title is quoted is due to how YAML is parsed. Since the title contains a :
, we need to quote it, else YAML can't parse it correctly. I'm not sure what you mean by, "but so is description" -- but I'll also note that YAML does understand URLs -- so when a URL contains :
(as they all do), YAML doesn't require the quotes for that.
Chris Moesel (Mar 01 2020 at 21:08):
I also use the IG resource for my own stuff so would be nice use a similar format to define them. In particular, what about extensions?
Good point, @David Hay. I hadn't thought of that, but I don't see why we couldn't (or wouldn't) support extensions. I think we'd treat the section under the resource like the IG.definition.resource
element (so since extension is allowed there, we'd allow it as well).
That brings up a question though. I said in the comment for that section of the config that if you put in a resource that matches a generated resource, your entry would override the generated entry -- but maybe in some cases, we'd want it merged? E.g., if the name
, description
, and exampleBoolean
, are generated correctly, maybe you really should only have to say this:
resources: Patient/my-example-patient: extension: http://clinfhir.com/StructureDefinition/igEntryType: logical
and since you don't supply name
, description
or example[x]
, we keep the generated values for those too.
David Hay (Mar 01 2020 at 21:23):
Ah silly me - didn't read @Mint Thompson answer correctly...
David Hay (Mar 01 2020 at 21:32):
So name
and description
come from the fsh file for the my-example-patient
instance . But where does exampleBoolean
come from? It's not in the example instance is it? Could you infer exampleCanonical from the instanceOf
element?
Chris Moesel (Mar 01 2020 at 22:21):
Currently, SUSHI treats all instances as examples, but a future version (soon) will allow the author to make the distinction between example instances and conformance instances. If an instance is an example, then it will use:
exampleCanonical
if it is an example of a profile in the IG, orexampleBoolean
otherwise.
Through trial and error, we've determined that's what the IG Publisher expects. If you set exampleCanonical
to a canonical URL for a core FHIR resource or a profile in a different IG, the publisher barks at you.
Grahame Grieve (Mar 01 2020 at 22:47):
If you set exampleCanonical to a canonical URL for a core FHIR resource or a profile in a different IG, the publisher barks at you.
That's an oversight. It should be possible to provide examples for profiles defined in other IGs
Chris Moesel (Mar 02 2020 at 01:50):
I assumed it was mainly because as best I can tell, exampleCanonical
mainly just ensures that the example shows up on the profile page's examples tab -- and that wouldn't really be relevant for profiles outside the IG. Still, I would prefer if it weren't treated as an error. (Although, to be honest, I can't remember 100% for sure that it happened with profiles in other IGs, but it definitely happened for FHIR core resources).
Amogh Thali (Mar 02 2020 at 13:31):
Hi @Chris Moesel , is there a way we can run this config file in the current version of sushi ? Executing sushi .
returns No package.json in FSH definition folder.
This is for me to play with a few resources and structure definitions and see how the IG looks. Thanks
Chris Moesel (Mar 02 2020 at 14:47):
Hi @Amogh Thali. The YAML config above is currently being proposed; we haven't implemented it yet. The current version of SUSHI still works using package.json
. You have to create your own package.json
, but here is an example to get you started:
{ "name": "myproject", "version" : "0.1.0", "canonical" : "http://example.org/fhir/myproject", "url" : "http://example.org/fhir/myproject", "title" : "My Project", "description": "A description of my project", "dependencies": { "hl7.fhir.r4.core": "4.0.1", "hl7.fhir.us.core": "3.1.0" }, "author": "Cameron Cod", "maintainers": [ { "name": "Cod Fans", "url": "http://example.org/codfans" } ], "license": "CC0-1.0" }
Last updated: Apr 12 2022 at 19:14 UTC