velociraptor
velociraptor copied to clipboard
CLI installation helpers
This feature combines @bcomnes 's local CLI dependencies proposal with our vr install
proposal.
Features
- [ ] #87
- [ ] #88
- [ ] #89
- [ ] #90
- [ ] #91
- [ ] #92
- [ ] #93
The install command
This command has two main purposes:
- allow consumers of CLIs that use Velociraptor to install them with simple commands,
- allow Velociraptor users to locally install CLIs they use in their scripts.
Global install
A new section of vr config files would be used to advertise CLI project's installation command:
# awesomecli/scripts.yaml
install:
entry: ./cli.ts
name: awesomecli
allow: [env, read, write]
scripts:
...
So that users of awesomecli
can install it with a simple command:
$ vr install -g awesomecli[@version]
# Translates to deno install --allow-env --allow-read --allow-write --name awesomecli https://<registry@version>/cli.ts
This new section would use a variant of the config structure already used by scripts
entries:
interface InstallOptions extends Omit<DenoCliOptions, 'watch' | 'inspect' | 'inspectBrk'> {
entry: string;
name?: string;
location?: string;
prompt?: boolean;
seed?: number;
}
Registries
The command would try to resolve the dependency from a default registry (ie deno.land/x/
) unless another registry is manually specified, ie:
$ vr install -g nest:[email protected]
$ vr install -g github:user/[email protected]
Local install
The install command, used without the -g, --global
flag and inside a project with a valid vr configuration, would save the dependency as project-local inside a new section of vr config files:
scripts:
...
dependencies: # Or deps? tools?
somecli:
entry: https://deno.land/x/somecli/cli.ts
allow: [read, write]
...
Where
dependencies
is aRecord<string, InstallOptions>
.
This would happen in two ways:
1. Installing tools that don't use Velociraptor
In this case users can simply replace deno
with vr
in the installation script recommended by the author:
- $ deno install --allow-net --allow-read -n serve https://deno.land/[email protected]/http/file_server.ts
+ $ vr install --allow-net --allow-read -n serve https://deno.land/[email protected]/http/file_server.ts
2. Installing tools that use Velociraptor and advertise their installation commands
Easy, just run:
$ vr install somecli
In this case the dependency entry could be simplified to a specifier+version combination like:
dependencies:
somecli: ^2.3.4
Install location and $PATH
patching
As per @bcomnes 's proposal these dependencies would be installed in a local folder (.bin
? .vr-bin
?) via deno install
's --root
option. When running scripts vr would check whether the .bin
folder exists and is up to date with the dependencies in the config file and deno install
them otherwise. Vr would add the .bin
folder to $PATH
when running scripts.
Run locally installed CLIs
Just like scripts
, dependencies
could be made runnable via the vr run
command:
dependencies:
somecli: ^2.3.4
$ vr run somecli [...args]
# Translates to
$ ./.bin/somecli [...args]
Init command
Using some of the logic from the previous points we could implement the Project scaffolder proposal: a special script name (init
?) could be resolved and run from remote script configurations in order to perform project initialization tasks (à la npm init <package>
):
vr init oak
# Would search for a script in a script configuration in https://deno.land/x/oak/...
# and (if present) execute the `init` script
Potential issues
Discovering advertised install commands from registries could be cumbersome if we have to make one network request for each possible combination of script config file name and extension:
GET https:/deno.land/x/somecli/scripts.yaml
GET https:/deno.land/x/somecli/scripts.yml
GET https:/deno.land/x/somecli/scripts.json
GET https:/deno.land/x/somecli/scripts.ts
GET https:/deno.land/x/somecli/velociraptor.yaml
GET https:/deno.land/x/somecli/velociraptor.yml
GET https:/deno.land/x/somecli/velociraptor.json
GET https:/deno.land/x/somecli/velociraptor.ts
We could mitigate this by restricting the install advertisement functionality to a single file name though.