Skip to content

Commit 972b96b

Browse files
authored
Merge branch 'main' into mlin/hints-grammar
2 parents f0ce9f4 + ea178fe commit 972b96b

File tree

13 files changed

+172
-39
lines changed

13 files changed

+172
-39
lines changed

.github/workflows/CI.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@ jobs:
1515
# disabled due to test data bitrot (Apr 2023)
1616
# - skylab_bulk_rna
1717
runs-on: ubuntu-22.04
18+
env:
19+
MAXIMIZE_SPACE_TARGETS: '["viral_assemble","viral_refbased"]'
1820
steps:
1921
- name: Maximize build space
20-
uses: AdityaGarg8/remove-unwanted-software@v3
22+
uses: AdityaGarg8/remove-unwanted-software@v5
2123
with:
2224
remove-dotnet: 'true'
2325
remove-android: 'true'
2426
remove-haskell: 'true'
2527
remove-codeql: 'true'
26-
if: ${{ matrix.ci_target == 'viral_assemble' }}
28+
remove-docker-images: 'true'
29+
remove-large-packages: 'true'
30+
remove-cached-tools: 'true'
31+
if: ${{ contains(fromJson(env.MAXIMIZE_SPACE_TARGETS), matrix.ci_target) }}
2732
- name: Login to GitHub Packages Docker Registry
2833
uses: docker/login-action@v1
2934
with:

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,9 @@ Feedback and contributions to miniwdl are welcome, via issues and pull requests
5656
## Security
5757

5858
Please disclose security issues responsibly by contacting [email protected].
59+
60+
## Code of Conduct
61+
62+
This project adheres to the Contributor Covenant [code of conduct](https://github.com/chanzuckerberg/.github/blob/master/CODE_OF_CONDUCT.md).
63+
By participating, you are expected to uphold this code.
64+
Please report unacceptable behavior to [[email protected]](mailto:[email protected]).

SECURITY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## Reporting Security Issues
2+
If you believe you have found a security issue, please responsibly disclose by contacting us at [[email protected]](mailto:[email protected]).

WDL/CLI.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,13 @@ def __call__(self, parser, namespace, values, option_string=None):
142142
else:
143143
print("miniwdl version unknown")
144144

145-
# show plugin versions
146-
# importlib_metadata doesn't seem to provide EntryPoint.dist to get from an entry point to
147-
# the metadata of the package providing it; continuing to use pkg_resources for this. Risk
148-
# that they give inconsistent results?
149-
import pkg_resources # type: ignore
145+
import importlib_metadata
150146

151147
for group in runtime.config.default_plugins().keys():
152148
group = f"miniwdl.plugin.{group}"
153-
for plugin in pkg_resources.iter_entry_points(group=group):
154-
print(f"{group}\t{plugin}\t{plugin.dist}")
149+
for plugin in importlib_metadata.entry_points(group=group):
150+
plugin_info = f"{plugin.dist.name} {plugin.dist.version}"
151+
print(f"{group}\t{plugin.name} = {plugin.value}\t{plugin_info}")
155152
sys.exit(0)
156153

157154

@@ -1125,11 +1122,7 @@ def runner_input_json_file(available_inputs, namespace, input_file, downloadable
11251122
elif input_file == "-":
11261123
input_json = sys.stdin.read()
11271124
else:
1128-
input_json = (
1129-
asyncio.get_event_loop()
1130-
.run_until_complete(make_read_source(False)(input_file, [], None))
1131-
.source_text
1132-
)
1125+
input_json = asyncio.run(make_read_source(False)(input_file, [], None)).source_text
11331126
input_json = YAML(typ="safe", pure=True).load(input_json)
11341127
if not isinstance(input_json, dict):
11351128
raise Error.InputError("check JSON input; expected top-level object")
@@ -1756,7 +1749,7 @@ def configure(cfg=None, show=False, force=False, **kwargs):
17561749
die("`miniwdl configure` is for interactive use")
17571750

17581751
from datetime import datetime
1759-
import bullet # type: ignore
1752+
import questionary # type: ignore
17601753
from xdg import XDG_CONFIG_HOME
17611754

17621755
miniwdl_version = pkg_version()
@@ -1774,11 +1767,12 @@ def configure(cfg=None, show=False, force=False, **kwargs):
17741767
cfg = os.path.join(XDG_CONFIG_HOME, "miniwdl.cfg")
17751768

17761769
def yes(prompt):
1777-
return bullet.Bullet(prompt=prompt, choices=["No", "Yes"]).launch() == "Yes"
1770+
answer = questionary.confirm(prompt, qmark="").unsafe_ask()
1771+
return bool(answer)
17781772

17791773
if os.path.exists(cfg):
17801774
assert force
1781-
logger.warn("Proceeding will overwrite existing configuration file at " + cfg)
1775+
logger.warning("Proceeding will overwrite existing configuration file at " + cfg)
17821776
sys.stderr.flush()
17831777
if not yes("OVERWRITE?"):
17841778
sys.exit(0)
@@ -1803,9 +1797,9 @@ def yes(prompt):
18031797
print("\nCall cache JSON file storage directory: ~/.cache/miniwdl/")
18041798

18051799
if yes("OVERRIDE?"):
1806-
options["call_cache"]["dir"] = bullet.Input(
1807-
prompt="Call cache directory: ", strip=True
1808-
).launch()
1800+
options["call_cache"]["dir"] = (
1801+
questionary.text("Call cache directory: ").unsafe_ask().strip()
1802+
)
18091803

18101804
print(
18111805
textwrap.dedent(
@@ -1822,9 +1816,10 @@ def yes(prompt):
18221816
print("\nDownload cache directory: /tmp/miniwdl_download_cache")
18231817

18241818
if yes("OVERRIDE?"):
1825-
options["download_cache"]["dir"] = bullet.Input(
1826-
prompt="Download cache directory: ", strip=True
1827-
).launch()
1819+
# use questionary text prompt for directory input
1820+
options["download_cache"]["dir"] = (
1821+
questionary.text("Download cache directory: ").unsafe_ask().strip()
1822+
)
18281823

18291824
print()
18301825
if yes("Configure non-public Amazon s3:// access?"):
@@ -1854,7 +1849,8 @@ def yes(prompt):
18541849
print(cfg_content)
18551850
print()
18561851
sys.stdout.flush()
1857-
os.makedirs(os.path.dirname(cfg), exist_ok=True)
1852+
if dn := os.path.dirname(cfg):
1853+
os.makedirs(dn, exist_ok=True)
18581854
with open(cfg, "w") as outfile:
18591855
print(
18601856
f"# miniwdl configure {miniwdl_version or '(version unknown)'} {datetime.utcnow()}Z",

WDL/Expr.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ class Struct(Base):
786786
"""
787787
:type: Optional[str]
788788
789-
In WDL 2.0+ each struct literal may specify the intended struct type name.
789+
In WDL 1.1+ each struct literal may specify the intended struct type name.
790790
"""
791791

792792
def __init__(
@@ -818,7 +818,7 @@ def children(self) -> Iterable[SourceNode]:
818818
def _infer_type(self, type_env: Env.Bindings[Type.Base]) -> Type.Base:
819819
object_type = Type.Object({k: v.type for k, v in self.members.items()})
820820
if not self.struct_type_name:
821-
# pre-WDL 2.0: object literal with deferred typechecking
821+
# pre-WDL 1.1: object literal with deferred typechecking
822822
return object_type
823823

824824
# resolve struct type
@@ -839,6 +839,16 @@ def _infer_type(self, type_env: Env.Bindings[Type.Base]) -> Type.Base:
839839
self, struct_type, object_type, exn.args[0] if exn.args else ""
840840
)
841841

842+
# but object_type.check() allows extra members in WDL 1.2
843+
for member in self.members:
844+
if member not in struct_type.members:
845+
raise Error.StaticTypeMismatch(
846+
self,
847+
struct_type,
848+
object_type,
849+
f"no such member '{member}' in struct {self.struct_type_name}",
850+
)
851+
842852
return struct_type
843853

844854
def _eval(self, env: Env.Bindings[Value.Base], stdlib: StdLib.Base) -> Value.Base:

WDL/Tree.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,10 @@ class Task(SourceNode):
266266
""":type: Dict[str,WDL.Expr.Base]
267267
268268
``runtime{}`` section, with keys and corresponding expressions to be evaluated"""
269+
requirements: Dict[str, Expr.Base]
270+
""":type: Dict[str,WDL.Expr.Base]
271+
272+
``requirements{}`` section (for WDL 1.2+ tasks; refers to same dict as ``runtime``)"""
269273
meta: Dict[str, Any]
270274
""":type: Dict[str,Any]
271275
@@ -297,6 +301,7 @@ def __init__(
297301
self.outputs = outputs
298302
self.parameter_meta = parameter_meta
299303
self.runtime = runtime
304+
self.requirements = self.runtime
300305
self.meta = meta
301306
self.effective_wdl_version = "1.0" # overridden by Document.__init__
302307
# TODO: enforce validity constraints on parameter_meta and runtime
@@ -1588,7 +1593,7 @@ def _load(
15881593
import_max_depth: int = 10,
15891594
importer: Optional[Document] = None,
15901595
) -> Document:
1591-
return asyncio.get_event_loop().run_until_complete(
1596+
return asyncio.run(
15921597
_load_async(
15931598
uri,
15941599
path=path,

WDL/Value.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,11 +561,19 @@ def from_json(type: Type.Base, value: Any) -> Base:
561561
return String(value)
562562
if isinstance(type, Type.Array) and isinstance(value, list):
563563
return Array(type.item_type, [from_json(type.item_type, item) for item in value])
564-
if isinstance(type, Type.Pair) and isinstance(value, dict) and set(value) == {"left", "right"}:
564+
if (
565+
isinstance(type, Type.Pair)
566+
and isinstance(value, dict)
567+
and set(v.lower() for v in value.keys()) == {"left", "right"}
568+
):
569+
lowercased_value = {k.lower(): v for k, v in value.items()}
565570
return Pair(
566571
type.left_type,
567572
type.right_type,
568-
(from_json(type.left_type, value["left"]), from_json(type.right_type, value["right"])),
573+
(
574+
from_json(type.left_type, lowercased_value["left"]),
575+
from_json(type.right_type, lowercased_value["right"]),
576+
),
569577
)
570578
if (
571579
isinstance(type, Type.Map)

WDL/_grammar.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
?task_section: task_input_decls
6565
| output_decls
6666
| meta_section
67-
| runtime_section
67+
| requirements_section
6868
| hints_section
6969
| task_env_decl -> noninput_decl
7070
@@ -87,8 +87,8 @@
8787
| "[" [meta_value ("," meta_value)*] ","? "]" -> meta_array
8888
!meta_section: ("meta" | "parameter_meta") meta_object
8989
90-
// task runtime section (key-expression pairs)
91-
runtime_section: ("runtime" | "requirements") "{" [runtime_kv (","? runtime_kv)*] "}"
90+
// task requirements section (key-expression pairs); some mixing with vestigial (pre-1.2) "runtime" terminology
91+
requirements_section: ("requirements" | "runtime") "{" [runtime_kv (","? runtime_kv)*] "}"
9292
runtime_kv: CNAME ":" expr
9393
9494
// hints section

WDL/_parser.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,17 @@ def runtime_section(self, meta, items):
396396
d[k] = v
397397
return {"runtime": d}
398398

399+
def requirements_section(self, meta, items):
400+
d = dict()
401+
assert all(isinstance(item, tuple) and len(item) == 2 for item in items)
402+
for k, v in items:
403+
if k in d:
404+
raise Error.MultipleDefinitions(
405+
self._sp(meta), "duplicate keys in requirements section"
406+
)
407+
d[k] = v
408+
return {"runtime": d}
409+
399410
def hints_section(self, meta, items):
400411
return {"hints": items[0]}
401412

@@ -407,8 +418,10 @@ def task(self, meta, items):
407418
if k == "noninput_decl":
408419
d["noninput_decls"].append(v)
409420
elif k in d:
421+
if k == "runtime":
422+
k = "requirements/runtime"
410423
raise Error.MultipleDefinitions(
411-
self._sp(meta), "redundant sections in task"
424+
self._sp(meta), f"redundant {k} sections in task"
412425
)
413426
else:
414427
d[k] = v

WDL/runtime/config_templates/default.cfg

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ flock = true
209209

210210
[download_aria2c]
211211
# see: https://github.com/chanzuckerberg/miniwdl/tree/main/tools_image
212-
docker = ghcr.io/miniwdl-ext/miniwdl-tools:Id_sha256_93faaef93f05d4bc101d45f3218392fde55701d3ff2ad38967a0a62e408749ec
212+
docker = ghcr.io/miniwdl-ext/miniwdl-tools:Id_sha256_d18297a683804ebc63cfd662ca0362b5a323be33c834272bb9b71dd438c44bc8
213213

214214

215215
[download_awscli]
@@ -222,14 +222,14 @@ docker = ghcr.io/miniwdl-ext/miniwdl-tools:Id_sha256_93faaef93f05d4bc101d45f3218
222222
# Failing all of the above, public S3 URIs can always be used.
223223
host_credentials = false
224224
# see: https://github.com/chanzuckerberg/miniwdl/tree/main/tools_image
225-
docker = ghcr.io/miniwdl-ext/miniwdl-tools:Id_sha256_93faaef93f05d4bc101d45f3218392fde55701d3ff2ad38967a0a62e408749ec
225+
docker = ghcr.io/miniwdl-ext/miniwdl-tools:Id_sha256_d18297a683804ebc63cfd662ca0362b5a323be33c834272bb9b71dd438c44bc8
226226

227227

228228
[download_gsutil]
229229
# current version:
230230
# docker pull gcr.io/google.com/cloudsdktool/cloud-sdk:slim
231231
# docker run gcr.io/google.com/cloudsdktool/cloud-sdk:slim gcloud version
232-
docker = gcr.io/google.com/cloudsdktool/cloud-sdk:517.0.0-slim
232+
docker = gcr.io/google.com/cloudsdktool/cloud-sdk:543.0.0-slim
233233

234234

235235
[call_cache]

0 commit comments

Comments
 (0)