-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow online installation of packages (#56)
## Registries _See the newly added registry.nuon file for more specific info about the registry format._ This PR adds a new concept: **registry**. Registries are .nuon files containing a list of packages, their versions, and how they should be installed. Currently, registry can contain two kinds of packages: * `local` -- installed from local file system * `git` -- installed from remote Git repository The list of recognized registries is stored in `$env.NUPM_REGISTRIES` as a record of name: path pairs. That way, users can maintain their collection of sources from where they want to install packages. Not sure if this will be the final way to pass available registries to nupm, but should be good enough for early testing. ## Online Installation If a package is to be installed from a Git repository, the repository is cached in `$env.NUPM_CACHE` to avoid re-cloning the same repository all the time. Once cloned, the local path of the cloned repository is passed to the installer, as if you called `nupm install --path=...`. One important missing feature is some kind of file integrity check. One step at a time... ## Versions If a registry contains multiple versions (common scenario), by default, the newest one is installed. "Newest" currently means sorting the versions alphabetically and taking the last one. If `--pkg-version` is specified, nupm tries to install the exact version passed to this option. This needs better version matching (e.g., version 0.2 matching 0.2.1 etc.), but again, one step at a time... ## New command `nupm search` searches for packages in registries without installing them. I thought this would be useful to have early on. ## Try it out From the repository root: ```nushell overlay use nupm/ nupm install nu-git-manager # use nu-git-manager * # ... ``` ## TODO - [x] Remove debug stuff - [x] Nicer / more informative prints - [x] (can be done over time) Rewrite https://github.com/nushell/nupm/blob/main/index.nuon to fit the registry format, move it to its own repo - It would be a single-file repository - Package authors would put PRs there whenever they update their package - [x] Tests ## After - better version matching => `0.2` shouldn't match `0.2.1` - file integrity checks
- Loading branch information
Showing
14 changed files
with
417 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
use utils/completions.nu complete-registries | ||
use utils/registry.nu search-package | ||
|
||
# Search for a package | ||
export def main [ | ||
package # Name, path, or link to the package | ||
--registry: string@complete-registries # Which registry to use (either a name | ||
# in $env.NUPM_REGISTRIES or a path) | ||
--pkg-version(-v): string # Package version to install | ||
]: nothing -> table { | ||
search-package $package --registry $registry --version $pkg_version | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export def complete-registries [] { | ||
$env.NUPM_REGISTRIES? | default {} | columns | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Misc unsorted helpers | ||
|
||
# Make sure input has requested columns and no extra columns | ||
export def check-cols [ | ||
what: string, | ||
required_cols: list<string> | ||
--extra-ok | ||
--missing-ok | ||
]: [ table -> table, record -> record ] { | ||
let inp = $in | ||
|
||
if ($inp | is-empty) { | ||
return $inp | ||
} | ||
|
||
let cols = $inp | columns | ||
if not $missing_ok { | ||
let missing_cols = $required_cols | where {|req_col| $req_col not-in $cols } | ||
|
||
if not ($missing_cols | is-empty) { | ||
throw-error ($"Missing the following required columns in ($what):" | ||
+ $" ($missing_cols | str join ', ')") | ||
) | ||
} | ||
} | ||
|
||
if not $extra_ok { | ||
let extra_cols = $cols | where {|col| $col not-in $required_cols } | ||
|
||
if not ($extra_cols | is-empty) { | ||
throw-error ($"Got the following extra columns in ($what):" | ||
+ $" ($extra_cols | str join ', ')") | ||
) | ||
} | ||
} | ||
|
||
$inp | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Utilities related to nupm registries | ||
|
||
# Search for a package in a registry | ||
export def search-package [ | ||
package: string # Name of the package | ||
--registry: string # Which registry to use | ||
--version: any # Package version to install (string or null) | ||
--exact-match # Searched package name must match exactly | ||
] -> table { | ||
let registries = if (not ($registry | is-empty)) and ($registry in $env.NUPM_REGISTRIES) { | ||
# If $registry is a valid column in $env.NUPM_REGISTRIES, use that | ||
{ $registry : ($env.NUPM_REGISTRIES | get $registry) } | ||
} else if (not ($registry | is-empty)) and ($registry | path exists) { | ||
# If $registry is a path, use that | ||
let reg_name = $registry | path parse | get stem | ||
{ $reg_name: $registry } | ||
} else { | ||
# Otherwise use $env.NUPM_REGISTRIES | ||
$env.NUPM_REGISTRIES | ||
} | ||
|
||
let name_matcher: closure = if $exact_match { | ||
{|row| $row.name == $package } | ||
} else { | ||
{|row| $package in $row.name } | ||
} | ||
|
||
# Collect all registries matching the package and all matching packages | ||
let regs = $registries | ||
| items {|name, path| | ||
# Open registry (online or offline) | ||
let registry = if ($path | path type) == file { | ||
open $path | ||
} else { | ||
try { | ||
let reg = http get $path | ||
|
||
if local in $reg { | ||
throw-error ("Can't have local packages in online registry" | ||
+ $" '($path)'.") | ||
} | ||
|
||
$reg | ||
} catch { | ||
throw-error $"Cannot open '($path)' as a file or URL." | ||
} | ||
} | ||
|
||
$registry | check-cols --missing-ok "registry" [ git local ] | ignore | ||
|
||
# Find all packages matching $package in the registry | ||
let pkgs_local = $registry.local? | ||
| default [] | ||
| check-cols "local packages" [ name version path ] | ||
| filter $name_matcher | ||
|
||
let pkgs_git = $registry.git? | ||
| default [] | ||
| check-cols "git packages" [ name version url revision path ] | ||
| filter $name_matcher | ||
|
||
let pkgs = $pkgs_local | ||
| insert type local | ||
| insert url null | ||
| insert revision null | ||
| append ($pkgs_git | insert type git) | ||
|
||
{ | ||
name: $name | ||
path: $path | ||
pkgs: $pkgs | ||
} | ||
} | ||
| compact | ||
|
||
$regs | where not ($it.pkgs | is-empty) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Commands related to handling versions | ||
# | ||
# We might move some of this to Nushell builtins | ||
|
||
# Sort packages by version | ||
def sort-by-version []: table<version: string> -> table<version: string> { | ||
sort-by version | ||
} | ||
|
||
# Check if the target version is equal or higher than the target version | ||
def matches-version [version: string]: string -> bool { | ||
# TODO: Add proper version matching | ||
$in == $version | ||
} | ||
|
||
# Filter packages by version and sort them by version | ||
export def filter-by-version [version: any]: table<version: string> -> table<version: string> { | ||
if $version == null { | ||
$in | ||
} else { | ||
$in | filter {|row| $row.version | matches-version $version} | ||
} | ||
| sort-by-version | ||
} |
Oops, something went wrong.