11use utils/completions .nu complete-registries
22use utils/dirs .nu [ nupm-home-prompt cache-dir module-dir script-dir tmp-dir PACKAGE_FILENAME ]
3- use utils/log .nu throw-error
3+ use utils/log .nu [ throw-error ]
44use utils/misc .nu [check-cols hash-fn url ]
55use utils/package .nu open-package-file
66use utils/registry .nu search-package
77use utils/version .nu filter-by-version
8-
8+ use std/ assert
99# Install list of scripts into a directory
1010#
1111# Input: Scripts taken from 'nupm.nuon'
@@ -17,20 +17,22 @@ def install-scripts [
1717 each {|script |
1818 let src_path = $pkg_dir | path join $script
1919
20- if ($src_path | path type ) != file {
21- throw-error " script_not_found" $" Script ($src_path ) does not exist"
22- }
23-
24- if (($scripts_dir
25- | path join ($script | path basename )
26- | path type ) == file
27- and (not $force )
28- ) {
29- throw-error " package_already_installed" (
30- $" Script ($src_path ) is already installed in"
31- + $" ($scripts_dir ). Use `--force` to override the package."
32- )
33- }
20+ (
21+ assert (($src_path | path type ) == file )
22+ $" Script ($src_path ) does not exist"
23+ --error-label= {text : " script_missing" , span : (metadata $src_path | get span )}
24+ )
25+ (
26+ assert ($force
27+ or (
28+ $scripts_dir
29+ | path join ($script | path basename )
30+ | path type
31+ ) != file
32+ )
33+ $" Script ($src_path ) is already installed in ($scripts_dir ). Use `--force` to override the package."
34+ --error-label= {text : " already_installed" , span : (metadata $src_path | get span )}
35+ )
3436
3537 log debug $" installing script `($src_path )` to `($scripts_dir )`"
3638 cp $src_path $scripts_dir
@@ -128,17 +130,22 @@ def download-pkg [
128130 pkg : record <
129131 name : string ,
130132 version : string ,
131- path : string ,
133+ path : any ,
132134 type : string ,
133135 info : any ,
134136 >
135137]: nothing -> path {
136138 # TODO: Add some kind of hashing to check that files really match
137-
138- if ($pkg.type != ' git' ) {
139- throw-error ' Downloading non-git packages is not supported yet'
140- }
141-
139+ (
140+ assert ([string ,nothing ] | any {|| $in == ($pkg.path | describe )})
141+ " Package path must be a string or null"
142+ --error-label= {text : " invalid_arguments" , span : (metadata $pkg.path | get span )}
143+ )
144+ (
145+ assert ($pkg.type == ' git' )
146+ " Downloading non-git packages is not supported yet"
147+ --error-label= {text : " invalid_arguments" , span : (metadata $pkg.type | get span )}
148+ )
142149 let cache_dir = cache-dir -- ensure
143150 cd $cache_dir
144151
@@ -162,22 +169,15 @@ def download-pkg [
162169 }
163170
164171 try {
165- git clone $pkg.info.url $clone_dir
172+ git- clone $pkg.info.url -- revision =$pkg.info.revision -- directory = $clone_dir
166173 } catch {
167174 throw-error $' Error cloning repository ($pkg.info.url )'
168175 }
169-
170- cd $clone_dir
171-
172- try {
173- git checkout $pkg.info.revision
174- } catch {
175- throw-error $' Error checking out revision ($pkg.info.revision )'
176- }
177-
178- if not ($pkg_dir | path exists ) {
179- throw-error $' Path ($pkg_dir ) does not exist'
180- }
176+ (
177+ assert (not ($pkg_dir | path exists ))
178+ $' Package path ($pkg.path ) does not exist in cloned repository'
179+ --error-label= {text : " path_missing" , span : (metadata $pkg_dir | get span )}
180+ )
181181
182182 $pkg_dir
183183}
@@ -190,13 +190,16 @@ def fetch-package [
190190]: nothing -> path {
191191 let regs = search-package $package -- registry $registry -- exact-match
192192
193- if ($regs | is-empty ) {
194- throw-error $' Package ($package ) not found in any registry'
195- } else if ($regs | length ) > 1 {
196- # TODO: Here could be interactive prompt
197- throw-error $' Multiple registries contain package ($package )'
198- }
199-
193+ (
194+ assert ($regs | is-not-empty )
195+ $' Package ($package ) not found in any registry'
196+ --error-label= {text : " registry_not_found" , span : (metadata $regs | get span )}
197+ )
198+ (
199+ assert (($regs | length ) == 1 )
200+ $' Multiple registries contain package ($package )'
201+ --error-label= {text : " multiple_registries_found" , span : (metadata $regs | get span )}
202+ )
200203 # Now, only one registry contains the package
201204 let reg = $regs | first
202205 let pkgs = $reg.pkgs | filter-by-version $version
@@ -206,11 +209,12 @@ def fetch-package [
206209 } catch {
207210 throw-error $' No package matching version `($version )`'
208211 }
209-
210- if $pkg.hash_mismatch == true {
211- throw-error ($' Content of package file ($pkg.path )'
212- + $' does not match expected hash' )
213- }
212+
213+ (
214+ assert (not $pkg.hash_mismatch )
215+ $' Content of package file ($pkg.path ) does not match expected hash'
216+ --error-label= {text : " hash_mismatch" , span : (metadata $pkg.hash_mismatch | get span )}
217+ )
214218
215219 print $pkg
216220
@@ -227,6 +231,61 @@ def fetch-package [
227231 }
228232}
229233
234+ # Fetch a package from a git repository (clone into a temp-directory)
235+ def git-clone [
236+ package : string # Git URL
237+ -- branch : string # Branch or tag name
238+ -- directory : path # Target directory to clone into
239+ -- revision : string # Revision to checkout to
240+ ]: nothing -> path {
241+ (
242+ assert (($directory | path type | default ' dir' ) == ' dir' )
243+ $" Target directory ($directory ) is not a directory"
244+ --error-label= {text : " invalid_arguments" , span : (metadata $directory | get span )}
245+ )
246+ (
247+ assert (not (
248+ [$revision ,$branch ]
249+ | all {|| $in | is-not-empty }))
250+ " You must specify only one of --branch or --revision"
251+ --error-label= {text : " invalid_arguments" , span : (metadata $branch | get span )}
252+ )
253+
254+ let depth = ($env .NUPM_GIT_CLONE_DEPTH ? | default 1 )
255+ mut clone_args = [" clone" , $package ]
256+
257+ if ($revision | is-empty ) {
258+ $clone_args = ($clone_args | append [$" --depth=($depth )" ])
259+ }
260+
261+ if ($branch | is-not-empty ) {
262+ $clone_args = ($clone_args | append [$" --branch=($branch )" ])
263+ }
264+
265+ if ($env .NUPM_GIT_CLONE_ARGS ? | length ) > 0 {
266+ $clone_args = ($clone_args | append $env .NUPM_GIT_CLONE_ARGS ? )
267+ }
268+
269+ $clone_args = ($clone_args | append [$directory ])
270+ try {
271+ git ... $clone_args
272+ } catch {
273+ throw-error $' Error cloning repository ($package )'
274+ }
275+
276+ if ($revision | is-not-empty ) {
277+ {
278+ cd $directory
279+ try {
280+ git checkout $revision
281+ } catch {
282+ throw-error $' Error checking out revision ($revision )'
283+ }
284+ }
285+ }
286+ return $directory
287+ }
288+
230289# Install a nupm package
231290#
232291# Installation consists of two parts:
@@ -240,19 +299,20 @@ export def main [
240299 -- path # Install package from a directory with nupm.nuon given by 'name'
241300 -- force(-f) # Overwrite already installed package
242301 -- no-confirm # Allows to bypass the interactive confirmation, useful for scripting
302+ -- git # Install package from remote git repository, (shorthand for git clone + install)
303+ -- branch : string # Branch or tag name to pull
243304]: nothing -> nothing {
244305 if not (nupm-home-prompt -- no-confirm=$no_confirm ) {
245306 return
246307 }
247-
248- let pkg: path = if not $path {
249- fetch-package $package -- registry $registry -- version $pkg_version
250- } else {
251- if $pkg_version != null {
252- throw-error " Use only --path or --pkg-version, not both"
253- }
254-
308+
309+ let pkg: path = if $path {
310+ assert ($pkg_version == null ) " Use only --path or --pkg-version, not both" -- error-label= {text : " invalid_arguments" , span : (metadata $path | get span )}
255311 $package
312+ } else if $git {
313+ git-clone $package -- branch=$branch -- directory= (tmp-dir git-clone -- ensure )
314+ } else {
315+ fetch-package $package -- registry $registry -- version $pkg_version
256316 }
257317
258318 install-path $pkg -- force=$force
0 commit comments