Skip to content

Commit 67ea3e7

Browse files
authored
Merge pull request #76 from martindurant/short-types
Add AI and publish types
2 parents 135cf58 + 6323f83 commit 67ea3e7

File tree

8 files changed

+94
-6
lines changed

8 files changed

+94
-6
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.opencode
2+
13
# Dask
24
dask-worker-space
35

src/projspec/content/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Contents classes - information declared in project specs"""
2+
13
from projspec.content.base import BaseContent
24
from projspec.content.data import FrictionlessData, IntakeSource
35
from projspec.content.env_var import EnvironmentVariables

src/projspec/proj/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
"""Project and spec classes"""
2+
13
from projspec.proj.base import ParseFailed, Project, ProjectSpec, ProjectExtra
4+
5+
from projspec.proj.ai import AIEnabled
26
from projspec.proj.briefcase import Briefcase
37
from projspec.proj.conda_package import CondaRecipe, RattlerRecipe
48
from projspec.proj.conda_project import CondaProject
@@ -11,6 +15,7 @@
1115
from projspec.proj.node import JLabExtension, Node, Yarn
1216
from projspec.proj.pixi import Pixi
1317
from projspec.proj.poetry import Poetry
18+
from projspec.proj.published import Citation, Zenodo
1419
from projspec.proj.pyscript import PyScript
1520
from projspec.proj.python_code import PythonCode, PythonLibrary
1621
from projspec.proj.rust import Rust, RustPython
@@ -22,7 +27,9 @@
2227
"ParseFailed",
2328
"Project",
2429
"ProjectSpec",
30+
"AIEnabled",
2531
"Briefcase",
32+
"Citation",
2633
"CondaRecipe",
2734
"CondaProject",
2835
"Golang",
@@ -49,4 +56,5 @@
4956
"Uv",
5057
"VSCode",
5158
"Yarn",
59+
"Zenodo",
5260
]

src/projspec/proj/ai.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from projspec.proj.base import ProjectSpec
2+
3+
4+
class AIEnabled(ProjectSpec):
5+
"""This project has text files intended for LLM/AI to read."""
6+
7+
spec_doc = "https://agents.md/"
8+
9+
def match(self) -> bool:
10+
return bool(
11+
{"AGENTS.md", "CLAUDE.md", ".specify"}.intersection(self.proj.basenames)
12+
)
13+
14+
def parse(self) -> None:
15+
pass

src/projspec/proj/base.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ def resolve(
151151
:param types: names of types to allow while parsing. If empty or None, allow all
152152
:param xtypes: names of types to disallow while parsing.
153153
"""
154-
if types and set(types) - set(registry):
154+
types = set(camel_to_snake(_) for _ in types or ())
155+
if types and types - set(registry):
155156
raise ValueError(f"Unknown types: {set(types) - set(registry)}")
156157
# sorting to ensure consistency
157158
for name in sorted(registry):
@@ -405,6 +406,7 @@ def make(self, qname: str, **kwargs):
405406
spec, artifact, name = None, qname, None
406407
else:
407408
spec, artifact, *name = qname.split(".")
409+
spec = camel_to_snake(spec)
408410
specs = [self.specs[spec]] if spec else self.specs.values()
409411
art = None
410412
for spec in specs:

src/projspec/proj/ide.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Code project container config within IDEs"""
2-
2+
from projspec.artifact import BaseArtifact
33
from projspec.proj import ProjectSpec
44

55

@@ -12,15 +12,28 @@ def match(self) -> bool:
1212
return self.proj.fs.exists(f"{self.proj.url}/.project/spec.yaml")
1313

1414
def parse(self) -> None:
15-
...
15+
from projspec.artifact.process import Process
16+
17+
# "opens" the project in the sense that it is set as the current context.
18+
# Editing still happens in jupyter/vscode/etc
19+
self.artifacts["set_project"] = Process(
20+
self.proj, cmd=["nvwb", "open", self.proj.url]
21+
)
22+
23+
# create:
24+
# https://docs.nvidia.com/ai-workbench/user-guide/latest/reference/user-interface/cli.html#create-project
1625

1726

1827
class JetbrainsIDE(ProjectSpec):
1928
def match(self) -> bool:
2029
return self.proj.fs.exists(f"{self.proj.url}/.idea")
2130

2231
def parse(self) -> None:
23-
...
32+
from projspec.artifact.process import Process
33+
34+
self.artifacts["launch"] = Process(
35+
self.proj, cmd=["pycharm", self.proj.url, "nosplash", "dontReopenProjects"]
36+
)
2437

2538

2639
class VSCode(ProjectSpec):
@@ -32,7 +45,9 @@ def match(self) -> bool:
3245
return self.proj.fs.exists(f"{self.proj.url}/.vscode/settings.json")
3346

3447
def parse(self) -> None:
35-
...
48+
from projspec.artifact.process import Process
49+
50+
self.artifacts["launch"] = Process(self.proj, cmd=["code", self.proj.url])
3651

3752

3853
class Zed(ProjectSpec):
@@ -42,4 +57,6 @@ def match(self) -> bool:
4257
return self.proj.fs.exists(f"{self.proj.url}/.zed/settings.json")
4358

4459
def parse(self) -> None:
45-
...
60+
from projspec.artifact.process import Process
61+
62+
self.artifacts["launch"] = Process(self.proj, cmd=["zed", self.proj.url])

src/projspec/proj/published.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import yaml
2+
3+
from projspec.proj.base import ProjectSpec
4+
5+
6+
class Citation(ProjectSpec):
7+
"""A github-specified format to say how this project should be cited."""
8+
9+
spec_doc = "https://citation-file-format.github.io/"
10+
11+
def match(self):
12+
return "CITATION.cff" in self.proj.basenames
13+
14+
def parse(self) -> None:
15+
from projspec.content.metadata import DescriptiveMetadata
16+
17+
with self.proj.fs.open(self.proj.basenames["CITATION.cff"], "rt") as f:
18+
meta = yaml.safe_load(f)
19+
self.contents["descriptive_metadata"] = DescriptiveMetadata(
20+
proj=self.proj, meta=meta
21+
)
22+
23+
24+
class Zenodo(ProjectSpec):
25+
"""This project has been published on Zenodo"""
26+
27+
spec_doc = "https://help.zenodo.org/docs/github/describe-software/zenodo-json/"
28+
29+
def match(self):
30+
# NB: zenodo picks up CITATION.cff too, but this format is more specific
31+
return ".zenodo.json" in self.proj.basenames
32+
33+
def parse(self) -> None:
34+
from projspec.content.metadata import DescriptiveMetadata
35+
36+
with self.proj.fs.open(self.proj.basenames[".zenodo.json"], "rt") as f:
37+
meta = yaml.safe_load(f)
38+
# TODO: extract known contents such as license.
39+
self.contents["descriptive_metadata"] = DescriptiveMetadata(
40+
proj=self.proj, meta=meta
41+
)

src/projspec/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import contextlib
22
import enum
33
import logging
4+
import os
45
import pathlib
56
import re
67
import subprocess

0 commit comments

Comments
 (0)