|
| 1 | +" If no valid $NODE or systemwide node.js: build node.js dependency |
| 2 | +function! spacevim#plug#nodejs#build(info) |
| 3 | + if !spacevim#load('programming') |
| 4 | + echom "nodejs layer requires the 'programming' layer to build. Add 'programming' layer to init.spacevim" |
| 5 | + return |
| 6 | + endif |
| 7 | + if g:spacevim.os.windows |
| 8 | + echom 'Building Node.js automatically on Windows is untested and likely to fail, PR welcome' |
| 9 | + execute('AsyncRun -mode=term -pos=tab @ .\\vcbuild openssl-no-asm') |
| 10 | + return |
| 11 | + endif |
| 12 | + if (!exists('$CC') && executable('gcc') != 1) || executable('make') != 1 || executable('python3') != 1 |
| 13 | + echom 'Unable to build Node.js, requires a C++ compiler, make, and python3' |
| 14 | + return |
| 15 | + endif |
| 16 | + |
| 17 | + echom 'Building Node.js...' |
| 18 | + let ninja_flag = '' |
| 19 | + let jobs_flag = '' |
| 20 | + if executable('ninja') |
| 21 | + let ninja_flag=' --ninja' |
| 22 | + else |
| 23 | + " Determine number of cores/threads for make -j, ninja autodetects |
| 24 | + let num_threads = 4 |
| 25 | + if executable('lscpu') |
| 26 | + let result = system("lscpu | grep -E '?^(CPU\\(s\\):|Thread\\(s\\) per core:)' | tr -s ' ' | cut -f 2 -d:") |
| 27 | + if !v:shell_error |
| 28 | + let num_threads = join(split(result), '*') |
| 29 | + endif |
| 30 | + endif |
| 31 | + let jobs_flag = ' -j '.num_threads |
| 32 | + endif |
| 33 | + |
| 34 | + " Build intermediate files to temp, vim will delete folder on exit |
| 35 | + let s:cwd = getcwd() |
| 36 | + let temp_dir = fnamemodify(tempname(), ':p:h') |
| 37 | + call mkdir(temp_dir.'/out', 'p') |
| 38 | + if getftype('out') =~# 'link' |
| 39 | + call system('rm out') |
| 40 | + endif |
| 41 | + call system('ln -s '.temp_dir.'/out out') |
| 42 | + call system('./configure'.ninja_flag.' > '.temp_dir.'/nodejs_configure.log') |
| 43 | + execute('AsyncRun -mode=term -pos=tab -program=make -post=call\ spacevim\\#plug\\#nodejs\\#postbuild(code) @'.jobs_flag) |
| 44 | +endfunction |
| 45 | + |
| 46 | +function! spacevim#plug#nodejs#postbuild(exit_code) |
| 47 | + execute 'tcd' fnameescape(s:cwd) |
| 48 | + unlet s:cwd |
| 49 | + if a:exit_code == 0 |
| 50 | + call system('rm -r deps/icu-tmp node') |
| 51 | + call rename('out/Release/node', 'node') |
| 52 | + let pathsep = g:spacevim.os.windows ? ';' : ':' |
| 53 | + let $PATH = g:plug_home.'/node'.pathsep.$PATH |
| 54 | + |
| 55 | + " This sets up corepack/npm links the same as `make install` does |
| 56 | + call system('ln -s deps/corepack/dist/corepack.js corepack') |
| 57 | + call system('ln -s deps/npm/bin/npm-cli.js npm') |
| 58 | + call system('ln -s deps/npm/bin/npx-cli.js npx') |
| 59 | + call system('node corepack enable') |
| 60 | + endif |
| 61 | + call system('rm out') |
| 62 | + tcd - |
| 63 | +endfunction |
| 64 | + |
| 65 | +" Check for Node.js >= v16.10 |
| 66 | +function! s:isNodeJsVersionSufficient(node) |
| 67 | + if executable(a:node) == 1 |
| 68 | + let node_version = system(a:node.' --version') |
| 69 | + let node_version_parts = map(filter(split(node_version, '\v\ze\.|v'), 'v:val =~# "\\v\\d+"'), 'matchstr(v:val, "\\v\\d+")') |
| 70 | + if len(node_version_parts) >= 2 && (node_version_parts[0] > 16 || (node_version_parts[0] == 16 && node_version_parts[1] >= 10)) |
| 71 | + return 1 |
| 72 | + endif |
| 73 | + endif |
| 74 | + return 0 |
| 75 | +endfunction |
| 76 | + |
| 77 | +" Will do the following checks in order of precedence: |
| 78 | +" -Use $NODE or $NODE/node if they exist and are executable |
| 79 | +" -check for node as vim-plug plugin (user-specific) |
| 80 | +" -check for system-wide install of node |
| 81 | +" -If all above fail will get node as vim-plug plugin and build it |
| 82 | +" Changes $PATH to include node path |
| 83 | +function! spacevim#plug#nodejs#isBuildRequired() |
| 84 | + let pathsep = g:spacevim.os.windows ? ';' : ':' |
| 85 | + " Prefer $NODE override |
| 86 | + if exists('$NODE') && s:isNodeJsVersionSufficient('$NODE') |
| 87 | + let $PATH = fnamemodify('$NODE', ':h').pathsep.$PATH |
| 88 | + return 0 |
| 89 | + endif |
| 90 | + " Prefer user plugin Node.js if it exists |
| 91 | + if s:isNodeJsVersionSufficient(g:plug_home.'/node/node') |
| 92 | + let $PATH = g:plug_home.'/node'.pathsep.$PATH |
| 93 | + return 0 |
| 94 | + endif |
| 95 | + " Last check for system-wide Node.js |
| 96 | + if s:isNodeJsVersionSufficient('node') |
| 97 | + return 0 |
| 98 | + endif |
| 99 | + return 1 |
| 100 | +endfunction |
0 commit comments