Skip to content

Commit

Permalink
allow installing multiple modules from a single package (nushell#33)
Browse files Browse the repository at this point in the history
related to 
- nushell#28
 
this will supersede nushell#28

## Description
Adds support for `$.modules` field to package.nuon. Similar to
`$.scripts`, this allows installing modules (both files and directories)
from custom locations.

> **Note**
> for Nupm, a package can be a collection of modules and scripts, this
PR comes closer to that goal

Another change is that the default package module (`package-name/` dir)
and script (`package-name.nu` file) are not required. You can have a
package that has _only_ the `$.modules:` and `$.scripts:` fields in
package.nuon.
  • Loading branch information
kubouch committed Oct 19, 2023
1 parent a4a1ca9 commit f428826
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 37 deletions.
100 changes: 63 additions & 37 deletions nupm/install.nu
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,20 @@ def install-scripts [
]: list<path> -> nothing {
each {|script|
let src_path = $pkg_dir | path join $script
let dst_path = $scripts_dir | path join $script

if ($src_path | path type) != file {
throw-error "script_not_found" $"Script ($src_path) does not exist"
}

if (($scripts_dir
| path join ($script | path basename)
| path type) == file
and (not $force)
) {
throw-error "package_already_installed" (
if $force {
rm --recursive --force $dst_path
}

if ($dst_path | path type) == file and (not $force) {
throw-error "script_already_installed" (
$"Script ($src_path) is already installed in"
+ $" ($scripts_dir). Use `--force` to override the package."
+ $" ($scripts_dir). Use `--force` to override it."
)
}

Expand All @@ -61,6 +62,41 @@ def install-scripts [
null
}

# Install list of modules into a directory
#
# Input: Modules taken from 'package.nuon'
def install-modules [
pkg_dir: path # Package directory
modules_dir: path # Target directory where to install
--force(-f): bool # Overwrite already installed modules
]: list<path> -> nothing {
each {|module|
let src_path = $pkg_dir | path join $module
let dst_path = $modules_dir | path join $module

if not ($src_path | path exists) {
throw-error "module_not_found" $"Module ($src_path) does not exist"
}

if $force {
rm --recursive --force $dst_path
}

if ($dst_path | path exists) == file and (not $force) {
throw-error "module_already_installed" (
$"Module ($src_path) is already installed in"
+ $" ($modules_dir). Use `--force` to override it."
)
}

log debug $"installing module `($src_path)` to `($modules_dir)`"
cp -r $src_path $modules_dir
}

null
}


# Install package from a directory containing 'project.nuon'
def install-path [
pkg_dir: path # Directory (hopefully) containing 'package.nuon'
Expand All @@ -74,44 +110,34 @@ def install-path [

match $package.type {
"module" => {
let mod_dir = $pkg_dir | path join $package.name
let default_name = $package.name

if ($mod_dir | path type) != dir {
throw-error "invalid_module_package" (
$"Module package '($package.name)' does not"
+ $" contain directory '($package.name)'"
)
if ($pkg_dir | path join $default_name | path exists) {
[ $default_name ]
} else {
[]
}
| append ($package.modules? | default [])
| install-modules $pkg_dir (module-dir --ensure) --force $force

let module_dir = module-dir --ensure
let destination = $module_dir | path join $package.name

if $force {
rm --recursive --force $destination
}

if ($destination | path type) == dir {
throw-error "package_already_installed" (
$"Package ($package.name) is already installed."
+ "Use `--force` to override the package"
)
}

cp --recursive $mod_dir $module_dir

if $package.scripts? != null {
log debug $"installing scripts for package ($package.name)"

$package.scripts
| install-scripts $pkg_dir (script-dir --ensure) --force $force
}
$package.scripts?
| default []
| install-scripts $pkg_dir (script-dir --ensure) --force $force
},
"script" => {
log debug $"installing scripts for package ($package.name)"
let default_name = $"($package.name).nu"

[ ($pkg_dir | path join $"($package.name).nu") ]
if ($pkg_dir | path join $default_name | path exists) {
[ $default_name ]
} else {
[]
}
| append ($package.scripts? | default [])
| install-scripts $pkg_dir (script-dir --ensure) --force $force

$package.modules?
| default []
| install-modules $pkg_dir (module-dir --ensure) --force $force
},
"custom" => {
let build_file = $pkg_dir | path join "build.nu"
Expand Down
12 changes: 12 additions & 0 deletions tests/mod.nu
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ export def install-module [] {
}
}

export def install-module-nodefault [] {
with-nupm-home {
cd tests/packages/spam_module_nodefault

nupm install --path .
assert ([$env.NUPM_HOME modules nodefault ] | path join | path exists)
assert ([$env.NUPM_HOME modules nodefault mod.nu]
| path join
| path exists)
}
}

export def install-custom [] {
with-nupm-home {
cd tests/packages/spam_custom
Expand Down
6 changes: 6 additions & 0 deletions tests/packages/spam_module_nodefault/package.nuon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
name: spam_module_nodefault,
type: module,
version: "0.1.0"
modules: src/nodefault
}
3 changes: 3 additions & 0 deletions tests/packages/spam_module_nodefault/src/nodefault/mod.nu
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export def main [] {
"No default module!"
}

0 comments on commit f428826

Please sign in to comment.