Contributing to ipyelk#
Install#
mamba install "pixi==0.67.0"
Get Started#
git clone https://github.com/jupyrdf/ipyelk
cd ipyelk
pixi task list # that's a lot
pixi run release # this is _basically_ what happens on CI
pixi run lab # start lab
Branches#
Presently, on GitHub:
master: the2.xline, which distributes the lab extension inside the python distribution for JupyterLab>=4.2generates the
latesttag on ReadTheDocs
Important Paths#
Path |
Purpose |
|---|---|
|
Robot Framework source for acceptance tests |
|
task automation tool |
|
pinned build/test/docs environments |
|
TypeScript source for |
|
|
|
package description for |
|
Python source for |
|
JSON schema derived from the TypeScript source |
|
frozen |
|
documentation |
|
examples, used in demo and test |
|
JupyterLite demo configuration |
Run
pixi run dev-extto get ready to developMost commands are run with
pixi run release(this is what CI does)
Live Development#
You can watch the source directory and run JupyterLab in watch mode to watch for changes in the extension’s source and automatically rebuild the extension and application.
Run:
pixi run watch
Open a tab with the provided URL in a standards-compliant browser of choice
After making changes, wait for
webpackterminal output, then reload the browserIf you add a new file, probably will have to restart the whole thing
Logging#
In the browser, jupyter-elk should only emit console.warn (or higher) messages if
there’s actually a problem.
For more verbose output, add ELK_DEBUG anywhere in a new browser URL, e.g.
http://localhost:8888/lab#ELK_DEBUG
Note: if a message will be helpful for debugging, make sure to
importand guardconsole.*or higher withELK_DEBUG &&
On the python side, each Widget has .log.debug which is preferable to print
statements. The log level can be increased for a running kernel through the JupyterLab’s
Log Console, opened with the Show Log Console command.
Quality Assurance#
Run:
pixi run fix
pixi run lint
pixi run lint-mypy # run only the Python type checker
pixi run test
Ensure the
examples/work. These will be tested in CI with:nbconvert --executein JupyterLab by Robot Framework with Restart Kernel and Run All Cells
If you add new features:
Add a new, minimal demonstration notebook to the examples.
Treat each feature as a function which can be reused for other examples, with:
the example in a humane name, e.g.
a_basic_elk_examplesome suitable defaults and knobs to twiddle
Add appropriate links to your new example.
These will be picked up by
itest
Potentially add some unit
./testsAdd appropriate Robot Framework in
./atest
Ensure coverage doesn’t degrade from the
ALL_PY_COV_FAIL_UNDERbaseline in.github/ci.yml
Structural Lint Rules#
pixi run lint-ast-grep runs ast-grep with the rules in
scripts/ast-grep/rules/, after checking them against their cases in
scripts/ast-grep/rule-tests/. These catch hazards specific to this code base that
ruff, mypy and tsc do not.
Add a rule as
scripts/ast-grep/rules/<id>.ymlwith amessageand a shortnotesaying why, andscripts/ast-grep/rule-tests/<id>-test.ymlwithvalidandinvalidcasesTry a pattern with
pixi run -e lint ast-grep run -l py -p '<pattern>' srcRun only the rule tests with
pixi run -e lint ast-grep test --skip-snapshot-testsSuppress an intended finding with the rule id, and the reason on the line above; a bare
ast-grep-ignore(checked byscripts/check_suppressions.py) or one that no longer matches anything fails the lint:
// a foreignObject shape renders its `use` markup by design
// ast-grep-ignore: ts-no-html-injection
let contents = html('div', { props: { innerHTML: node?.properties?.shape?.use } });
ast-grep cannot parse notebooks, so examples/*.ipynb are not scanned. Known gaps,
accepted as unlikely: window['eval'], Reflect.apply(eval, ...) and const e = eval;
el['insertAdjacentHTML'], contentDocument.write, srcdoc and
DOMParser.parseFromString; console.log.call/.apply; and an Instance nested in
T.Tuple(...) next to a JSON one.
Prose#
Vale lints the prose in the root *.md files, docs/, docstrings
and comments in src/, tests/ and scripts/, and notebook markdown cells, in US
English, with the proselint and write-good styles. Any warning or error fails
pixi run lint. To run it alone:
pixi run lint-vale
Findings in notebooks point at build/nblint/examples/<notebook>/cell-<n>.md, the
markdown of the n-th cell.
Fix real typos. Vale doesn’t spell-check hyphenated words (e.g.
re-serialisedpasses), so check those by eye.Add a project term (a name, an API word) to
scripts/vale/config/vocabularies/IPyElk/accept.txt, one per line. Entries are regular expressions, andVale.Termsalso enforces their case: write a lowercase word as[Ww]ordso it may start a sentence, or prefix(?i)to accept any case.In markdown, turn a rule off for one passage, with the reason:
<!-- vale proselint.Very = NO -->
<!-- quoting the upstream docs verbatim -->
It is very fast.
<!-- vale proselint.Very = YES -->
In Python, Vale has no inline switch, and it can’t skip RST literals for
Vale.Terms. Add the exact phrase to the vocabulary (e.g.package\.jsonstopsjsonin it from being flagged), or turn the rule off for that file invale.iniin a[**/file.py]section (the**/also covers the module docstring’s copy underbuild/vale_docstrings/), with a one-line comment giving the reason.Turn a rule off everywhere in
vale.ini, with a one-line comment giving the reason.
Limiting Testing#
To run just some acceptance tests, add something like:
*** Test Cases ***
Some Test
[Tags] some:tag
...
Then run:
ATEST_ARGS="--exclude NOTsome:tag" pixi run atest-robot
Pipeline Benchmark#
CI runs pixi run bench-check: it benchmarks Diagram.refresh() headlessly with
scripts/bench_pipeline.py and compares the deterministic counts (comm opens, messages
and bytes in both directions, layouts) to scripts/bench_baseline.json. Any change
fails, in either direction. If the change is intended, run pixi run bench-update and
commit the baseline, so the diff shows reviewers what got cheaper or more expensive.
Timings are written to the job summary but not gated.
Building Documentation#
To build (and check the link health) of what would go to ipyelk.readthedocs.org, we:
build with
sphinxandmyst-nbcheck links with
pytest-check-links
Spelling and prose are checked in the sources by pixi run lint-vale.
pixi run check
Watch the Docs#
sphinx-autobuild will try to watch docs sources for changes, re-build, and serve a
live-reloading website. A number of files (e.g. _static) won’t often update correctly,
but will usually work when restarted.
pixi run watch-docs
Releasing#
After merging to
master, download the ipyelk dist artifactsInspect the files in
./dist.Check out master
Tag appropriately
git push upstream --tags
Ensure you have credentials for
pypiandnpmjsnpmjsrequires you have set up two-factor authentication (2FA)… this is strongly recommended forpypido not use
jlpm publishoryarn publish, as this appears to drop files from the distribution
npm login
npm publish
npm logout
twine upload where-you-expanded-the-archive/ipyelk-*
Updating Dependencies#
Python Dependencies#
Edit the
feature.*.dependenciessection ofpixi.tomlRun:
pixi run fix
Commit the changes to
pixi.tomlandpixi.lock
Browser Dependencies#
Edit the appropriate section of
./package.json.Run:
pixi run setup-js || pixi run setup-js || pixi run setup-js
pixi run fix
Commit the changes to
./package.jsonand the./yarn.lock.