-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathjustfile
More file actions
275 lines (225 loc) · 9.23 KB
/
justfile
File metadata and controls
275 lines (225 loc) · 9.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# ============ Hint for for Windows Users ============
# On Windows the "sh" shell that comes with Git for Windows should be used.
# If it is not on path, provide the path to the executable in the following line.
#set windows-shell := ["C:/Program Files/Git/usr/bin/sh", "-cu"]
# ============ Variables used in recipes ============
# Load environment variables from config.public.mk or specified file
set dotenv-load := true
# set dotenv-filename := env_var_or_default("LINKML_ENVIRONMENT_FILENAME", "config.public.mk")
set dotenv-filename := x'${LINKML_ENVIRONMENT_FILENAME:-config.public.mk}'
# Set shebang line for cross-platform Python recipes (assumes presence of launcher on Windows)
shebang := if os() == 'windows' {
'py'
} else {
'/usr/bin/env python3'
}
# Environment variables with defaults
schema_name := env_var_or_default("LINKML_SCHEMA_NAME", "_no_schema_given_")
source_schema_dir := env_var_or_default("LINKML_SCHEMA_SOURCE_DIR", "")
config_yaml := if env_var_or_default("LINKML_GENERATORS_CONFIG_YAML", "") != "" {
"--config-file " + env_var_or_default("LINKML_GENERATORS_CONFIG_YAML", "")
} else {
""
}
gen_doc_args := env_var_or_default("LINKML_GENERATORS_DOC_ARGS", "")
gen_java_args := env_var_or_default("LINKML_GENERATORS_JAVA_ARGS", "")
gen_owl_args := env_var_or_default("LINKML_GENERATORS_OWL_ARGS", "")
gen_pydantic_args := env_var_or_default("LINKML_GENERATORS_PYDANTIC_ARGS", "")
gen_ts_args := env_var_or_default("LINKML_GENERATORS_TYPESCRIPT_ARGS", "")
# Directory variables
src := "src"
dest := "project"
pymodel := src / schema_name / "datamodel"
source_schema_path := source_schema_dir / schema_name + ".yaml"
docdir := "docs/elements" # Directory for generated documentation
distrib_schema_path := "docs/schema" # Directory for publishing schema artifacts
# ============== Project recipes ==============
# List all commands as default command. The prefix "_" hides the command.
_default: _status
@just --list
# Initialize a new project (use this for projects not yet under version control)
[group('project management')]
setup: _check-config _git-init install _git-add && _setup_part2
git commit -m "Initialise git with minimal project" -a || true
_setup_part2: gen-project gen-doc
@echo
@echo '=== Setup completed! ==='
@echo 'Various model representations have been created under directory "project". By default'
@echo 'they are ignored by git. You decide whether you want to add them to git tracking or'
@echo 'continue to git-ignore them as they can be regenerated if needed.'
@echo 'For tracking specific subfolders, add !project/[foldername]/* line(s) to ".gitignore".'
# Install project dependencies
[group('project management')]
install:
uv sync --group dev
# Updates project template and LinkML package
[group('project management')]
update: _update-template _update-linkml
# Clean all generated files
[group('project management')]
clean: _clean_project
rm -rf tmp
rm -rf {{docdir}}/*.md
# (Re-)Generate project and documentation locally
[group('model development')]
site: gen-project gen-doc
# Deploy documentation site to Github Pages
[group('deployment')]
deploy: site
mkd-gh-deploy
# Run all tests
[group('model development')]
test: _test-schema _test-python _test-examples
# Run linting
[group('model development')]
lint:
uv run linkml-lint {{source_schema_dir}}
# Generate md documentation for the schema and add artifacts
[group('model development')]
gen-doc: _gen-yaml && _add-artifacts
uv run gen-doc {{gen_doc_args}} -d {{docdir}} {{source_schema_path}}
# Build docs and run test server
[group('model development')]
testdoc: gen-doc _serve
# Generate the Python data models (dataclasses & pydantic)
gen-python:
uv run gen-project -d {{pymodel}} -I python {{source_schema_path}}
uv run gen-pydantic {{gen_pydantic_args}} {{source_schema_path}} > {{pymodel}}/{{schema_name}}_pydantic.py
# Generate project files including Python data model
[group('model development')]
gen-project:
uv run gen-project {{config_yaml}} -d {{dest}} {{source_schema_path}}
mv {{dest}}/*.py {{pymodel}}
uv run gen-pydantic {{gen_pydantic_args}} {{source_schema_path}} > {{pymodel}}/{{schema_name}}_pydantic.py
@# Some generators ignore config_yaml or cannot create directories, so we run them separately.
uv run gen-java {{gen_java_args}} --output-directory {{dest}}/java/ {{source_schema_path}}
@if [ ! -d "{{dest}}/typescript" ]; then \
mkdir -p {{dest}}/typescript ; \
fi
uv run gen-typescript {{gen_ts_args}} {{source_schema_path}} > {{dest}}/typescript/{{schema_name}}.ts
@if [ ! -d "{{dest}}/owl" ]; then \
mkdir -p {{dest}}/owl ; \
fi
uv run gen-owl {{gen_owl_args}} {{source_schema_path}} > "{{dest}}/owl/{{schema_name}}.owl.ttl"
# ============== Migrations recipes for Copier ==============
# Hidden command to adjust the directory layout on upgrading a project
# created with linkml-project-copier v0.1.x to v0.2.0 or newer.
# Use with care! - It may not work for customized projects.
_post_upgrade_v020: && _post_upgrade_v020py
mv docs/*.md docs/elements
_post_upgrade_v020py:
#!{{shebang}}
import subprocess
from pathlib import Path
# Git move files from folder src to folder dest
tasks = [
(Path("src/docs/files"), Path("docs")),
(Path("src/docs/templates"), Path("docs/templates-linkml")),
(Path("src/data/examples"), Path("tests/data/")),
]
for src, dest in tasks:
for path_obj in src.rglob("*"):
if not path_obj.is_file():
continue
file_dest = dest / path_obj.relative_to(src)
if not file_dest.parent.exists():
file_dest.parent.mkdir(parents=True)
print(f"Moving {path_obj} --> {file_dest}")
subprocess.run(["git", "mv", str(path_obj), str(file_dest)])
print(
"Migration to v0.2.x completed! Check the changes carefully before committing."
)
# ============== Hidden internal recipes ==============
# Show current project status
_status: _check-config
@echo "Project: {{schema_name}}"
@echo "Source: {{source_schema_path}}"
# Check project configuration
_check-config:
#!{{shebang}}
import os
schema_name = os.getenv('LINKML_SCHEMA_NAME')
if not schema_name:
print('**Project not configured**:\n - See \'.env.public\'')
exit(1)
print('Project-status: Ok')
# Update project template
_update-template:
copier update --trust --skip-answered
# Update LinkML to latest version
_update-linkml:
uv add linkml --upgrade-package linkml
# Test schema generation
_test-schema:
uv run gen-project {{config_yaml}} -d tmp {{source_schema_path}}
# Run Python unit tests with pytest
_test-python: gen-python
uv run python -m pytest
# Run example tests
_test-examples: _ensure_examples_output
uv run linkml-run-examples \
--input-formats json \
--input-formats yaml \
--output-formats json \
--output-formats yaml \
--counter-example-input-directory tests/data/invalid \
--input-directory tests/data/valid \
--output-directory examples/output \
--schema {{source_schema_path}} > examples/output/README.md
# Add the merged model to docs/schema.
_gen-yaml:
-mkdir -p {{distrib_schema_path}}
uv run gen-yaml {{source_schema_path}} > {{distrib_schema_path}}/{{schema_name}}.yaml
# Overridable recipe to add project-specific artifacts to the distribution schema path
_add-artifacts:
# Run documentation server
_serve:
uv run mkdocs serve
# Initialize git repository
_git-init:
git init
# Add files to git
_git-add:
git add .
# Commit files to git
_git-commit:
git commit -m 'chore: just setup was run' -a
# Show git status
_git-status:
git status
_clean_project:
#!{{shebang}}
import shutil, pathlib
# remove the generated project files
for d in pathlib.Path("{{dest}}").iterdir():
if d.is_dir():
print(f'removing "{d}"')
shutil.rmtree(d, ignore_errors=True)
# remove the generated python data model
for d in pathlib.Path("{{pymodel}}").iterdir():
if d.name == "__init__.py":
continue
print(f'removing "{d}"')
if d.is_dir():
shutil.rmtree(d, ignore_errors=True)
else:
d.unlink()
_ensure_examples_output: # Ensure a clean examples/output directory exists
-mkdir -p examples/output
-rm -rf examples/output/*.*
# ============== Include project-specific recipes ==============
import "project.justfile"
# ====== Override recipes from above with custom versions =======
# Uncomment the following line to allow duplicate recipe names
set allow-duplicate-recipes
# Overriding recipes from the root justfile by adding a recipe with the same
# name in an imported file is not possible until a known issue in just is fixed,
# https://github.com/casey/just/issues/2540
# Custom recipe for dcat-ap-plus to add project-specific artifacts to the distribution schema path
_add-artifacts:
@echo "Adding project-specific artifacts to {{distrib_schema_path}} for deploying to gh-pages"
for d in "{{distrib_schema_path}}"/*/; do rm -rf "$d"/; done
for d in "{{dest}}"/*/; do cp -a "$d" "{{distrib_schema_path}}"/; done
cp {{source_schema_dir}}/*.yaml {{distrib_schema_path}}/
@mkdir -p {{distrib_schema_path}}/merged-yaml
uv run gen-yaml {{source_schema_path}} > {{distrib_schema_path}}/merged-yaml/{{schema_name}}.yaml