Every post of the series on one page. Use the printer button in the menu bar, or your browser's Print command, and pick "Save as PDF" to keep a copy. Back to the series.
I should have a dispatch method that receives an XvcRootOpt and runs a command
with it. The dispatcher can also update the XvcRoot from None to Some(XvcRoot)
in some cases, so it should receive a mutable XvcRootOpt or return one after
receiving ownership.
The issue with having a mutable element is that we need to update XvcRoot from
Arc<XvcRootInner> to Arc<RwLock<XvcRootInner>>, which will cause almost all
machinery around XvcRoot to require locking the object first. This is too
large a refactoring.
However, I can write an xvc_root! macro to replace xvc_root.read() or
whatever is required to minimize the code changes. XvcRoot can also be a wrapper
object, but thatโs too much fuss, and the responsibility may be misplaced.
Letโs update the type and let the dispatcher update XvcRootInner only
when necessary. Letโs see what will require updating.
We have a bug in the Python bindings where xvc.file.track() enters an infinite loop.
There can be multiple reasons, but are you sure that the xvc CLI works with the
same command?
Letโs start testing by creating another notebook server.
The notebook creates an Xvc repo successfully and returns the root with
xvc.root(), but xvc.file().track("test-data/dir-0001/") never finishes.
Itโs likely that this is caused by something in the background threads.
The CLI command completes successfully, but we may be passing the command
incorrectly. Letโs try dir-0001 only.
Even if an incorrect path is provided, it shouldnโt enter an infinite loop.
When I provide the correct path, dir-0001, it returns. There may be something going on with finding the root of the Xvc repo.
It returns, but itโs also giving an error that it cannot find a repository. I should take a closer look.
The Xvc struct wasnโt implementing Debug, so I added it.
Letโs add it to others, XvcFile, etc.
Added it. Recompiling to get more info when we run track with an incorrect path.
You can also make it run after a commit to avoid starting a new server if one is already running.
Added conditionals, and now it runs the server if none is running in the background.
PORT=7979
if [[ ! -s "$(ps ax | rg -v ps | rg jupyter-lab | rg $PORT)" ]] ; then
jupyter lab --port=$PORT --notebook-dir=Readme/ &
open http://localhost:${PORT}/lab/workspaces/auto-H/tree/Readme.ipynb
fi
We were debugging Python bindings for Xvc. xvc.file.track enters an infinite
loop when given a non-existent path.
To make debugging easier, we can add file deletions in the ./start-readme script
to the notebook itself.
Instead, Iโll run my watcher run-after-commit.sh to ensure that the files
are deleted after commits.
That may also work; you can use both as well.
I noticed cli-opts pass --no-system-config etc. by default. Letโs deal with
this first.
I fixed that.
Iโm testing whether we are in the directory that we should be in with
xvc.root("--absolute"), but it looks like itโs not possible to pass a string
argument to the command.
Let me take a look at this.
It looks like there have been some changes in optional parameter handling in PyO3.
You may need to deal with keyword arguments with decorators.
Now, letโs try xvc.file().track() once more with dir-0001/.
It seems to be working now. With an existing directory, it doesnโt show an
error.
What does xvc.file().list() show?
It shows a single string with \n in it. It looks like we need to handle this in
the output thread.
I added a replace("\\n", "\n") to output_str at the end, but it didnโt make a
difference. I tested in the notebook with list_result.split("\n"), and these
\n characters are indeed CRLF. So Jupyter shows CRLF in strings with \n, and
this is not something we should try to fix, I think.
You can search how to show \n characters in a Jupyter notebook with CRLF.
The output string should be fed into repr, as in:
# Define a string with CRLF characters
text_crlf = "Hello\r\nWorld\r\nThis is a test string."
# Use repr to show the \r\n characters explicitly
print(repr(text_crlf))
I tested this, and GPT misleads. repr is when you want to show \n, not
vice versa. When I print(list_result), it prints the results properly.
It looks like we donโt need to make this a priority now. We can tell the user in the
notebook that the commands are intentionally returning strings, and they can
process or print them however they want.
Letโs begin this session by removing debug statements from both the Xvc library and the Python bindings.
Another issue is the restart script. The if in that script that restarts the server doesnโt work; it always restarts the notebook server.
I removed some println! statements from xvc.py. There doesnโt seem to be anything in the library related to outputs.
Letโs search for how to check if a jupyter-lab command with the port 7979 runs in the background.
It looks like the bug is in the condition; itโs not -s, itโs -z.
Oops, yeah.
Letโs do a bit of tidying and check if the script is fixed.
I have a clippy warning with a new function that says these usually donโt take self as a parameter. This is for the pipeline new command, and it receives a self as an XvcPipeline object. It seems best to turn off the clippy warning for this.
I allowed two clippy warnings, and the script seems to work fine.
Letโs go on to copying the content from the Xvc README to the notebook.
There is an issue with the run-after-commit script. When Xvc commits the changes, the command we give is run again.
The issue is that git initializes the directory in the test-data/ directory, while xvc works in the current directory. I think we can either git init in the current directory or xvc init in test-data.
Weโre already deleting .git and .xvc directories in the start-readme script. I think it may be easier to update git init to just initialize in the current directory.
Yep, letโs do it that way.
I see there are still extra outputs from the commands. We need to deal with this first.
I removed them, but there are still pink outputs. These are from dbg! statements, it looks like, or weโre initializing the output thread incorrectly.
Fixed those as well. I wrote up the xvc file list command examples as well. Now we have issues with xvc storage new s3 not running, and not even showing any debug output. Weโll deal with it in the next devlog, though.
While writing Xvc tests for Python, I hit an error caused by the ECS single-load protection.
The single-loader allows only one instance of Xvc to be run in a single process. This is no problem for the shell, but it looks like it wonโt be possible to use multiple Xvc instances in a single Python process.
Itโs possible to overcome this with an elaborate multiprocessing setup in the wrapper, but I wonโt bother with it for now.
I have a habit of testing against the CLIโs help string output. It allows me to
keep the documentation up to date and makes me aware of any undocumented options.
When new features are added, the help text changes and the test fails, which
prompts me to add those options to the documentation.
I tried the same approach when testing Python bindings with Pytest:
def test_pipeline_step_dependency(empty_xvc_repo):
dep_help = empty_xvc_repo.pipeline().step().dependency(help=True)
expected = """
Usage: xvc pipeline step dependency [OPTIONS] --step-name <STEP_NAME>
Options:
-s, --step-name <STEP_NAME>
Name of the step to add the dependency to
"""
assert dep_help == expected
This doesnโt work because the help text is generated by clap and skips the usual
thread-based output handler. All command output and errors in Xvc are returned
as strings from the command, except for the help text thatโs generated by clap
automatically.
There are probably workarounds for this, but I wonโt pursue them further as I donโt
test the actual functionality in the Python bindings anyway.
I noticed that I often forget to update the Xvc CHANGELOG. To fix this, I added
a pre-push hook that checks the files Iโm pushing. If the CHANGELOG is not among
them and there are changes to Rust files, it prevents the push. I hope this will
remind me to update the logs more frequently.
#!/bin/bash
# Git pre-push hook to check if CHANGELOG.md is included in the push and if the branch is develop
# Get the current branch name
current_branch=$(git rev-parse --abbrev-ref HEAD)
# Check if the branch is develop
if [ "$current_branch" == "main" ]; then
echo "You are on the main branch. Skipping CHANGELOG.md check."
exit 0
fi
# remote="$1"
# url="$2"
# Get the list of commits to be pushed
commits=$(git rev-list '@{u}..HEAD')
has_rust_files=$(false)
# TODO: We can iterate to get file list only once
# Get the list of files that are going to be pushed
for commit in $commits; do
if git diff-tree --no-commit-id --name-only -r "${commit}" | grep -q "\\.rs$"; then
has_rust_files=$(true)
fi
done
if [[ ! $has_rust_files ]]; then
echo "No .rs files in the push, no need to check CHANGELOG"
exit 0
fi
# Check if CHANGELOG.md is among the files in the commits
for commit in $commits; do
if git diff-tree --no-commit-id --name-only -r "${commit}" | grep -q "CHANGELOG.md"; then
echo "CHANGELOG.md is included in the push."
exit 0
fi
done
echo "ERROR: CHANGELOG.md is not included in the push."
exit 1
Edit (2025-02-08): Added a check for when only code files are changed.
๐ข The only failure was the patch coverage in Xvc. Letโs see what needs to be done.
๐ It looks, from the coverage page, that our additions to HStore donโt have any tests. Maybe we can add some unit tests to the new joins.
๐ข I donโt find unit tests particularly useful, but letโs use GitHub Copilot to add some for us.
๐ I added a unit test and a doc test for full_join. I think doc tests have more value; they provide documentation, and we can readily see how to use a function from its docs. Itโs better to increase coverage with doc tests.
๐ข There are things I should keep in mind while writing doc tests. Imports must use the full path, not crate. Also, the tested struct doesnโt have implicit imports.
๐ The ceremony for adding keys and values is a bit too much. It might be worthwhile to add an insert method for anything that implements Into<XvcEntity>.
๐ข That would certainly save timeโno more typing .into() for each key! :)
๐ Pushed to test again. Should we have some way to test coverage locally?
๐ข I donโt think we need to check coverage locally. Itโs not worth our time right now.
๐ Now, while waiting for the tests to complete, what else can we do?
gh -R iesahin/xvc run list
completed failure v0.6.13 Rust-CI v0.6.13 pull_request 12543831360 3m54s 2024-12-30T08:15:06Z
...
๐ข That didnโt take too long. Letโs view the results:
gh -R iesahin/xvc run view 12543831360
...
X Run Current Dev Tests
...
To see what failed, try:
View this run on GitHub: https://github.com/iesahin/xvc/actions/runs/12543831360
๐ข The current dev tests are failing for some reason. Letโs run them locally.
๐ Weโre missing llvm-tools-preview locally. How do I install this?
๐ข The command is rustup component add llvm-tools-preview:
info: component 'llvm-tools' for target 'aarch64-apple-darwin' is up to date
๐ Itโs already installed. We just need to set the environment variables.
๐ข Instead, we can just turn off dev tests for the time being. We donโt really need them; our local tests pass.
๐ Yeah, okay. We donโt need to solve every single bit of these issues right now.
gh -R iesahin/xvc run list
...
๐ Okay, letโs take a look at the run again.
gh -R iesahin/xvc run list
completed failure v0.6.13 Rust-CI v0.6.13 pull_request 12544020064 3m39s 2024-12-30T08:33:25Z
gh -R iesahin/xvc run view 12544020064
...
X Test and Coverage
...
gh run view 12544020064 --log-failed
...
Test and Coverage (stable) Test and Coverage 2024-12-30T08:36:58.8911690Z Error: ProcessError { stdout: "", stderr: " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\ncurl: (7) Failed to connect to e1.xvc.dev port 80 after 160 ms: Couldn't connect to server\n" }
...
๐ข We need to start Nginx on the server. We forgot to do that yesterday.
๐ Ah, right. After that dufs installation. Okay.
๐ข We also need to add a reverse proxy for dufs somehow, but thatโs for later.
๐ For this use case, I donโt think itโs necessary. We can just adjust the port to a non-standard one if we need 443 for something else. Letโs look at the tests again.
๐ข Letโs add another doc test, this time to XvcStore.
cargo test -p xvc-ecs --doc
...
test result: ok. 8 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.87s
๐ Sent the files again. Waiting for the tests to finish.
๐ข Letโs check the keymaps file in the meantime.
๐ I tried reading the documentation but didnโt see an error. Maybe we should just set it to non-lazy and disallow remaps.
๐ข Weโve already spent too much time on this.
๐ Yes, letโs check the tests again.
gh -R iesahin/xvc run list
completed success v0.6.13 Rust-CI v0.6.13 pull_request 12544291068 8m10s 2024-12-30T09:00:42Z
...
๐ข Oh, nice, the merge is ready.
๐ Patch coverage is still behind the target, though.
๐ข Yeah, but letโs release this one and ensure the next one is better covered. Also, Iโm not sure if the doc tests actually affected the coverage report.
๐ If we look at the coverage page again, we can see.
๐ข It seems codecov.io doesnโt consider coverage for doc tests. Thatโs a bit weird, but letโs not spend more time on it.
๐ Sure, letโs merge.
๐ข I think we forgot to bump the versions in the Cargo.toml files. Weโll have to do that in main.
๐ Oh, yeah. Letโs bump them and tag the release as well.
๐ข Now we can wait for all the files to be produced. Whatโs next?
๐ We can release the Python version too. It shouldnโt need any changes.
๐ข Right. Maybe we can add a few tests there as well.
๐ Letโs bump the version first and see.
๐ข Iโve bumped the versions in Cargo.toml and run maturin develop.
๐ It seems ready now.
๐ข The main branch is failing, though. The โPublish cratesโ action is looking for libsqlite3. Letโs investigate.
gh -R iesahin/xvc run list
completed failure Release v0.6.13 Publish Crates v0.6.13 push 12544753359 6m1s 2024-12-30T09:41:56Z
๐ข The issue is that the VM doesnโt have libsqlite3-dev. Letโs add it.
๐ We need to restart the job manually. Letโs skip tagging this time.
๐ข Some of the packages were already published, and now theyโre causing failures because crates.io says they already exist. Maybe we can check if a package is already published before trying.
๐ Letโs see if we can make cargo publish more forgiving.
๐ข There doesnโt seem to be an easy option. Letโs search for โhow to skip published packages in workspace to avoid errors with cargo publish.โ
๐ Claude is hallucinating again. Letโs try a manual approach: how to skip already published packages?
๐ข It might be easier to just add a check. How do we get that info?
๐ Or we can just move on to the next package if one is already available.
๐ข Letโs push the missing packages manually this time.
๐ข We should have a key to open garden files quickly. What does Fzf-Lua files receive as arguments?
๐ Letโs check the help page: fzf-lua.
๐ข Before that, maybe we can try to fix why selected lines are not searched in Visual-Line mode?
๐ Yep, letโs fix our search first.
๐ข How do you set a key in visual line mode in Neovim Lua?
๐ The abbreviation is V. Letโs try that.
๐ข Looks like we need to restart the session.
๐ Itโs still not working. Letโs check :map.
๐ข It seems it needs more care; Iโll check it later.
๐จ๐พโ๐ฆฒ
๐ข Bence kendini biraz daha anlamlฤฑ bir iลle uฤraลtฤฑrmalฤฑsฤฑn.
๐ Ne gibi?
๐ข Belki biraz daha yayฤฑn yapmalฤฑsฤฑn, biraz daha iลe baลvurmalฤฑsฤฑn.
๐ โMeliโ, โmalฤฑโ ile geรงiyor รถmrรผmรผz.
โ
๐ข It looks like we can move most of the daily template to links or commands. We can call it ref/daily. My idea is to fill the page intentionally, without templates.
๐ It might be better to start with a blank page, yeah. The template makes me a bit nervous. There are too many things to fill in, and most of them arenโt things I like being pushed into doing.
๐ข Letโs start by moving the daily templates to ref/daily. No more daily template.
๐ Now we can delete the rest of this page. Weโll use the daily links page and maybe have reminders at the end of these sessions.
๐ข Today Iโm planning to add cross-compilation to the Xvc 0.6.13 branch to provide more platform support.
๐ It looks like you first need to turn off this ghost text from the blink output. It makes writing insufferable.
๐ข Yep, letโs do that first.
๐ Now, letโs restart Neovim.
๐ข I donโt know why blink.cmp doesnโt prioritize the emojis I use. Maybe we can just use #tor and #rab for ourselves.
๐ I think over time it will learn that the emojis I defined in the snippets file should have higher priority, but letโs skip this for now. What do we need to do to add cross-compilation?
๐ข Maybe we can just make the completion menu wait a bit longer. It shows up almost instantly, and I want it to wait for a few more milliseconds.
๐ Okay, letโs look at the config.
๐ข The configuration file doesnโt seem to have a key for this. Letโs search: blink.cmp.
๐ Now we have the cross and cross-util commands. Cross-compilation requires Podman on Linux or Docker on macOS. Do we have Docker?
๐ข It looks like we donโt. Maybe we can just set up a remote build using Podman or GitHub Actions. I saw a crate for that yesterday; I remember saving it somewhere but canโt find it now. Searching again seems easier, which says something about my archival and retrieval habits.
๐ Maybe later you can add some vector search capabilities to your archiveโsemantic search.
๐ข Yep, sometime later.
๐ Now letโs search for โadding rust cross compilation to github actions.โ
๐ We can just convert the current configuration to this and see if it works.
๐ข Letโs do that. I created .github/workflows/release.yml and will update it.
๐ Letโs check the results with gh:
$ gh -R iesahin/xvc run list
completed failure v0.6.13 Release v0.6.13 pull_request 12525070531 34s 2024-12-28T08:17:28Z
๐ข It says the release has completed.
$ gh -R iesahin/xvc run view 12525070531
X v0.6.13 Release iesahin/xvc#263 ยท 12525070531
Triggered via pull_request about 3 minutes ago
JOBS
X Release - FreeBSD-x86_64 in 12s (ID 34936257653)
โ Set up job
โ Checkout
X Build binary
- Publish artifacts and release
โ Post Build binary
โ Post Checkout
โ Complete job
...
Now letโs look at the failure:
$ gh -R iesahin/xvc run view 12525070531 --log-failed
๐ Change the order and see what happens. Maybe we should first succeed in a non-cross-compilation build.
$ gh -R iesahin/xvc run list
completed failure v0.6.13 Release v0.6.13 pull_request 12525178664 35s 2024-12-28T08:34:18Z
...
$ gh -R iesahin/xvc run view 12525178664 --log-failed
...
๐ข Itโs the same error. The usage example is actually much more sophisticated.
๐ The issue is that weโre asking for command from the matrix, but the matrix doesnโt define it. Thatโs the second time today an example from the documentation has failed. Iโve added command for each platform. We can also add separate features this way to make platform-specific functionality work.
๐ข Agreed. Letโs look at it once more.
$ gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525253982 41s 2024-12-28T08:46:23Z
$ gh -R iesahin/xvc run view 12525253982 --log-failed
...
Release - macOS-x86_64 Build binary 2024-12-28T08:46:44.8464010Z [1m [31merror [0m [1m: [0m the lock file /Users/runner/work/xvc/xvc/Cargo.lock needs to be updated but --locked was passed to prevent this
๐ Ah, thatโs a different error. Letโs remove the --locked flag and retry.
$ gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525289176 1m8s 2024-12-28T08:53:23Z
๐ข Weโre finally starting to get some good news. Now weโre getting OpenSSL errors. We need feature flags for these platforms or to specify where OpenSSL is. Letโs add bundled-openssl to the failed ones. We also need bundled-sqlite for Windows binaries.
gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525354179 3m9s 2024-12-28T09:04:55Z
๐ It looks like the Changes.md file is missing, and it canโt upload the binaries as a release because of this. Iโll set the changes file to CHANGELOG.md.
๐ข Itโs weird to fail because of that. I think we should report these errors and possibly send a PR to make that file optional.
gh -R iesahin/xvc run list | rg Release | head -n 1
in_progress v0.6.13 Release v0.6.13 pull_request 12525449368 1m38s 2024-12-28T09:18:40Z
...
โ Release - macOS-x86_64 in 2m39s (ID 34937017695)
โ Release - macOS-aarch64 in 2m42s (ID 34937017787)
..
ARTIFACTS
xvc-macOS-x86_64.tar.gz
xvc-macOS-arm64.tar.gz
๐ข It looks like Linux-riscv64 has OpenSSL compilation errors. I think we can skip this platform for now. The goal was to add aarch64 for macOS, and that seems to have succeeded.
gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525504079 3m24s 2024-12-28T09:26:43Z
...
X Release - Linux-x86_64 Build binary 2024-12-28T09:29:16.2262518Z [0m [1m [38;5;9merror[E0308] [0m [0m [1m: mismatched types [0m
...
๐ข It looks like Linux-x86_64 doesnโt support reflinks. Maybe we can make reflinks an optional feature and add it specifically to macOS and Windows targets.
๐ Iโve removed reflink from the default features. This is a breaking change, but fortunately we donโt have many users who will be affected by it.
Letโs check the results once more.
gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525597866 3m39s 2024-12-28T09:42:44Z
๐ข Now turn off the NetBSD target as well.
๐ FreeBSD and Linux-x86_64 targets are building. Letโs see why the ARM Linux targets are failing.
gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525643284 4m46s 2024-12-28T09:52:04Z
๐ It looks like those targets donโt have libsqlite3 installed. Letโs add bundled-sqlite to these targets too.
gh -R iesahin/xvc run list | rg Release | head -n 1
completed failure v0.6.13 Release v0.6.13 pull_request 12525734325 4m11s 2024-12-28T10:07:36Z
๐ข Adding Android as a target didnโt work. Letโs remove it for now; it seems to require more work.
๐ I think weโll eventually move to using Xvc to distribute binaries. We could build the Android binary on Termux and link it on the releases page or push it as a release artifact.
๐ข I need to learn more about GitHub releases. If we can add artifacts to the release, maybe we can do some of this work locally.
๐ We can start by looking at the capabilities of gh commands.
๐ข It looks like itโs possible to upload assets to releases. Letโs check how that works.
gh release upload --help
๐ So basically, we can just upload files to tags. We can list releases and work with them like anything else.
gh -R iesahin/xvc release list
And we can delete releases:
for r in v0.4.2-alpha.8 v0.4.2-alpha.7 v0.4.2-alpha.6 v0.4.2-alpha.5 v0.4.2-alpha.0 v0.4.1-alpha.0; do
gh -R iesahin/xvc release delete "${r}"
done
๐ข Now letโs list them again.
gh -R iesahin/xvc release list
๐ The latest one has failed again.
X Failed to CreateArtifact: Received non-retryable error: Failed request: (409) Conflict: an artifact with this name already exists on the workflow run
๐ข It looks like weโre coming to the end of this session. Under what conditions will we create a release?
๐ I think itโs better to release only non-alpha tags.
๐ข Then the rule in the workflow will be something like:
on:
workflow_dispatch:
push:
tags:
- "v*.*.*"
- "!v.*.*-alpha.*"
๐ And now we have this result:
โ v0.6.13 Release iesahin/xvc#263 ยท 12533498361
Triggered via pull_request about 21 minutes ago
JOBS
โ Release - FreeBSD-x86_64 in 4m14s
โ Release - Linux-x86_64 in 4m3s
โ Release - Linux-aarch64 in 4m50s
โ Release - Windows-x86_64 in 8m47s
โ Release - Windows-aarch64 in 6m42s
โ Release - macOS-x86_64 in 2m37s
โ Release - macOS-aarch64 in 2m36s
๐ข Nice! Letโs check the release list.
gh -R iesahin/xvc release list
๐ Why is there no โlatestโ release?
๐ข We have to tag it first.
๐ Ah, right. Letโs tag it then.
๐ข Iโve pushed the changes and tagged them with v0.6.13-alpha.5.
๐ I think itโs possible to make a release today.
๐ข It looks like it, yes.
๐ We can merge the PR and tag it. Then everything should work.
๐ข We need some cleanup in the YAML files, though.
๐ข Now we have another failure in the regular CI. Letโs look at it.
๐ The issue seems to be in the doc tests:
- Total #: 8 Workspace Size: 276 Cached Size: 19
+ Total #: 8 Workspace Size: 278 Cached Size: 19
๐ข These tests are brittle, but they provide valuable information. Letโs fix it and push again.
๐ Done. We can also remove some of the watches that produce so many logs.
๐ข Iโm a bit ambivalent about them. I thought we could use these watches when debugging, but experience has shown that we need more granular watches during debugging and almost never use these otherwise. Letโs remove some of them.
๐ We can increase the output for certain commands, but the tracing output doesnโt help much in regular runs. If Xvc gets popular enough that we canโt cope with bug reports, we can always add more watches.
๐ข Another option is to exclude the watch code from the release build, but that wonโt change anything for our debug cycles.
๐ I think removing them is a fair trial. We can always put them back when debugging.
๐ข Watches could also produce regular output instead of tracing. That way we wonโt forget to remove them.
๐ Ah, yep, thatโs a good option too.
๐ข We can have a trace! macro similar to the current one for user consumption, and a watch! macro that sends output to stderr.
๐ Good idea. Letโs do that in the next release.
๐ข Letโs check the tests before pushing this cleanup.
gh -R iesahin/xvc run list
completed success v0.6.13 Rust-CI v0.6.13 pull_request 12533993607 13m49s 2024-12-29T08:47:50Z
๐ CI succeeded, and the release didnโt run. Letโs do some more cleanup.
gh -R iesahin/xvc run list
in_progress v0.6.13 Rust-CI v0.6.13 pull_request 12534416152 43s 2024-12-29T09:57:02Z
๐ข Now weโre going into the real deep work. The only failure was the Codecov patch in Xvc. Letโs see what needs to be done.
๐ It looks, from the coverage page, that our additions to HStore donโt have any tests. We can add some unit tests to new joins, maybe.
๐ข I donโt find unit tests particularly useful, but letโs use GitHub Copilot to add tests for us.
๐ Added a unit test and a doc test for full_join, and I think doc tests have more value. They provide documentation, and we can readily see how to use a function from its docs. Better to increase coverage with doc tests.
๐ข There are points that I should learn while writing doc tests. The imports must use the full path, not crate::. The tested struct also doesnโt have implicit imports.
๐ The ceremony of adding keys and values is a bit too much. It may be worthwhile to add insert for any Into<XvcEntity>.
๐ข It will certainly save time if we donโt have to type .into() for each key :)
๐ Pushed to test again. Should we have some means to test coverage locally?
๐ข I donโt think we need to consider coverage locally. Itโs not worth our time.
๐ Now while waiting for tests to be completed, what can we do?
gh -R iesahin/xvc run list
completed failure v0.6.13 Rust-CI v0.6.13 pull_request 12543831360 3m54s 2024-12-30T08:15:06Z
...
๐ข I donโt think it took too much time. Letโs view the results:
gh -R iesahin/xvc run view 12543831360
...
X Run Current Dev Tests
...
To see what failed, try:
View this run on GitHub: https://github.com/iesahin/xvc/actions/runs/12543831360
๐ข The current dev tests fail for some reason. Letโs run these locally.
๐ Weโre missing llvm-tools-preview locally. How do we install this?
๐ข The command is:
rustup component add llvm-tools-preview
info: component 'llvm-tools' for target 'aarch64-apple-darwin' is up to date
๐ Itโs already installed. We need to set the environment variables.
๐ข Instead, we can just turn off dev tests for the time being. We donโt need them. Our local tests pass.
๐ Yeah, ok, we donโt need to solve each and every bit of these issues.
gh -R iesahin/xvc run list
โฆ
๐ Ok. Letโs take a look at the run again.
gh -R iesahin/xvc run list
completed failure v0.6.13 Rust-CI v0.6.13 pull_request 12544020064 3m39s 2024-12-30T08:33:25Z
gh -R iesahin/xvc run view 12544020064
...
X Test and Coverage
...
gh run view 12544020064 --log-failed
...
Test and Coverage (stable) Test and Coverage 2024-12-30T08:36:58.8911690Z Error: ProcessError { stdout: "", stderr: " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\ncurl: (7) Failed to connect to e1.xvc.dev port 80 after 160 ms: Couldn't connect to server\n" }
...
๐ข We need to start nginx on the server. We forgot it yesterday.
๐ Ah, yeah. After adding that dufs installation. Ok.
๐ข We also need to add a reverse proxy to dufs somehow, but this is for later.
๐ For the use case, I donโt think itโs necessary. We can just adjust the port to a non-standard one if we need to use 443 for another thing, but letโs take a look at the tests again.
๐ข Letโs add another doc test. This time to XvcStore.
cargo test -p xvc-ecs --doc
...
test result: ok. 8 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 2.87s
๐ Sent the files again. Waiting for tests to finish.
๐ข Letโs check the keymaps file in the meantime.
๐ I tried to read some documentation but didnโt see an error. Maybe we should just set it to non-lazy and avoid allowing remaps.
๐ข We already spent too much time with this.
๐ Yes, letโs take a look at the tests again.
gh -R iesahin/xvc run list
completed success v0.6.13 Rust-CI v0.6.13 pull_request 12544291068 8m10s 2024-12-30T09:00:42Z
...
๐ข Oh, yeah, the merge is ready.
๐ Patch coverage is still behind the target, though.
๐ข Yeah, but letโs release this one and make the next better covered. Also, Iโm not sure if the doc tests had any effect on coverage.
๐ If we look at the coverage page again, we can see if the doc tests had any effect.
๐ข It seems codecov.io doesnโt consider coverage for doc tests. This is a bit weird, but letโs not spend more time on this.
๐ Sure, letโs merge.
๐ข I think we forgot to bump the version in Cargo.toml. Weโll have to do that in main.
๐ Oh, yeah. Letโs bump it and tag as well.
๐ข Now, we can wait for all files to be produced. What will we do next?
๐ We can just release the Python version as well. It shouldnโt need any changes.
๐ข Umm, right. Maybe we can add a few tests as well.
๐ Letโs bump the version first and see.
๐ข Bumped versions in Cargo.toml and ran maturin develop.
๐ It seems ready now.
๐ข The main fails, though. The โPublish Cratesโ action looks for libsqlite3. Letโs take a look at it.
gh -R iesahin/xvc run list
completed failure Release v0.6.13 Publish Crates v0.6.13 push 12544753359 6m1s 2024-12-30T09:41:56Z
๐ข The issue is that the VM doesnโt have libsqlite3-dev. Letโs add it.
๐ We need to start the job manually again. Letโs not tag this time.
๐ข Some of the packages were already published. Now they break. crates.io says theyโre already published. Maybe we can check if a package is already published.
๐ Letโs check if we can make cargo publish more forgiving.
๐ข There doesnโt seem to be an option. Letโs search โhow to skip published packages in the workspace to avoid errors with cargo publishโ.
๐ Claude is bullshitting again. Letโs try a manual approach: how to skip already published packages.
๐ข It may be easier to just add a check if the package is published. How do we get the info?
๐ Or we can just go on to the next package if the package is already available.
๐ข Letโs move slowly. Letโs create a brew project first.
๐ฆ There is a brew create command, but could we really copy it from someone else?
๐ข I read the espanso example, and Iโll start by adding a repository. Welcome https://github.com/iesahin/homebrew-xvc
๐ฆ We can search to automate this for Rust stuff first. Maybe itโs easier to automate than to do it manually with examples.
๐ข Letโs search โhow to automate homebrew tap formula updates with github actionsโ
๐ฒ There is a shell script that updates the brew repo with a shell script. It fires the action from the main repository with a command like:
gh workflow run release.yml -f version=${{ env.VERSION }} -R itspriddle/homebrew-slack-notify
๐ข It looks a little brittle, though.
๐ฒ There is also a GitHub action: https://github.com/marketplace/actions/homebrew-tap but it doesnโt look very popular. There is another one https://github.com/marketplace/actions/bump-homebrew-formula but this is for formulas, or the default settings are those.
๐ข There is an example https://github.com/marketplace/actions/bump-homebrew-formula#examples for taps as well.
๐ฒ This one is simpler, and probably we can just add this first: https://github.com/marketplace/actions/homebrew-bump-formula Most of the fields are optional.
๐ I think this is much easier than the other. Letโs start with this.
๐ข Now letโs add a token to the Xvc repo. โ
๐ฆ Add a branch to Xvc and add the release action file.
๐ข Added the release action file ~/github.com/iesahin/xvc/.github/workflows/homebrew.yml, but we still donโt have a tap; maybe we can just add one.
๐ฆ Can you check espansoโs for example?
๐ข It has a cask and is in the core. We need a tap example.
๐ฒ I believe we need to clone homebrew-xvc and run gh workflow run.
๐ข Yes, letโs clone the repo and try to run it manually.
๐ We donโt have a formula yet.
๐ฆ Whatโs the directory structure of a Homebrew tap project?
๐ข Itโs something like this, but we donโt need tests for this, I believe.
๐ I think we can start by improving xvc.py. I mean, releasing. Yesterday we finished our work with the Rust library.
๐ข Then we can start to look at the GUI, I believe. We can replace that 3-column view with a table and preview. It will be much easier that way.
๐ Yep. Letโs finish and release the Python version first. Then weโll go on to the GUI.
๐ข Letโs take a look at the PRs first.
ghpl
36 Bump pyo3 from 0.22.2 to 0.23.3 dependabot/cargo/pyo3-0.23.3 OPEN 2024-12-04T03:52:03Z
gh pr close 36
โ Closed pull request iesahin/xvc.py#36 (Bump pyo3 from 0.22.2 to 0.23.3)
๐ข We have already upgraded to pyo3 0.23. No need for this. Letโs create a PR for the current branch.
๐ข Iโd like to have some more coverage for certain parts of the code. Letโs add some tests.
๐ It looks like we mainly lack the storage tests. They need configuration to add keys to GitHub, and we already skip some of these even in the Rust code.
๐ข Umm, I see. We also need a way to measure coverage. Could we do this with Codecov, I wonder?
๐ I found an example here: https://github.com/codecov/example-python/blob/main/.github/workflows/ci.yml. It needs coverage and pytest-cov in the requirements.
๐ข Letโs try this then.
๐ Added coverage.yml file. Itโs simpler than the other GitHub action. Need to update the token now.
๐ข There is an issue installing the requirements.
๐ I forgot to add sudo to apt-get. Will take care of it now.
๐ It takes a while and we still didnโt add the CODECOV_TOKEN.
๐ข Letโs add it, and after that, we need to take a look at this blink configuration. It adds letters after the selection.
๐ Added the secret and configured xvc.py for coverage. There is an error with the build, though. Maybe the command we should be using is maturin develop instead of build to make Xvc available for the environment.
๐ข Letโs update and try it then.
๐ maturin develop requires a virtual environment.
๐ข I checked the options for build, and I think there is an option, but letโs search first.
๐ I searched, but it looks like we can just pass an --out directory or install xvc from the target/wheels/ directory. The second option requires less maintenance.
๐ข Okay. Letโs add a step to the action then.
๐ Now, letโs wait for the run to finish with gh run watch.
๐ It looks like some of the tests are failing. Letโs run the tests locally.
๐ข We should run with the --forked option, and it looks like we have a test to update with the xvc file list.
๐ Updated the test, and I noticed we forgot to supply the new --show-directories option in the Python interface.
๐ข Yep. Passing these options as command-line options in strings is not robust. Itโs very easy to forget things. I think we should start using CLI structs directly, but itโs not time yet.
๐ I agree. Itโs one of the goals for building a GUI, actually.
๐ Added db.commit() to two places in the code. This should pass now.
๐ข Yeah!
ghrl | head -n 1
completed success Release v0.6.13 coverage v0.6.13 pull_request 12557509836 3m46s 2024-12-31T08:44:33Z
gh run view 12557509836
โ v0.6.13 coverage iesahin/xvc.py#37 ยท 12557509836
Triggered via pull_request about 4 minutes ago
JOBS
โ linux in 3m36s (ID 35010253915)
ANNOTATIONS
! ubuntu-latest pipelines will use ubuntu-24.04 soon. For more details, see https://github.com/actions/runner-images/issues/10636
linux: .github#1
For more information about the job, try: gh run view --job=35010253915
View this run on GitHub: https://github.com/iesahin/xvc.py/actions/runs/12557509836
๐ I canโt see a coverage report on codecov.io, though.
๐ข It says no coverage report is generated. Letโs test to generate XML files locally.
๐ The option in the docs seems incorrect. --cov-branch doesnโt produce anything.
๐ข Letโs wait for the run again.
๐ Should we add a badge to the README?
๐ข It wonโt show much, but yeah, letโs make it.
๐ The results are in and it shows 100% coverage. This means it doesnโt actually test anything.
๐ข We need Rust coverage for this. Letโs search for it.
๐ I found this: https://github.com/cjermain/rust-python-coverage. It runs cargo llvm-cov with the project and measures test coverage. But we donโt have any Rust tests.
๐ข It looks like we donโt need Rust tests. cargo llvm-cov can check coverage with the Python as well.
๐ There is no version string in ~/github.com/iesahin/xvc.py/pyproject.toml. Itโs dynamic.
๐ข Then, letโs try to publish from local now.
๐ The iex username requires email verification.
๐ข It looks like I publish xvc through the iesahin account, not iex. Maybe I can add both accounts to the project.
๐ There seem to be no errors on the PyPI site.
๐ข Updating the token. Letโs add the token to pass to run maturin publish.
๐ Weโre receiving invalid or non-existent authentication information. Upgraded maturin to see if it fixes the issue.
๐ข We can also double-check the key.
๐ Uploaded successfully from local. Letโs check the job again.
๐ข The release job was skipped because we didnโt tag after the merge. https://github.com/iesahin/xvc.py/actions/runs/12557780141/job/35011303045 That looks like the reason.
๐ I should be more careful which is run and which is skipped.
๐ข Maybe we can relax the condition. We do this rarely. Maybe republishing is alright?
๐ Yep, removed that. The jobs are running now. Letโs watch them to see what happens when we publish some of the packages.
๐ข In the meantime, letโs experiment with searching commands file with fzf-lua.
๐ It requires more experimentation, but we can start from https://github.com/ibhagwan/fzf-lua/wiki/Advanced#interactive-shell-command.
๐ข The xvc publish jobs failed, btw.
ghrl
completed failure Remove if condition from release publish-to-pypi v0.6.13 push 12568863716 15m26s 2025-01-01T08:30:03Z
gh run view 12568863716 --log-failed
...
Release Run actions/download-artifact@v4.1.7 Please ensure that your artifact is not expired and the artifact was uploaded using a compatible version of toolkit/upload-artifact.
...
๐ It was using an older version of upload-artifact.
๐ข Rerunning the job and it looks like it runs for both push to main and tag with v0.6.13. We can turn off push to main, I believe.
๐ There was a missing upload-artifact again. Fixed and updated the tags.
๐ข There are conflicts with uploaded artifacts now. We may need to clean up the artifacts manually.
๐ The conflicts were not about inter-workflow names. The names were conflicting because all files were named wheel. I added the platform and target to the names to avoid conflicts.
๐ข Letโs wait then. Maybe it will work this time. Could you search for a Lua console for Neovim?
๐ข I couldnโt make it run but wonโt spend much time ATM. How about the jobs?
ghrl
completed failure update upload artifact names publish-to-pypi v0.6.13 push 12569298414 13m57s 2025-01-01T09:27:00Z
ghrf 12569298414
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9180510Z ##[group]Run actions/download-artifact@v4
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9182098Z with:
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9182859Z name: wheels
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9183843Z merge-multiple: false
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9184817Z repository: iesahin/xvc.py
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9185820Z run-id: 12569298414
Release Run actions/download-artifact@v4 2025-01-01T09:40:52.9186903Z ##[endgroup]
Release Run actions/download-artifact@v4 2025-01-01T09:40:53.1937617Z Downloading single artifact
Release Run actions/download-artifact@v4 2025-01-01T09:40:53.4694769Z ##[error]Unable to download artifact(s): Artifact not found for name: wheels
Release Run actions/download-artifact@v4 Please ensure that your artifact is not expired and the artifact was uploaded using a compatible version of toolkit/upload-artifact.
Release Run actions/download-artifact@v4 For more information, visit the GitHub Artifacts FAQ: https://github.com/actions/toolkit/blob/main/packages/artifact/docs/faq.md
๐ Now the download doesnโt work.
๐ข Update it to download using patterns.
๐ Did so and letโs take a look at the jobs again.
ghrl
completed failure added pattern to download .github/workflows/publish.yml main push 12569456859 0s 2025-01-01T09:49:19Z
ghrv 12569456859
X main .github/workflows/publish.yml ยท 12569456859
Triggered via push about 3 minutes ago
X This run likely failed because of a workflow file issue.
For more information, see: https://github.com/iesahin/xvc.py/actions/runs/12569456859
๐ข The line with the pattern was reported as broken.
๐ Removed it and recommitted.
ghrl
โ completed success remove pattern to download all publish-to-pypi v0.6.13 push 12569509435 14m41s 2025-01-01T09:58:49Z
๐ข And now this completes the v0.6.13 release.
๐ Weโll see how it will work next time.
๐ข Yep. Letโs move on to the GUI for now. Is that okay with you?
๐ข Completions are similar to the Homebrew work. Itโs in another ecosystem and feels boring.
๐ฒ We can try to make it in Rust: โWriting shell completions in Rust.โ
๐ข There are two solutions: One is clap_complete (https://docs.rs/clap_complete/latest/clap_complete/) and the other is shell_completion (https://github.com/JoshMcguigan/shell_completion). The latter is very new but may be what we need: writing completions only with Rust.
๐ฒ The shell_completion crate is very bare-bones. It doesnโt have anything, actually. https://github.com/JoshMcguigan/shell_completion/issues/1
๐ The feature that we need is dynamic completion. Weโll write something similar to ArgValueCompleter for this.
๐ฆ I think we can just start a new branch.
๐ฒ We have a branch for Homebrew; should we merge it?
๐ข I think, yes, we can merge it. Weโll fix it if it breaks. Itโs a separate workflow file anyway.
๐ฆ Created the PR.
ghpl
264 add brew tap add-brew-tap OPEN 2025-01-03T05:14:45Z
๐ข Merged it.
๐ Now letโs create a new branch and add clap-complete to Cargo.toml.
๐ฒ There are some packages that we need to take a look at. thiserror now has v2.
๐ข Upgraded packages and compiled. It works.
๐ฒ Letโs update the version.
๐ข Done. Now we can add clap-complete.
๐ฆ Added with the unstable-dynamic command. Can we build it again?
๐ข Built it. Now we can add a completions subcommand to Xvc.
๐ฒ Is this the right name for this?
๐ข It will output a shell script that we can source in the shell.
๐ฒ Okay, letโs add the subcommand now.
๐ข The example doesnโt work with the clap builder.
๐ Letโs search for it.
๐ข I think weโre extending ourselves a bit when trying to add all dynamic features of completion at once. We can just start by adding completion to xvc-test-helper.
๐ Yep, thatโs a better idea. We can have many more examples, and itโs certainly more straightforward.
๐ข One thing I noticed when working yesterday is that using auto-save was actually preventing many of these swap errors.
๐ฒ It was a bit slow. Can we take a look at a few others?
๐ข https://github.com/okuuva/auto-save.nvim seems a bit more polished.
๐ Installed it, but havenโt seen an effect yet.
๐ข We may need to restart this.
๐ฒ Now, we can get into the test-helper completions.
๐ข Done. Added these quickly as you thought. Now adding this to main seems much easier.
๐ฆ That was a nice approach. Letโs dive into adding this to main.
๐ Should we go with a separate command or just an option?
๐ฒ Our commands have distinct initial letters, allowing them to be used with just those letters. Adding another top-level command for this will make c useless.
๐ข I donโt think thatโs a valid concern. We can create aliases for all commands and completions shouldnโt have to have an alias. But I agree that completions should not be a top-level command. It will be run once for installation at most.
๐ฆ I agree. Letโs call it --completions. It will be run as xvc --completions zsh and will print out the completions.
๐ข Okay. Letโs do this.
๐ฆ No errors left. Letโs install this version.
๐ข We get:
error: 'xvc' requires a subcommand but one was not provided
[subcommands: file, init, pipeline, storage, root, check-ignore, aliases, help]
Usage: xvc [OPTIONS] <COMMAND>
For more information, try '--help'.
๐ฆ Umm, okay. I think we donโt have an option to create a command like that. Then weโll have to print completions with a subcommand.
๐ฒ The above discussion is now moot. โ
๐ข We can try to push, but probably itโs not worth it.
๐ฒ Letโs not lose time on this. I think we can remove the aliases command and replace it with completions, and add single-letter aliases to subcommands.
๐ข We can have an option in the completions command to print aliases. That will work.
๐ฆ I donโt think people will use the aliases command if we have single-letter command aliases.
๐ข You may be right. No need to try to maintain that at this time.
๐ข Good morning, and Iโm fed up with these blink.cmp errors, you know.
๐ Reinstalling blink works. Itโs interesting to rely on such unreliable software.
๐ข Oh, yeah. Itโs interesting. Where were we yesterday?
๐ฒ We decided to rename the aliases command to completions.
๐ And waiting for rust-analyzer to complete its analysis.
๐ข Uh, yeah. I see.
๐ฆ The code itself is very short, actually.
if let Some(shell) = cli_opts.completions {
let mut cmd = XvcCLI::command();
generate(shell, &mut cmd, "xvc", &mut io::stdout());
return Ok(None);
}
๐ฒ Weโll use the output! macro instead of writing to io::stdout(), right?
๐ข Yes, we can rely on the usual output system. It will be slower to create an output thread but shouldnโt matter for outputting a shell script.
๐ It takes a while for rust-analyzer to scan all the directories, it looks like. When I close the project, it just cannot reload it immediately.
๐ข We can use cargo clean from time to time.
๐ฆ rust-analyzer finished scanning; letโs try to rename AliasesCLI.
๐ฒ Letโs keep these here; maybe weโll need them in our scripts:
# Standard Xvc command aliases for longer commands.
alias xls='xvc file list'
alias pvc='xvc pipeline'
alias fvc='xvc file'
alias xvcf='xvc file'
alias xvcft='xvc file track'
alias xvcfl='xvc file list'
alias xvcfs='xvc file send'
alias xvcfb='xvc file bring'
alias xvcfh='xvc file hash'
alias xvcfco='xvc file checkout'
alias xvcfr='xvc file recheck'
alias xvcp='xvc pipeline'
alias xvcpr='xvc pipeline run'
alias xvcps='xvc pipeline step'
alias xvcpsn='xvc pipeline step new'
alias xvcpsd='xvc pipeline step dependency'
alias xvcpso='xvc pipeline step output'
alias xvcpi='xvc pipeline import'
alias xvcpe='xvc pipeline export'
alias xvcpl='xvc pipeline list'
alias xvcpn='xvc pipeline new'
alias xvcpu='xvc pipeline update'
alias xvcpd='xvc pipeline dag'
alias xvcs='xvc storage'
alias xvcsn='xvc storage new'
alias xvcsl='xvc storage list'
alias xvcsr='xvc storage remove'
๐ฆ We can use them when adding single-letter aliases.
๐ There is a from_env method for Shell; will we support it?
๐ฆ I think we can support it. Itโs much easier to use if we omit the shell.
๐ฒ We had aliases in xvc-core, but we need to access XvcCLI from completions. The completions module must be moved to xvc.
๐ฆ We added the clap_complete dependency to the xvc-pipeline and xvc-file crates, but I donโt think they are necessary. Letโs remove them now.
๐ข Now only the test-helper and xvc crates have the clap_complete dependency.
๐ Are we ready to test?
๐ข Completions are working. ๐
๐ฒ Now we need to update the docs and doc tests, I believe.
๐ข There are also tests to update.
๐ Tests are running now. In the meantime, can we take a look at the blink configuration?
๐ฒ When we removed xvc aliases, we also removed pvc, xls, and other aliases. Maybe we can add these to the docs.
๐ข We can put them in the xvc completions reference for now.
๐ข It takes a while for rust-analyzer to finish analyzing the codebase.
๐ฆ Added aliases for xvc pipeline commands. Do you think we need to repeat root-level flags in xvc-pipeline?
๐ข No need to divert attention, I believe. Also, I still think there is an easier way to do that.
๐ Okay. Do you think we should add easier subcommands to step? Like, step new becoming xvc p s n instead of xvc p s n? (Wait, thatโs the same). I mean, more concise.
๐ข I think we can extend these even to the top-level, but shouldnโt make them visible. It will pollute the help text. We can add xvc fl for file list to avoid the space, but hide these from the help text.
๐ฒ Thatโs a good idea, but it will require including sub-crate level modules at the top level. We must test it first.
๐ข Letโs finish up the current changes and release them first.
๐ By the way, we didnโt add two-letter abbreviations to the xvc storage new subcommands. Do you think we need them?
๐ข When we think about the frequency of these commands, no, I donโt think we need them. Users wonโt add a new storage every day.
๐ By that logic, we shouldnโt need an n for xvc storage new.
๐ข Actually, yeah. Maybe we should remove even s.
๐ฆ storage list may be useful.
๐ข s is a very common letter, though. We can have other uses for that letter.
๐ Updating xvc p s dependency options, but it looks like making dependency options subcommands is a better way.
๐ฆ We didnโt do it because currently we can supply multiple options with a single command. If we go the subcommand route, weโll have to write all dependencies one by one. Adding multiple subcommands with clap is a bit tricky.
๐ข Umm. Yeah, I see.
๐ Maybe we can provide a separate command to add multiple dependencies. Like, xvc p s d add 'lines=myfile.csv::10-20; file=myimage.jpg; glob=dir/image-10*'
๐ฒ That looks like the start of a language. We need a parser for those strings. They will be freeform.
๐ฆ Another option is to keep the current options and add commands with the same names.
๐ข That will be confusing. The user will have both --param and param, and they will work differently.
๐ We can have an add command that accepts the current options. Parsing will be done by clap just like now, but for a subcommand of dependency.
๐ข The full command will be something like xvc pipeline step --step-name preprocessing dependency add --params 'params.json::batch_size'
๐ With shorter commands, itโs like xvc p s -s preprocessing d a --params 'params.json::batch_size', and this doesnโt look like ffmpeg monstrosities.
๐ฒ In any case, this is a backward-incompatible change. This should wait for v0.7 along with ECS changes.
๐ข ECS changes are not user-visible, but these are. Certainly needs a minor version update.
๐ Then, okay, letโs keep the current ones for this version and think about updating them in a future version.
๐ข Okay. Letโs finish up and weโll create a separate invisible subcommand to ask questions to the Xvc repo for completions.
๐ We completed completions for the common command structure. Now, we need a way to show certain info after certain commands. A tab after xvc p r -p should show pipeline names, for example.
๐ข Umm, yeah. And these should be as quick as possible. They shouldnโt check Git or any other things.
๐ I looked here and there, and the only working example I found is here: https://github.com/clap-rs/clap/blob/master/clap_complete/tests/testsuite/zsh.rs#L248 in clap_complete tests.
๐ข Letโs try to dive in. We can start by cloning the repo, I believe.
๐ข Now, letโs return to clap and its dynamic completions. Last time you said:
๐ The examples are only found in the tests: https://github.com/clap-rs/clap/blob/master/clap_complete/tests/testsuite/engine.rs#L604
and we can try to create those random strings this way.
๐ฆ The issue is that we may not be able to use the derive method to add these custom completers. All examples are using the builder API.
๐ข We should be able to obtain the end result from derives and modify them to use these custom completers, but letโs try to use add = ArgValueCompleter first.
๐ It looks like we have another problem. We need to add a rust-toolchain.toml file to the project, you know, to keep it on the stable channel.
๐ข Ah, yeah, we now use multiple channels. Letโs do that.
๐ข Iโm trying to add this to the --from-ref option of Xvc. Itโs not running anything. The custom completer should return a random string, but it doesnโt.
๐ฆ Maybe test with a constant first.
๐ข It didnโt work that way either.
๐ Letโs do a cargo clean.
๐ข Nothing has changed.
๐ Letโs take a look at the output of xvc completions:
xvc completions
...
'(--skip-git)--from-ref=[Checkout the given Git reference (branch, tag, commit etc.) before performing the Xvc operation. This runs \`git checkout <given-value>\` before running the command]:FROM_REF:_default' \
...
๐ข This is the only place --from-ref is mentioned and, as far as I can see, there is nothing that calls a dynamic command here.
๐ Umm, right. Thereโs something weird here. Maybe we lack the ArgExt trait or something.
๐ข It should be turned on by clap-complete with its unstable-dynamic feature, but who knows.
๐ It didnโt work.
๐ข ArgExt is available, but it isnโt being used.
๐ I think I found the answer in https://jj-vcs.github.io/jj/latest/install-and-setup/#command-line-completion:
source <(COMPLETE=zsh xvc)
is the command we should use.
๐ข It doesnโt produce a completion script, though.
๐ We have this in jj/cli/src/cli_util.rs:
if env::var_os("COMPLETE").is_some() {
return handle_shell_completion(ui, &self.app, &config, &cwd);
}
๐ข I think the whole handle_shell_completion set is written by them. Iโd like to see what jj with COMPLETE=zsh outputs.
๐ Building it to see now.
๐ข As expected, it calls a function:
โฏ COMPLETE=zsh target/debug/jj
#compdef jj
function _clap_dynamic_completer_jj() {
local _CLAP_COMPLETE_INDEX=$(expr $CURRENT - 1)
local _CLAP_IFS=$'\n'
local completions=("${(@f)$( \
_CLAP_IFS="$_CLAP_IFS" \
_CLAP_COMPLETE_INDEX="$_CLAP_COMPLETE_INDEX" \
COMPLETE="zsh" \
/Users/iex/github.com/etc/jj/target/debug/jj -- ${words} 2>/dev/null \
)}")
if [[ -n $completions ]]; then
_describe 'values' completions
fi
}
compdef _clap_dynamic_completer_jj jj
๐ Now we should make it the same; the shell must call xvc to get the completions. Thatโs how all these will work.
๐ข Our goal now is to make a random string output from the --from-ref completion.
๐ The plan is to make completions work as quickly as possible.
๐ข We have done it. ๐๐ฅณ
๐ Cool. Now we need to fill up all those completion methods.
๐ฆ Yeah. We can start with basic ones and move from there.
๐ข There will probably be architectural changes as well. We cannot just run xvc functions directly. We need to run internal functions, but not through commands. At that point, when the user hits tab, we donโt know which command to run.
๐ Maybe itโs time to move to a Git library. โWhat is the best Git library for Rust?โ
๐ฒ Should we use a Git library?
๐ข It looks like Gitoxide is the default Rust way to interact with Git repositories. We can keep our way of using the Git binary and use this as an experimental way to learn.
๐ฆ Yep. Thatโs a good idea. We can include it in the lib for the time being and start to use it in completions.
๐ข Should we go into completions directly, or do we have anything to update in the working scripts?
๐ Starting with completions is better. One question I have is whether the completions work for subcommands as usual, like in the static completions.
๐ข Yes, they work. We need to add:
source <(COMPLETE=zsh xvc)
to .zshrc, though.
๐ It looks like we can drop the xvc completions command. Weโre just checking the COMPLETE environment variable, and thereโs no need for a separate command in this case.
๐ข Yes, letโs remove that.
๐ Maybe we can employ a completions module for all completion-related functionality. Itโs a separate thing, you know.
๐ข Which completions do we need?
๐ We can just mark them with TODOs now.
๐ข Yes, letโs check where we need completions and what.
๐ I noticed weโre repeating options in XvcFileCLI, and some of the options are missing, e.g., --from-ref and --to-branch.
๐ข Because it can compile into a different binary, and global options donโt work that way. Maybe we can move all these binaries into different files under lib. We can have feature flags to turn off certain features and compile different binaries.
๐ฆ Letโs search for it; I havenโt seen it before: building different binaries with feature flags using cargo.
๐ข There is no clear-cut solution, but it looks like we can move all binaries to the root with the required-features field.
๐ฒ We can postpone this to another release.
๐ Yes, letโs not spend time on this now.
๐ข Should we try making pipeline_name a global option? Itโs repeating everywhere.
๐ That will make it easier to maintain.
๐ข Weโll have to pass pipeline_name to subcommands, though.
๐ I think we can have a set of global options that we can pass. For the time being, thatโs only the pipeline_name.
๐ข Okay. Letโs do this.
๐ A similar option is the step name for pipeline steps.
๐ข Dependencies will need a revamp in the next version anyway. So letโs keep it for now.
๐ฒ Also, the semantics of step-name are different for these commands. step new interprets it as a new name, while step dependency interprets it as an existing name. The first can be renamed to --name, and the second can be --to, as one of its aliases suggests.
๐ข Yes, letโs keep it for now, and weโll continue to work on others.
๐ฆ I want to post a comment in the clap discussions.
๐ข Wrote it. Now letโs build it after changing the pipeline_name.
๐ It compiles. Should we test it?
๐ข I think weโll test after all this completion work is done.
๐ We did most of the strum-related completion.
๐ข Didnโt test them yet, though.
๐ This is Rust. It will work if it compiles, and it compiles.
๐ข Good morning. Yesterday we wrote a proxy server for a job application. It was a pleasing experience, but I wasnโt able to write a dialogue.
๐ It was one of those nice days. I have that feeling in my head that I used it to its full potential.
๐ข So we can do some light work today.
๐ Like completions?
๐ข Yep, letโs fill in some missing pieces there.
๐ Letโs see what those missing pieces are.
๐ข We need to clean up the code comments we copied from jj.
๐ฆ Cleaned up quite a bit and moved everything to main. Itโs a single function call.
๐ข I think we completed all strum-related completions. Now we need to discuss store completions a bit.
๐ They canโt all have the same function like we used for strum-based enums. They will look up different parts of components. For XvcPath, it will be the inner RelativePathBuf; for StorageIdentifier, that will be the names of all recorded storage names and GUIDs. The field weโre going to complete will change from case to case.
๐ฆ They can depend on the same machinery. It will detect .xvc, load a store, and return a field from the component. The first two are the same for all.
๐ข Yep. Letโs write a few TODOs in the code, then.
๐ฆ One thing to discuss is whether we should load all config and root. It may be a bit time-consuming. Just loading the stores should be enough.
๐ข I think so. ECS doesnโt depend on XvcRoot, and we can load stores without loading XvcRoot. We have convenience functions in XvcRoot, but they are for convenience. There is nothing that prevents us from loading stores without loading the root.
๐ฆ Letโs take a look at XvcRootโs loading of these.
๐ข We are progressing towards adding all store completions. In the meantime, I
switched to nushell from zsh. Completions for
nushell require a different crate and it
doesnโt have dynamic completions yet.
๐ We can just complete the completions for this version and add JSON output
for all commands to use in nushell. In the meantime, dynamic completions support
for nushell is likely to be added.
๐ข Umm, yep. Then weโll continue to run tests with zsh for the current version.
๐ run-tests is a zsh file, and
we will continue to use it. We can switch to nushell eventually as we add more
compatibility with it, but letโs not do this now.
๐ข Where were we the last time for completions?
๐ We added xvc_path_completers. Letโs check the TODO list now.
๐ข We still need tracked_targets completions in a few places.
๐ Added those.
๐ข Now we have some strum completers. Letโs finish these up as well.
๐ Ok. They are done as well.
๐ข Now, letโs start adding a storage_identifier completer. It should read all
XvcStorage records and list their names.
๐ Added a storage_identifier completer. Letโs add it to all places where we use
storage_identifiers.
๐ข Now, we need completers for pipeline and step names. These are
straightforward.
๐ Added these. Letโs fill up where they are needed.
๐ข I want to skip some of the fine-grained completions in this version. We can
have a specific completer for --params options for files and params inside,
for example. Or a special completer for directories.
๐ Letโs not forget these. Reading YAML files and extracting hyperparameter
keys for the prompt would be a really good feature for the user.
๐ข I agree. These are good features in general, but we need to ship the current
version as soon as possible.
๐ฆ We can use xvc_path_completer for the tracked directory completer for the
time being. For pipeline update, we can use a ValueHint instead. Itโs not
necessary to use a custom completion.
๐ข For the xvc file copy destination, we can have a file or a directory that we
track and is not available, or we donโt track and is available. Itโs a similar situation
to xvc_path_completer, but we also need to check the local paths. It requires
some more care.
๐ Now we can begin to run the tests.
๐ข Is this building?
๐ It should.
๐ข We also have one bug. xvc shouldnโt print help text when the COMPLETE
environment variable is set.
๐ Umm, yeah, thatโs a blocker.
๐ข Fixed it. We can bump the version and push the changes.
So it probably waits for user input to complete, but it doesnโt have any and
cannot complete it, so it returns an error.
๐ฆ Letโs comment the earlier test out and check if other tests work.
๐ข Yes, they fail the same. When there are no commands to run, xvc returns an
error. Maybe we can change this behavior or handle the error in the
Command::cargo_bin line above.
๐ I checked the code and we donโt handle the โno argumentsโ case anywhere. It
looks like the behavior to return an error code is inherited from clap.
๐ข Updated the error handling code to report a more descriptive
message from the source.
cargo test -p xvc --test test_completions
...
failures:
---- test_completions stdout ----
Output { status: ExitStatus(unix_wait_status(25856)), stdout: "", stderr: "\nthread 'main' panicked at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.20/src/builder/debug_asserts.rs:341:13:\nCommand pipeline: command `export` alias `l` is duplicated\nstack backtrace:\n 0: rust_begin_unwind\n at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library/std/src/panicking.rs:692:5\n 1: core::panicking::panic_fmt\n at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library/core/src/panicking.rs:75:14\n 2: clap_builder::builder::debug_asserts::assert_app\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.20/src/builder/debug_asserts.rs:341:13\n 3: clap_builder::builder::command::Command::_build_self\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.20/src/builder/command.rs:4173:13\n 4: clap_builder::builder::command::Command::_build_recursive\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.20/src/builder/command.rs:4076:9\n 5: clap_builder::builder::command::Command::_build_recursive\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.20/src/builder/command.rs:4078:13\n 6: clap_builder::builder::command::Command::build\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_builder-4.5.20/src/builder/command.rs:4071:9\n 7: clap_complete::env::CompleteEnv<F>::try_complete_\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_complete-4.5.40/src/env/mod.rs:229:9\n 8: clap_complete::env::CompleteEnv<F>::try_complete\n at /Users/iex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/clap_complete-4.5.40/src/env/mod.rs:210:9\n 9: xvc::main\n at ./src/main.rs:18:30\n 10: core::ops::function::FnOnce::call_once\n at... [truncated]
ExitStatus(unix_wait_status(25856))
...
error: test failed, to rerun pass `-p xvc --test test_completions`
๐ข The real issue is when we assert the successful run, at this line:
๐ If you look at the error message carefully, youโll see that this is a
different error. We added an alias to xvc pipeline export with l, which is
a duplicate.
๐ข Oops, yeah.
cargo test -p xvc --test test_completions
...
test test_completions ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.81s
๐ There are some warnings in compilation. Letโs fix these.
๐ข Although I turned off most of the watches, logs are still so large that itโs not possible to view them from the interface. Downloaded the log archive.
๐ฆ We can have different GitHub Actions steps for each test. Claude can help write such a repeating set of steps.
๐ We can at least separate z_test_docs to see if integration tests or that fails.
๐ข Weโll have to add caching for test artifacts to upload them for coverage. Iโm not sure we really need to add that complexity to the process just to avoid downloading the logs.
๐ We can actually move all to Xvc. We need a GitHub Action to run an Xvc pipeline.
๐ข Eventually yes, we should move our testing to Xvc itself. Now, the logs show that there are differences in z_test_docs actually.
๐ When I run the command below, it passes. We may have a different config in GitHub Actions.
$ XVC_TRYCMD_TESTS=storage,file,pipeline,core,start TRYCMD=overwrite rws cargo test --features test-ci -p xvc --test z_test_docs
test z_doc_tests ... ok
...
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.34s
๐ข We donโt have an XVC_TRYCMD_TESTS=storage,file,pipeline,core,start definition in GitHub Actions; letโs add it, bump the version, and try again.
$ cargo set-version "0.6.14-alpha.10"
Upgrading xvc from 0.6.14-alpha.9 to 0.6.14-alpha.10
...
๐ฆ We could also update run-tests.zsh to get a quick response.
๐ข Yep, letโs do that as well.
๐ Dev tests pass, but there are differences in the documents still. For some reason, the local run-tests.zsh doesnโt update xvc/book/src/ref/xvc-storage.md. It only has the help text as a reference, but itโs not updated with the aliases, and it breaks the CI. This is weird but a small issue. Fixed it manually.
๐ข We have an error in the publish action. Letโs fix it and rerun it.
๐ There are two errors. One resulted from forgetting sudo when installing
dependencies. The other was the incorrect name for the OpenSSL library. It should be
libssl-dev instead of openssl-dev. Maybe we can link the command list in
the docs.
๐ข Oops, yes, we should at least keep that in mind.
๐ Iโm checking the most popular crates. getrandom
retrieves a random number from the system. It looks much lighter than the rand
crate.
๐ฆ We can use once_cell to initialize
XvcEntityCounter. We currently
useOnce
for this purpose.
๐ I donโt think it will provide any better features.
๐ฆ For that case, yes, no better features. But the interface is something like:
And this makes, for example, working with XvcRoot much easier. We are passing
Arc<RwLock<XvcRootInner>>> everywhere. This is a heavy price when we only use
it in a read-only manner. We can prevent most of these, when we use a read lock, by using
OnceCell.
๐ XvcConfig can benefit from this as well. We donโt update the config during runs.
๐ข Why do we want to assign it, though? We currently have a config field in
XvcRootInner, and we get a reference to it with the config() method.
๐ Ok. Letโs skip this for now. No need to worry before measuring the performance impact.
๐ข Now, the next version will have a --json output for xvc file list. We
can start working on it or update the Readme file?
๐ What about adding at least command completions for Nushell?
๐ข Letโs read a bit about clap_complete_nushell.
๐ฆ There seems to be a nu-complete command. Letโs check its documentation.
๐ Nothing was found, and Kagi doesnโt help much either.
๐ข There is a completions document for Nushell: https://www.nushell.sh/book/custom_completions.html
๐ There is a tool called carapace to provide completions across shells.
๐ข Its documentation is
thin, and Iโm not sure if it supports dynamic completions out of the box. I
believe instead of adding a carapace setup, we can just write a Nushell
completion script that will use JSON output from the commands and add some
(maybe hidden) utility commands to support it.
๐ There are a set of example scripts in the Nushell repo:
https://github.com/nushell/nu_scripts/tree/main/custom-completions
๐ข The reason I want to write custom completions for Nushell is that it will be
an exercise for the scripting language. gh
completions
are not as scary as a Bash script.
๐ git
completions
are a better example for XVC. They simply run git whenever necessary. We can
start from a static completions command and update this with dynamic
completions manually. It will teach a lot.
๐ข I forked the nu_scripts repo and
will add XVC completions script there.
๐ Then letโs begin by adding Nushell static completions. Shall we add a
command for this?
๐ฆ Reviving the completion command we removed in 0.6.13?
๐ข We shouldnโt list it. We can make a _comp subcommand for the time being
and generate and distribute completions in the repository. When
clap_complete_nushell has the feature parity to provide dynamic completions,
we can remove these commands.
๐ What will we use this for other than generating completions?
๐ข Maybe dynamic completions can call this as well.
๐ Added Nushell static completions to be output using xvc _comp generate-nushell. Letโs bump up the version to 0.6.15.
cargo set-version 0.6.15-alpha.1
Upgrading xvc from 0.6.14 to 0.6.15-alpha.1
...
๐ข I noticed we forgot a line in the CLI command handler that asserts xvc_root_opt.is_some(), and this fails when we run xvc outside of repositories. We need to release this version quickly.
๐ Oops, now, ok, letโs write a static Nushell generator and just release quickly.
๐ฆ Generating completions with
xvc comp generate-nushell
๐ข Completion command is run with comp instead of _comp. Should we rename it?
๐ Renamed it to _comp. Itโs not hidden, but at least we can be sure that it wonโt be misunderstood as a common command.
๐ข Bumping the version again. Now letโs source the generated script and test it.
cargo set-version 0.6.15-alpha.2
Upgrading xvc from 0.6.15-alpha.1 to 0.6.15-alpha.2
...
๐ฆ Yep, it works. We now have completions for Nushell.
๐ข Letโs update the completions documentation.
๐ Done. Now, letโs take a look at CI and see what fails.
๐ข Iโm not sure we use this particular implementation; we just use XvcOutputLine::Info(s), not XvcOutputLine::info(s) anywhere. We can delete these methods actually.
๐ Weโll add JSON output via this particular struct. Can we refactor these to use formatting for JSON, for example? Or use these to output JSON?
๐ฆ We can add a formatter to XvcOutputLine to output structures.
๐ข The enum is now defined as:
#[derive(Clone, Debug)]
pub enum XvcOutputLine {
/// The output that we should be reporting to user
Output(String),
/// For informational messages
Info(String),
/// For debug output to show the internals of Xvc
Debug(String),
/// Warnings that are against some usual workflows
Warn(String),
/// Errors that interrupts a workflow but may be recoverable
Error(String),
/// Panics that interrupts the workflow and ends the program
/// Note that this doesn't call panic! automatically
Panic(String),
/// Progress bar ticks.
/// Self::Info is also used for Tick(1)
Tick(usize),
}
Here, these fields can also have a formatter that will render the string in a particular format. For example, the output can be
XvcOutputLine::Output(XvcJsonFormatter, String)
๐ Iโm not sure this is a good idea. Output already specifies this string as output. We can have a wrapper instead, like,
and we can use the supplied format to render XvcStructuredOutput to an output line with XvcOutputLine::Output. If we donโt provide output as structured, it will be too much error-prone work to convert the current outputs to structured.
๐ฆ The transition will also be gradual. We may not need structured output for most of the commands. We can start with xvc file list and convert others as we go.
๐ข This is sensible. By the way, coverage still didnโt increase. There may be something going on with Codecov or running the test.
cargo test -p xvc --test test_completions
...
test test_completions ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.80s
๐ข Can we make sure the output is a Nushell script and not an error message?
๐ Letโs print it out.
๐ข It looks like when the COMPLETE environment variable is set, it never calls _comp subcommand and never calls those lines.
cargo set-version 0.6.15-alpha.4
Upgrading xvc from 0.6.15-alpha.3 to 0.6.15-alpha.4
...
๐ข Letโs make a release for 0.6.15. Coverage is OK now.
cargo set-version 0.6.15
Upgrading xvc from 0.6.15-alpha.4 to 0.6.15
...
๐ข We need to find a theme for the blog. The current
one breaks Nushell output tables
because the code blocks are too narrow.
๐ https://www.getzola.org/themes/pico/ is an option, but I donโt like its header.
๐ฆ Minimal Dark from the same author looks better: https://kuznetsov17.github.io/minimal-dark/notes/note1/
๐ https://www.getzola.org/themes/no-style-please/ is also an option.
๐ฆ https://halve-z.netlify.app/posts/information/ looks interesting, but there is too much screen estate for the left bar.
๐ข Letโs start by running the site locally first.
๐ There are errors in the configuration. Thatโs weird, but letโs fix these.
๐ข Fixed errors. These are probably related to a newer version. Can we take a look at netlify.toml to see if it downloads the same version?
๐ There are breaking changes in Zola 0.19. Letโs update and push the Netlify config to see the results.
๐ข We need to add language support for Nushell to prevent warnings. Take a look at how to add a syntax file to Zola.
๐ I added
extra_syntaxes_and_themes = ["syntaxes"]
to the [markdown] section and added a syntaxes/nushell.sublime-syntax file copied from https://github.com/kurokirasama/nushell_sublime_syntax. Iโm getting:
Error: Reason: Error while compiling regex '\b(?x: 7z | ?
...
s-to-gdrive | usage | ver | verify | weather | wget-all | which-cd | wifi-info | wifi-pass | xls2csv | ydx | yt-api | ytcli | ytm | z | zi)\b'
Oniguruma error: target of repeat operator is not specified
๐ข The syntax highlighter may be a bit buggy. Letโs try to fix this if itโs a one-off.
๐ Found the bug. There is a ? in the regex that causes it to fail. Now it compiles, and Nushell blocks are colored.
๐ข Cool. Letโs fix the other warnings now. shell and console are not recognized, it looks like.
๐ There is only Bash listed in https://www.getzola.org/documentation/content/syntax-highlighting/.
๐ฆ What do you think about migrating to mdBook? We already maintain mdBook for XVC; what about just moving the site to mdBook?
๐ข I thought about this before, and the only downside is the lack of an RSS feed.
๐ฆ I found this: https://github.com/theowenyoung/mdbook-rss
๐ข Now, this changes everything. We can even move the nedriy.at site to mdBook in this case.
๐ Then, letโs start working on this. The site will be a technical book site in this case.
๐ข We already added Nu support to Zola, and we can just change the theme. This is a blocker in my opinion.
๐ I searched for Nushell highlight.js support, and nothing appears. I think we can just postpone until Nu has more support on this front.
๐ข Yes. Letโs first try this change in the non-technical blog, and we can come back to this issue. Now, weโll update console and shell to bash, I think.
๐ Replaced shell and console with bash.
๐ข There is a file for ggplot that has warnings from earlier incarnations. We also lack syntax highlighters for Vim and Tmux.
๐ There is a sublime-syntax file for Tmux at https://raw.githubusercontent.com/gerardroche/sublime-tmux/refs/heads/master/Tmux.sublime-syntax, but do we need it for a single file?
๐ข Letโs set it to plain text.
๐ Now we only have Mermaid warnings left.
๐ข There should be a diagram at https://emresahin.net/developing-a-gitignore-crate/, but it doesnโt show up. We need a shortcode to show these, like the YouTube shortcode. Now letโs get back to theme selection.
๐ I tested Karzok, but it doesnโt have category and tags support.
๐ข And I tested https://github.com/micahkepe/radion, but the best so far is the apollo theme. Iโm struggling to modify the index page, though. I forgot that I modified the themeโs index.html file. I have content in /content/_index.md and a modified index.html in /themes/anemone/templates/index.html to show the content, tags, categories, etc. It should be fixed now.
๐ Ah, cool. Can we clean the recent duplicate pages now?
๐ Letโs turn to discussing the JSON output changes. We can add another option
to XvcOutputLine, like XvcOutputLine::Json(T: Serialize), that will output
the type using serde_json. It wonโt introduce any other type.
๐ข Yes, but what will T be? Although store structures have Serde
implementations, they are not particularly useful for this.
๐ We can have output types, named like XvcFileListOutput, that will be
converted to strings with serialization.
๐ฆ We do something similar in xvc pipeline export and import commands. We
use
XvcPipelineSchema
and XvcStepSchema just for the import and export commands. Weโll write similar
structs for all JSON output and will use Serde to convert these to strings.
๐ข Unlike the import and export commands, we have optional fields in the
output, though. I donโt want content digests to appear in JSON output if they
are not required.
๐ข We donโt need another crate for this. Serde has the
skip_serializing_if attribute
for fields. We can add Option::is_none as a method to these to skip outputting None
fields. All those fields, in this case, will be optional.
๐ This is fine. We already use structs to format the xvc file list output. We
can just use them to output JSON.
๐ Is there a way to implement Default for CLI structs?
๐ข There is a way if we start from the configuration, not just files. The default
configuration is a TOML document. We can make it an XvcConfiguration struct and
load and store it with confy.
๐ We have a cascading set of configurations, but maybe we can start from the
struct and serialize/deserialize it on demand.
๐ฒ I donโt think we need to update xvc-config at the moment. Itโs working, and
we donโt need to alter its inner workings in the near future.
๐ข I agree. We can use the config crate when we need to update and have
enough time to work on this.
๐ข We can add type checking to xvc.pyโs command-line handler. Currently, it builds a command line manually from the given options and parses it with clap. Itโs error-prone.
๐ What are the options, though? xvc.py is just a wrapper around xvc, and that was the easiest way to get it working. We can list all options manually in the headers as documentation, but it will be harder to maintain.
๐ข Once we start doing it, weโll find a good way to simplify and shorten it.
๐ Letโs start to work on xvc file track, then.
๐ข Worked on it a bit, and I decided itโs not worth it at the moment. We need to supply default values for most of the options. Maintaining a separate list of default values may not be feasible; it will be error-prone in a different way.
๐ข Tests are passing; we can merge the PR. But our commit hook to check the CHANGELOG doesnโt work. Thatโs weird; we donโt get any errors when the CHANGELOG is not in the push set.
/// Copy a file from the local machine to the remote.
pub fn copy_to_remote(
local_file: &str,
remote_name: &str,
remote_destination: &str,
) -> Result<(), RcloneError> {
copy(
"/",
local_file,
&get_remote_name(remote_name),
remote_destination,
)
}
/// Copy a file from the remote to the local machine.
pub fn copy_to_local(
local_destination: &str,
remote_name: &str,
remote_file: &str,
) -> Result<(), RcloneError> {
copy(
&get_remote_name(remote_name),
remote_file,
"/",
local_destination,
)
}
๐ It looks like thatโs all we need. We can organize the commands differently, but these examples are enough to use librclone. It seems rather straightforward.
๐ข As the new version is updated, we can go back to the project. Whatโs the next step?
๐ We can continue working on rclone.
๐ข Umm, ok. Letโs try to focus on adding another storage type.
โ #๐ป ADD rclone storage type (2025-04-24 06:27)
๐ข I think the first option is to run the commands from the command line. We can just use a modified generic storage type without trying to make it fast.
๐ Letโs make it run first, you say?
๐ข Yes, letโs make it run first and then we can think about making it run fast.
๐ข Letโs discuss how to move Xvc forwardโmaybe we can write a post to Reddit and the Rust forum in the meantime.
๐ I think the next step is rclone remotes. It will allow us to use all remote storages supported by Rclone, which is a nice feature.
๐ข Donโt you think we need to publish the current version to Reddit and the forum?
๐ We can do that as well.
๐ฆ Adding rclone remote must be a straightforward task.
๐ข We need to understand rclone paths, but overall, yes. Weโll just need to get the remote name, like drive://, and a path, like my-xvc-storage, and build paths with these.
๐ What are the commands?
๐ข We need to learn how to upload files from local to remote and how to download these files. We can also list the files and get files as well.
๐ฒ How about adding a paths.txt to folders in remotes to show which paths the files in 0.jpg belong to? This will change the remote cache structure a bit. We will have a reverse index of files and they will be findable.
๐ข Whatโs the reason for this?
๐ฒ When I upload a file to Drive with only the content hash, I lose track of the actual path. This is not desirable. We can add a file to the directory, called paths.txt, to get the paths for a file.
๐ข This may prove to be a feat, though; adding these XvcPaths to a file requires a lookup.
๐ Maybe a JSON file? It might be possible to look up a path with a JSON file, and it will be easier to parse.
๐ฒ I donโt think the issue is about parsing, though. We can just have a plain text file that lists the paths. Itโs a text file, which is the most compatible across all storages.
๐ข Storages, you mean.
๐ฒ Ugh, yeah. If I have a file called Alan Watts but I only have the content, this file will be immensely useful.
๐ข This makes XvcCachePath and XvcPath coupled. Architecture-wise, it may not be a good thing, though.
๐ Also, there may be common storages for multiple repositories.
๐ฒ Umm, thatโs a good point. I donโt think the architecture will be much compromised, though. We already keep the file paths and their cache paths somewhere.
๐ข Cache paths are generated from the content, but any number of paths can point to a single path in the cache. If I have 1 million copies of the same file, will I add all these files to the paths.txt you mentioned?
๐ฒ Thatโs a good point too. We can have a limit, like 1,000 or something, not to make these files too big.
๐ข Instead of this, we can store the output of xvc file list at the storage root and allow looking up the files that way.
๐ฒ It has the same problem, though; if we have a million files, their list will be too large.
๐ข There can be a manual command, like xvc file index --to storage, that will show content hashes and paths of each file. We can also add URLs to files if possible.
๐ฒ No one will use it when itโs manual, though.
๐ข We can add functionality to update this index when we send a file, though. ๐ฒ So, after each send, weโll update the index for the repository on that storage. Is that correct?
๐ข Not after each send. After each send session, maybe.
๐ We can have an incremental way of updating the index, like we do in ECS?
๐ข It will be overkill for this functionality and add too much noise to the storage.
๐ฒ Letโs keep this discussion here, but I also want to have an index merge or index cleanup mechanism for the entity generator and the ECS.
๐ข We can have a โmerge indicesโ functionality in ECS. That will remove all older entity-generator files and merge all store files.
๐ Removing older entity files is easy, but what about merging the store files?
๐ข Itโs easy too. Weโll just load all event logs from the directory, remove all other files, and save the event log to a file.
๐ Will this be manual or automatic?
๐ข I think the first version can be manual, something like xvc fsck merge-store-files or something like that. We can notify the user if the number of files is > 10,000 or something like that. I donโt think we need to make it automatic unless we measure the impact of these files. There is no point in trying to do it at every command.
๐ Then weโll have two new commands for the next version?
๐ข I think we can just add rclone remote now and release it, then make changes in the ECS for this new xvc fsck command.
๐ Can the name be doctor or something? Or util? Or can we add a top-level merge indices command?
๐ข xvc doctor seems like a better alternative. We can have a diagnose subcommand as well to check for possible inconsistencies. xvc doctor merge-store-files is a better command.
๐ฒ Will we use d for this command?
๐ข No need to add a single-letter command for this, I believe. It shouldnโt be required to run frequently.
๐ Hmm, ok. What do we need to know for rclone remote?
๐ฒ I noticed we donโt have the xvc storage remove command implemented yet. Maybe we can start from that.
๐ข Hmm, yeap. Letโs start by implementing that first. We can add the rclone command next.
๐ Will we use a feature flag for rclone? It will run the command only with an external binary.
๐ข Itโs better to have a feature flag. I think we can add a feature flag for rsync remote as well.
๐ We can use the generic one to update the feature flag.
๐ข I think the only two items of information we need for rclone are the remote name and the remote directory. Will we make these required?
๐ข I think sending Alt keys in Ghostty needs some love. Letโs start with it as an easy task for the day.
๐ While checking macos-option-as-alt as a potential source of the problem, I spent time adjusting the Ghostty icon. I changed the app icon. This is how I spend my time being extremely productive.
๐ข Weird. The Option as alt key setting is fine.
๐ Actually, the Alt key works; the reason we cannot make panes larger is that Alt-Right and Alt-Left are not bound to this.
๐ข You may be right, yes. Then, whatโs the key to enlarge a pane?
๐ฆ List all the keys. Check the keys. You should have done this already.
๐ resize-pane has keys, but they conflict with C-Right, etc., which are macOS display selection keys. I defined M-S-Right, etc., to resize and M-C-Right, etc., to swap the panes. Defining new keys with M-Sโฆ
๐ข We can set keys to swap windows too, maybe to M-C-PageDown, etc. M-PageDown now moves between windows.
๐ Letโs take a look at the command options:
swap-window [-d] [-s src-window] [-t dst-window]
(alias: swapw)
This is similar to link-window, except the source and destination windows are swapped. It is an error if no window exists at src-window. If -d is given, the new window
does not become the current window.
If -s is omitted and a marked pane is present (see select-pane -m), the window containing the marked pane is used rather than the current window.
This dialog is about converting ColQwen2 to the ONNX format.
๐ข Now, I have two classes. This one is a copy of the ONNX Patcher thatโs used to convert ColQwen2 to ONNX format. But this one is valid only for the underlying model, that is Qwen2VLForConditionalGeneration, and ColQwen2 also has some modifications to call it.
๐ What are these modifications?
๐ข The forward method looks something like this:
๐ How about the inner_forward method? Does it just directly call Qwen2VLForConditionalGenerationโs forward?
๐ข No, it has some conditionals:
if inputs_embeds is None:
inputs_embeds = self.model.embed_tokens(input_ids)
if pixel_values is not None:
pixel_values = pixel_values.type(self.visual.get_dtype())
image_embeds = self.visual(pixel_values, grid_thw=image_grid_thw)
image_mask = (input_ids == self.config.image_token_id).unsqueeze(-1).expand_as(inputs_embeds)
image_embeds = image_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
inputs_embeds = inputs_embeds.masked_scatter(image_mask, image_embeds)
if pixel_values_videos is not None:
pixel_values_videos = pixel_values_videos.type(self.visual.get_dtype())
video_embeds = self.visual(pixel_values_videos, grid_thw=video_grid_thw)
video_mask = (input_ids == self.config.video_token_id).unsqueeze(-1).expand_as(inputs_embeds)
video_embeds = video_embeds.to(inputs_embeds.device, inputs_embeds.dtype)
inputs_embeds = inputs_embeds.masked_scatter(video_mask, video_embeds)
if attention_mask is not None:
attention_mask = attention_mask.to(inputs_embeds.device)
outputs = self.model(
input_ids=None,
position_ids=position_ids,
attention_mask=attention_mask,
past_key_values=past_key_values,
inputs_embeds=inputs_embeds,
use_cache=use_cache,
output_attentions=output_attentions,
output_hidden_states=output_hidden_states,
return_dict=return_dict,
)
hidden_states = outputs[0]
return hidden_states
๐ฆ The patcher only modifies the past_key_values_args and moves them to a DynamicCache. There are no other changes for patching.
๐ข But the return types are also different. Qwen2VLForConditionalGeneration.forward returns a Union[Tuple, Qwen2VLCausalLMOutputWithPast], but ColQwen2.forward returns a torch.Tensor.
๐ How is that torch.Tensor calculated from the return type of Qwen2VLForConditionalGeneration? โ
๐ฆ There are multiple return types in Qwen2VLForConditionalGeneration. Itโs determined by the return_dict argument.
if not return_dict:
output = (logits,) + outputs[1:]
return (loss,) + output if loss is not None else output
return Qwen2VLCausalLMOutputWithPast(
loss=loss,
logits=logits,
past_key_values=outputs.past_key_values,
hidden_states=outputs.hidden_states,
attentions=outputs.attentions,
rope_deltas=self.rope_deltas,
)
๐ Whatโs that argument in ColQwen2?
๐ข Itโs passed from the caller; itโs a kwarg.
๐ Is there any modification to this in the ONNX patcher?
๐ข Nope.
๐ Then we can consider it as the default. Whatโs the default?
๐ข The default is None. Hence it returns (logits,) + outputs[1:].
๐ Then, logits are the first parameter by default.
๐ข Yes, we can assume this.
๐ What does ColQwen2 do with these logits?
๐ฆ By the way, it calls inner_forward with use_cache=False and output_hidden_states=True. What do these change in Qwen2VLForConditionalGeneration?
๐ข These hidden states are actually output. In ColQwen2.forward, the inner_forward call is actually:
๐ I think we can leave that post-processing for the time being. We only need multi-vector embeddings for FastEmbed.
๐ข Maybe itโs convertible to a forward method that we can use with ONNX.
๐ Letโs see how this scoring works, then.
๐ข score_multi_vector receives two tensors or tensor lists and compares query vectors with passage vectors. Itโs a rather straightforward implementation that requires Torch, but not Transformers.
๐ In theory, we can also convert this to an ONNX model.
๐ฆ We can also write a custom model for this.
๐ข It has two for loops for comparisons. Can we convert all of these?
๐ฆ The loop indices can be seen as dynamic_axes, and itโs possible to convert the whole thing as a Torch model, then use torch.onnx.export just as we do for the model itself.
๐ข I see, but I donโt think thatโs what we must do now.
๐ Yes, letโs skip that for the time being and convert the model itself. Weโll have multivectors for patches and queries at the end.
๐ข So, weโll keep the processing part, send BatchFeature objects that are output from the processor, and send this to two models: one for images and one for text.
๐ Yep, thatโs the plan. In the end, weโll have two ONNX models that require BatchFeatures.
๐ข Then, weโll modify past_key_values in this argument to use DynamicCache.
๐ Yes, thatโs alright. We can start by moving past_key_values_converter to a method in PatchedColQwen2.
๐ข past_key_values wasnโt used much, so I completely removed it. I also began to use processor outputs as dummy input in the exporter. However, when using BatchFeature, we get:
RuntimeError: Only tuples, lists and Variables are supported as JIT inputs/outputs. Dictionaries and strings are also accepted, but their usage is not recommended. Here, received an input of unsupported type: BatchFeature
๐ So, we can try Dynamo first, I think. If that doesnโt work, we can just collect items as tensors and build up a BatchFeature inside the patcher.
๐ข Letโs try dynamo=True for this first.
๐ฆ This time, itโs about BatchFeature again, but the error is different: KeyError: 'Indexing with integers is not available when using Python based feature extractors'
๐ In this case, we can just create BatchFeature inside the patcher.