tool-sync
tool-sync copied to clipboard
groundwork for shellcheck
hello again!
SC has only 1 public release, and well integrated in distro package managers. But it brings up some fun challenges too:
tar tf shellcheck-v0.8.0.linux.x86_64.tar.xz
shellcheck-v0.8.0/LICENSE.txt
shellcheck-v0.8.0/README.txt
shellcheck-v0.8.0/shellcheck
- [ ] tar.xz support (and easy addition of
.zst,.lzmaas needed) - [ ] new asset_name guessing pattern (
${project}-v${version})
The windows zip puts shellcheck.exe in toplevel, so it works for me right away.
For the dir guessing, i attempted suffix trimming:
let platforms = [".x86_64", ".linux"];
let mut raw_asset = asset_name;
for p in platforms {
raw_asset = raw_asset.trim_end_matches(p)
}
vec![
[raw_asset, &exe_name].iter().collect(),
// .... original guesses
but the platforms list, as well as other projects' delimiter styles will make this complex fast. What do you think about using glob for finding the executable?
For xz, i plan to:
- Use early-return in
Archive::fromto avoid rightward drift, and match moretartypes - switch on the
tar_pathextension to use different types astar_decoder, return error for unsupported compression - rename
TarGztype to be more generalTarBall
How do you like this?
cheers
@hdhoang Thanks for writing the detailed implementation plan! The ${project}-v${version} naming scheme is used in hlint as well (another CLI tool I use and would like to support) so it makes sense to support it.
Ideally, I would like to have a separate PR for .xz support. But we need an asset to actually test it and so far shellcheck is the only tool that uses .xz. So, in an ideal world, I'd like to have three separate PRs:
- Support xz (with the early-return and other refactorings as you suggest)
- Support the new project naming scheme
- Support
shellcheck
But we need something to test this so a single PR for this case is acceptable 👌🏻
but the platforms list, as well as other projects' delimiter styles will make this complex fast. What do you think about using glob for finding the executable?
The path part is rather simple: ${project}-v${version}. So I think that glob would be an overkill. We only need to get the version and combine it with the project name.
This should be enough for shellcheck and hlint:
- shellcheck
Tag: v0.8.0 Asset name: shellcheck-v0.8.0.linux.x86_64.tar.xz Asset path: shellcheck-v0.8.0/shellcheck - hlint
Tag: v3.5 Asset name: hlint-3.5-x86_64-linux.tar.gz Asset path: hlint-3.5/hlint
So I imagine, the final function would look like this:
// List of potential paths where an executable can be inside the archive
fn exe_paths(exe_name: &str, asset_name: &str, tool_name: &str, version: &str) -> Vec<PathBuf> {
let exe_name = mk_exe_name(exe_name);
let content_dirs =
mk_asset_dir_name(tool_name, version); // returns two elements here: with 'v' and without 'v' prefix
vec![
[asset_name, &exe_name].iter().collect(),
[&exe_name].iter().collect(),
["bin", &exe_name].iter().collect(),
[asset_name, "bin", &exe_name].iter().collect(),
[content_dir, &exe_name].iter().collect(),
] ... combine with [content_dir, &exe_name] for each content dir
}