Skip to content

Commit a5f2ecd

Browse files
committed
docs: address review feedback on module specification
Incorporates reviewer feedback and self-review fixes across both specifications and the JSON schemas: - Reinstate the import version-compatibility rule dropped by the `Import Statements` rewrite and cross-reference it from resolution. - Define scope propagation: names merged by forms 2 and 3 become members of the document's namespace; form 1 namespaces do not propagate. Add duplicate-name rules with same-declaration merging. - Rewrite the entrypoint curation example around the scope-merging forms and clarify form 1's role in an entrypoint. - Remove the `version` field from `module.json` and lockfile entries; Git tags are the sole source of module versions, with a required `v` prefix. Define partial version requirements and `0.x` caret semantics. - Require refusal when a previously signed module resolves without `module.sig`. - Exclude `.git` from content hashing and forbid symbolic links. - Drop `checksum`/`signer` from local path lockfile entries. - Normalize hyphens in sub-path components as for dependency names. - Define module identity for cycle detection as source coordinates. - Rename tools `homepage` to `url` and add a `links` map; clarify `exclude`, `readme`, lockfile scoping, and packaging notes. - Link the changelog entries to the pull request and fix schema `$id` URLs and dead anchors.
1 parent feadb49 commit a5f2ecd

5 files changed

Lines changed: 118 additions & 85 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ Keep the changelog pleasant to read in the text editor:
2020
version 1.4.0
2121
---------------------------
2222

23-
+ Added a module specification and ecosystem. A new peer specification at [`modules/SPEC.md`](modules/SPEC.md) defines the `module.json` manifest, dependency resolution, `module-lock.json`, content hashing, module signing, credential management, and engine tooling expectations.
23+
+ Added a module specification and ecosystem. A new peer specification at [`modules/SPEC.md`](modules/SPEC.md) defines the `module.json` manifest, dependency resolution, `module-lock.json`, content hashing, module signing, credential management, and engine tooling expectations. ([#765](https://github.com/openwdl/wdl/pull/765))
2424

25-
+ Reserved the `from` keyword. Earlier `version` declarations continue to parse `from` as an ordinary identifier.
25+
+ Reserved the `from` keyword. Earlier `version` declarations continue to parse `from` as an ordinary identifier. ([#765](https://github.com/openwdl/wdl/pull/765))
2626

27-
+ Added two new import forms alongside the existing one. `import * from <source>` brings every task, workflow, and user-defined type from `<source>` into the importing document's scope. `import { <member> [as <Name>], ... } from <source>` brings only the listed items, with an optional per-member `as <Name>` rename. A `<source>` is either a quoted URI or an unquoted symbolic module path resolved through the consuming module's `module.json`.
27+
+ Added two new import forms alongside the existing one. `import * from <source>` brings every task, workflow, and user-defined type from `<source>` into the importing document's scope. `import { <member> [as <Name>] (, <member> [as <Name>])* [,] } from <source>` brings only the listed items, with an optional per-member `as <Name>` rename. A `<source>` is either a quoted URI or an unquoted symbolic module path resolved through the consuming module's `module.json`. ([#765](https://github.com/openwdl/wdl/pull/765))
2828

2929
version 1.3.0
3030
---------------------------

SPEC.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3905,7 +3905,7 @@ This demonstrates that `~{verbosity}` produces the choice name "Info", while `~{
39053905

39063906
Although a WDL workflow and the task(s) it calls may be defined completely within a single WDL document, splitting them across multiple documents can be beneficial for modularity and code reuse. Furthermore, complex workflows consisting of multiple subworkflows must be defined across multiple documents because each document is allowed at most one workflow.
39073907

3908-
The `import` statement is the basis for modularity in WDL. A document may contain any number of `import` statements. An import names a source and selects which of the source's items enter the importing document's scope. A source is either a quoted URI (see [Import URIs](#import-uris)) or ✨ an unquoted symbolic module path resolved through the consuming module's `module.json` per the [WDL Module Specification](modules/SPEC.md). The three available forms are described in [✨ Import Forms](#-import-forms).
3908+
The `import` statement is the basis for modularity in WDL. A document may contain any number of `import` statements. An import names a source and selects which of the source's items enter the importing document's scope. A source is either a quoted URI (see [Import URIs](#import-uris)) or ✨ an unquoted symbolic module path resolved through the consuming module's `module.json` per the [WDL Module Specification](modules/SPEC.md). The three available forms are described in [✨ Import Forms](#-import-forms). Regardless of source style and form, the imported document must be a WDL document **with the same major version and a minor version less than or equal to the minor version of the importing document**.
39093909

39103910
```wdl
39113911
import "http://example.com/lib/analysis_tasks" as analysis
@@ -3929,14 +3929,18 @@ workflow wf {
39293929

39303930
### ✨ Import Forms
39313931

3932-
An import statement takes one of three forms. Every form accepts the same two source styles, and the source style affects only how the build system locates the imported document.
3932+
An import statement takes one of three forms. Every form accepts the same two source styles, and the source style affects only how the execution engine locates the imported document.
39333933

39343934
1. `import <source> [as <alias>] (alias <Old> as <New>)*`. User-defined types (structs and enums) from `<source>` are copied into the importing document's scope. Tasks and workflows from `<source>` are accessible only through the import's namespace, which defaults to the filename minus the `.wdl` extension for a quoted URI or to the last component of the path for a symbolic module path. `as <alias>` overrides the default namespace; `alias <Old> as <New>` renames a struct or enum as it is copied. `alias` cannot rename tasks or workflows. See [Fully Qualified Names & Namespaced Identifiers](#fully-qualified-names--namespaced-identifiers) for how the namespace is used.
39353935
2. `import * from <source>`. Every task, workflow, and user-defined type from `<source>` enters the importing document's scope. No namespace is introduced.
3936-
3. `import { <member> [as <Name>], ... } from <source>`. Only the listed items enter the importing document's scope. A per-member `as <Name>` renames the selected item locally. A trailing comma after the last member is permitted. No namespace is introduced.
3936+
3. `import { <member> [as <Name>] (, <member> [as <Name>])* [,] } from <source>`. Only the listed items enter the importing document's scope. A per-member `as <Name>` renames the selected item locally. A trailing comma after the last member is permitted. No namespace is introduced.
39373937

39383938
Forms 2 and 3 do not accept a trailing `as <alias>` or `alias` clause.
39393939

3940+
Names brought into a document's scope by forms 2 and 3—like user-defined types copied in by form 1—become members of that document's namespace and are visible to importers of that document exactly as if they were defined locally. The namespace created by form 1 is not itself a member of the importing document's namespace: tasks and workflows reachable only through a form 1 namespace do not propagate to downstream importers, and hierarchical namespaces cannot be constructed through chained imports.
3941+
3942+
Forms 2 and 3 must not introduce duplicate names into the importing document's scope. A task or workflow name brought in by a scope-merging import that collides with a local declaration, with a name brought in by another import, or with a namespace identifier introduced by a form 1 import is an error—unless the colliding names denote the same underlying declaration in the same resolved source document, in which case they refer to that single declaration and no error is raised. This mirrors the rule for identical struct definitions and keeps diamond-shaped import graphs—two documents that each re-export the same shared file—usable without renames. Genuine conflicts are resolved with form 3's `as <Name>` rename or by selecting fewer members. User-defined types follow the rules in [Importing and Aliasing Structs](#importing-and-aliasing-structs): identical definitions may coexist; conflicting definitions require an alias.
3943+
39403944
A `<source>` is either a quoted URI or an unquoted symbolic module path. A quoted URI (e.g., `"foo.wdl"`, `"https://example.com/lib.wdl"`) resolves per [Import URIs](#import-uris). A symbolic module path takes the form `<dep>[/<sub-path>]` and resolves through the consuming module's `module.json` per the [WDL Module Specification](modules/SPEC.md). The two source styles produce identical scoping in every form; once resolved, they are interchangeable.
39413945

39423946
A symbolic module path is a sequence of `/`-separated components. Each component must be a valid WDL identifier. Empty components, leading or trailing `/`, `.`, `..`, whitespace, null bytes, and any other character not permitted in a WDL identifier are themselves not permitted in a symbolic module path. A document containing an import whose symbolic path violates this grammar is malformed.
@@ -3948,6 +3952,7 @@ version 1.4
39483952
39493953
import "csvkit.wdl" # tasks via `csvkit` namespace; structs/enums in scope
39503954
import "csvkit.wdl" as csv # tasks via `csv` namespace; structs/enums in scope
3955+
import "csvkit.wdl" alias CsvConfig as CsvkitConfig # rename an imported struct or enum
39513956
import * from "csvkit.wdl" # tasks, workflows, structs, enums all in scope
39523957
import { CsvSort } from "csvkit.wdl" # only `CsvSort` in scope
39533958
import { CsvSort as MySort, CsvSortStable } from "csvkit.wdl" # `MySort` and `CsvSortStable` in scope

0 commit comments

Comments
 (0)