switch from bat to ps1
authorAJ ONeal <coolaj86@gmail.com>
Sun, 28 Jun 2020 07:26:32 +0000 (01:26 -0600)
committerAJ ONeal <aj@therootcompany.com>
Sun, 28 Jun 2020 12:17:57 +0000 (12:17 +0000)
13 files changed:
README.md
_webi/bootstrap.ps1 [new file with mode: 0644]
_webi/packages.js
_webi/releases.js
_webi/template.ps1 [new file with mode: 0644]
_webi/test.js
_webi/ua-detect.js
_webi/webi.bat
_webi/webi.ps1 [new file with mode: 0644]
_webi/webi.ps1.bat [new file with mode: 0644]
node/install.ps1 [new file with mode: 0644]
node/releases.js
pathman/install.ps1 [new file with mode: 0644]

index f83b77647e55d7fab5ddddf5f030ac9a4d49d859..6d9a43b397d386c17c50667d1b9887bd20562253 100644 (file)
--- a/README.md
+++ b/README.md
@@ -252,3 +252,32 @@ webi_post_install       # Runs `webi_add_path $pkg_dst_bin`
 - [ ] Support arbitrary git urls (i.e. `@github.com/node/node`)
   - (maybe `ghi node/node` for github specifically)
 - [ ] Support git as an archive format
+
+# Windows Notes
+
+```bat
+set WEBI_HOST=https://webinstall.dev
+```
+
+Windows 10 has curl too!?
+
+```bat
+curl.exe -sL -A "MS" https://webinstall.dev/node | powershell
+```
+
+And it's easy enough to ignore the execution policy
+
+```bat
+powershell -ExecutionPolicy Bypass install.ps1
+```
+
+And if we want something that looks as complicated as we expect Windows to be,
+historically, we have options:
+
+```bat
+powershell "Invoke-Expression ( Invoke-WebRequest -UseBasicParsing https://webinstall.dev/node ).Contents"
+```
+
+```bat
+powershell ( Invoke-WebRequest -UseBasicParsing https://webinstall.dev/node ).Contents | powershell
+```
diff --git a/_webi/bootstrap.ps1 b/_webi/bootstrap.ps1
new file mode 100644 (file)
index 0000000..c01089b
--- /dev/null
@@ -0,0 +1,42 @@
+# If a command returns an error, halt the script.
+$ErrorActionPreference = 'Stop'
+
+# Ignore progress events from cmdlets so Invoke-WebRequest is not painfully slow
+$ProgressPreference = 'SilentlyContinue'
+
+# Switch to userprofile
+pushd $Env:USERPROFILE
+
+# Make paths if needed
+if (!(Test-Path -Path .local\bin))
+{
+    New-Item -Path .local\bin -ItemType Directory
+}
+
+# {{ baseurl }}
+# {{ version }}
+
+# Enter path
+pushd .local\bin
+
+# TODO SetStrictMode
+# TODO Test-Path variable:global:Env:WEBI_HOST ???
+IF(!$Env:WEBI_HOST)
+{
+    $Env:WEBI_HOST = "https://webinstall.dev"
+}
+
+# Fetch webi.bat
+Invoke-WebRequest "$Env:WEBI_HOST/packages/_webi/webi.ps1.bat" -OutFile webi.bat
+Invoke-WebRequest "$Env:WEBI_HOST/packages/_webi/webi.ps1" -OutFile webi.ps1
+
+popd
+
+# Run webi.bat
+& .\.local\bin\webi.bat {{ exename }}
+
+# Run pathman to set up the folder
+& "$Env:USERPROFILE\.local\bin\pathman.exe" add "$Env:USERPROFILE\.local\.bin"
+
+# Done
+popd
index b6ed22123ba4254db5fe97d92c42ac70161d0516..279e94056eb4f605b65062c923d18324c2cb080c 100644 (file)
@@ -38,7 +38,7 @@ pkgs.create = function (Pkgs, basepath) {
     var yash = path.join(basepath, node, 'package.yash');
     var curlbash = path.join(basepath, node, 'install.sh');
     var readme = path.join(basepath, node, 'README.md');
-    var winstall = path.join(basepath, node, 'install.bat');
+    var winstall = path.join(basepath, node, 'install.ps1');
     return Promise.all([
       fs.promises
         .readFile(readme, 'utf-8')
@@ -80,7 +80,7 @@ pkgs.create = function (Pkgs, basepath) {
         // no winstaller
         winstall = '';
         if ('ENOENT' !== e.code && 'ENOTDIR' !== e.code) {
-          console.error("failed to read '" + node + "/install.bat'");
+          console.error("failed to read '" + node + "/install.ps1'");
           console.error(e);
         }
       })
index dc30ce1600fb0cf8afd6ce38d5f32b587a832e97..83eeb14ab41fa9948b821e04273e824d31578ba0 100644 (file)
@@ -166,3 +166,61 @@ Releases.renderBatch = function (
         });
     });
 };
+
+Releases.renderPowerShell = function (
+  pkgdir,
+  rel,
+  { baseurl, pkg, tag, ver, os, arch, formats }
+) {
+  if (!Array.isArray(formats)) {
+    formats = [];
+  }
+  if (!tag) {
+    tag = '';
+  }
+  return fs.promises
+    .readFile(path.join(pkgdir, 'install.ps1'), 'utf8')
+    .then(function (installTxt) {
+      var vers = rel.version.split('.');
+      var v = {
+        major: vers.shift() || '',
+        minor: vers.shift() || '',
+        patch: vers.join('.').replace(/[+\-].*/, ''),
+        build: vers
+          .join('.')
+          .replace(/[^+\-]*/, '')
+          .replace(/^-/, '')
+      };
+      return fs.promises
+        .readFile(path.join(__dirname, 'template.ps1'), 'utf8')
+        .then(function (tplTxt) {
+          var pkgver = pkg + '@' + ver;
+          return tplTxt
+            .replace(
+              /^(#)?\$Env:WEBI_HOST\s*=.*/im,
+              "$Env:WEBI_HOST = '" + baseurl + "'"
+            )
+            .replace(
+              /^(#)?\$Env:WEBI_PKG\s*=.*/im,
+              "$Env:WEBI_PKG = '" + pkgver + "'"
+            )
+            .replace(
+              /^(#)?\$Env:PKG_NAME\s*=.*/im,
+              "$Env:PKG_NAME = '" + pkg + "'"
+            )
+            .replace(
+              /^(#)?\$Env:WEBI_VERSION\s*=.*/im,
+              "$Env:WEBI_VERSION = '" + rel.version + "'"
+            )
+            .replace(
+              /^(#)?\$Env:WEBI_PKG_URL\s*=.*/im,
+              "$Env:WEBI_PKG_URL = '" + rel.download + "'"
+            )
+            .replace(
+              /^(#)?\$Env:WEBI_PKG_FILE\s*=.*/im,
+              "$Env:WEBI_PKG_FILE = '" + rel.name + "'"
+            )
+            .replace(/{{ installer }}/, installTxt);
+        });
+    });
+};
diff --git a/_webi/template.ps1 b/_webi/template.ps1
new file mode 100644 (file)
index 0000000..1ccc5c6
--- /dev/null
@@ -0,0 +1,37 @@
+# If a command returns an error, halt the script.
+$ErrorActionPreference = 'Stop'
+
+# Ignore progress events from cmdlets so Invoke-WebRequest is not painfully slow
+$ProgressPreference = 'SilentlyContinue'
+
+$Env:WEBI_HOST = 'https://webinstall.dev'
+#$Env:WEBI_PKG = 'node@lts'
+#$Env:PKG_NAME = node
+#$Env:WEBI_VERSION = v12.16.2
+#$Env:WEBI_PKG_URL = "https://.../node-....zip"
+#$Env:WEBI_PKG_FILE = "node-v12.16.2-win-x64.zip"
+
+# Switch to userprofile
+pushd $Env:USERPROFILE
+
+# Make paths if needed
+if (!(Test-Path -Path Downloads))
+{
+    New-Item -Path Downloads -ItemType Directory
+}
+if (!(Test-Path -Path .local\bin))
+{
+    New-Item -Path .local\bin -ItemType Directory
+}
+if (!(Test-Path -Path .local\opt))
+{
+    New-Item -Path .local\opt -ItemType Directory
+}
+
+# {{ baseurl }}
+# {{ version }}
+
+{{ installer }}
+
+# Done
+popd
index 947fbb14756d9a0a5c838f1200f73aa29c228cf4..d45b87fb0eb4acfd126835a29f84ddac720496cb 100755 (executable)
@@ -46,7 +46,7 @@ nodes.forEach(function (node) {
 var maxLen = 0;
 console.info('');
 console.info('Has the necessary files?');
-['README.md', 'releases.js', 'install.sh', 'install.bat']
+['README.md', 'releases.js', 'install.sh', 'install.ps1']
   .map(function (node) {
     maxLen = Math.max(maxLen, node.length);
     return node;
@@ -106,7 +106,7 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
       arch,
       formats: formats
     }).catch(function () {}),
-    Releases.renderBatch(pkgdir, rel, {
+    Releases.renderPowerShell(pkgdir, rel, {
       baseurl: 'https://webinstall.dev',
       pkg: pkgname,
       tag: pkgtag || '',
@@ -117,13 +117,13 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
     }).catch(function () {})
   ]).then(function (scripts) {
     var bashTxt = scripts[0];
-    var batTxt = scripts[1];
+    var ps1Txt = scripts[1];
     var bashFile = 'install-' + pkgname + '.sh';
-    var batFile = 'install-' + pkgname + '.bat';
+    var ps1File = 'install-' + pkgname + '.ps1';
 
     if (debug) {
       bashTxt = (bashTxt || 'echo ERROR').replace(/#set -x/g, 'set -x');
-      batTxt = (batTxt || 'echo ERROR').replace(
+      ps1Txt = (ps1Txt || 'echo ERROR').replace(
         /REM REM todo debug/g,
         'REM todo debug'
       );
@@ -131,8 +131,8 @@ Releases.get(path.join(process.cwd(), pkgdir)).then(function (all) {
     console.info('Has the necessary files?');
     fs.writeFileSync(bashFile, bashTxt, 'utf-8');
     console.info('\tNEEDS MANUAL TEST: bash %s', bashFile);
-    fs.writeFileSync(batFile, batTxt, 'utf-8');
-    console.info('\tNEEDS MANUAL TEST: cmd.exe %s', batFile);
+    fs.writeFileSync(ps1File, ps1Txt, 'utf-8');
+    console.info('\tNEEDS MANUAL TEST: powershell.exe %s', ps1File);
     console.info('');
   });
 });
index fb0a316e9d00ac45e7b2db7f2379870a1f1639c8..27d772a7113a3bfb25a78b8e7fea2c045b3b0868 100644 (file)
@@ -10,7 +10,7 @@ function getOs(ua) {
     return 'android';
   } else if (/iOS|iPhone|Macintosh|Darwin|OS\s*X|macOS|mac/i.test(ua)) {
     return 'macos';
-  } else if (/Microsoft|Windows|win32|win|PowerShell/.test(ua)) {
+  } else if (/^ms$|Microsoft|Windows|win32|win|PowerShell/i.test(ua)) {
     // 'win' must be tested after 'darwin'
     return 'windows';
   } else if (/Linux|curl|wget/i.test(ua)) {
index ed56295c89fd2905bcc098b78fad6f19f2554539..6023b9226a5a8e467df914bda53b0936ee3d9119 100644 (file)
@@ -22,7 +22,7 @@ pushd "%userprofile%" || goto :error
   .\.local\bin\pathman add ".local\bin" || goto :error
 
   echo downloading and installing %1
-  powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/%1/install.bat -OutFile %1-webinstall.bat || goto :error
+  powershell $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest https://webinstall.dev/packages/%1/install.ps1 -OutFile %1-webinstall.bat || goto :error
 
   rem TODO only add if it's not in there already
   PATH .local\bin;%PATH%
diff --git a/_webi/webi.ps1 b/_webi/webi.ps1
new file mode 100644 (file)
index 0000000..3e30242
--- /dev/null
@@ -0,0 +1,51 @@
+# If a command returns an error, halt the script.
+$ErrorActionPreference = 'Stop'
+
+# Ignore progress events from cmdlets so Invoke-WebRequest is not painfully slow
+$ProgressPreference = 'SilentlyContinue'
+
+# TODO get arch
+$Env:WEBI_UA = 'Windows/10 amd64'
+$exename = $args[0]
+
+# Switch to userprofile
+pushd $Env:USERPROFILE
+
+# Make paths if needed
+if (!(Test-Path -Path .local\bin))
+{
+    New-Item -Path .local\bin -ItemType Directory
+}
+if (!(Test-Path -Path .local\opt))
+{
+    New-Item -Path .local\opt -ItemType Directory
+}
+# TODO windows version of mktemp -d
+if (!(Test-Path -Path .local\tmp))
+{
+    New-Item -Path .local\tmp -ItemType Directory
+}
+
+if (!(Test-Path -Path .local\bin\pathman.exe))
+{
+    & curl.exe -fsSL -A "$Env:WEBI_UA" "$Env:WEBI_HOST/packages/pathman/install.ps1" -o .\.local\tmp\pathman-setup.ps1
+    powershell .\.local\tmp\pathman-setup.ps1
+    # TODO del .\.local\tmp\pathman-setup.bat
+}
+
+# {{ baseurl }}
+# {{ version }}
+
+# Fetch <whatever>.ps1
+echo "$Env:WEBI_HOST/packages/$exename/install.ps1"
+echo "$exename.install.ps1"
+
+# TODO detect formats
+# Invoke-WebRequest -UserAgent "Windows amd64" "$Env:WEBI_HOST/api/installers/$exename.ps1?formats=zip,tar" -OutFile ".\.local\tmp\$exename.install.ps1"
+& curl.exe -fsSL -A "$Env:WEBI_UA" "$Env:WEBI_HOST/api/installers/$exename.ps1?formats=zip,tar" -o .\.local\tmp\$exename.install.ps1
+
+# Run <whatever>.ps1
+powershell .\.local\tmp\$exename.install.ps1
+
+# Done
+popd
diff --git a/_webi/webi.ps1.bat b/_webi/webi.ps1.bat
new file mode 100644 (file)
index 0000000..17915ad
--- /dev/null
@@ -0,0 +1 @@
+powershell -ExecutionPolicy Bypass .\.local\bin\webi.ps1 %1
diff --git a/node/install.ps1 b/node/install.ps1
new file mode 100644 (file)
index 0000000..64a6096
--- /dev/null
@@ -0,0 +1,47 @@
+# Fetch archive
+
+IF (!(Test-Path -Path "$Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE"))
+{
+    # TODO: arch detection
+    echo "Downloading $Env:PKG_NAME from $Env:WEBI_PKG_URL to $Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE"
+    #Invoke-WebRequest https://nodejs.org/dist/v12.16.2/node-v12.16.2-win-x64.zip -OutFile node-v12.16.2-win-x64.zip
+    & curl.exe -A "$Env:WEBI_UA" -fsSL "$Env:WEBI_PKG_URL" -o "$Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE.part"
+    & move "$Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE.part" "$Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE"
+}
+
+IF (!(Test-Path -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERSION"))
+{
+    echo "Installing $Env:PKG_NAME"
+    # TODO: temp directory
+
+    # Enter opt
+    pushd .local\tmp
+
+        echo "Remove leftover node-v* stuffs"
+        Remove-Item -Path "node-v*" -Recurse -ErrorAction Ignore
+
+        # Unpack archive
+        # Windows BSD-tar handles zip. Imagine that.
+        echo "Unpacking $Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE"
+        & tar xf "$Env:USERPROFILE\Downloads\$Env:WEBI_PKG_FILE"
+        Get-ChildItem "node-v*"
+
+        # Settle unpacked archive into place
+        echo "New Name: $Env:PKG_NAME-v$Env:WEBI_VERSION"
+        Get-ChildItem "node-v*" | Select -f 1 | Rename-Item -NewName "$Env:PKG_NAME-v$Env:WEBI_VERSION"
+        echo "New Location: $Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERSION"
+        Move-Item -Path "$Env:PKG_NAME-v$Env:WEBI_VERSION" -Destination "$Env:USERPROFILE\.local\opt"
+
+    # Exit tmp
+    popd
+}
+
+echo "Versioning $Env:PKG_NAME"
+Remove-Item -Path "$Env:USERPROFILE\.local\opt\node" -Recurse -ErrorAction Ignore
+Copy-Item -Path "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME-v$Env:WEBI_VERSION" -Destination "$Env:USERPROFILE\.local\opt\$Env:PKG_NAME" -Recurse
+
+# make npm not act stupid about which node to use... ugh (this should be the default)
+& .\.local\opt\node\npm.cmd --scripts-prepend-node-path=true config set scripts-prepend-node-path true
+
+# Add to path
+& "$Env:USERPROFILE\.local\bin\pathman.exe" add .local\opt\node
index 44f4cad0f99269b9971a991e06db1765706af312..04c6a548fde3db748f064a22656ed0ed2f9a7105 100644 (file)
@@ -5,7 +5,7 @@ var map = {
   // OSes
   osx: 'macos',
   linux: 'linux',
-  win: 'windows',
+  win: 'windows', // windows
   sunos: 'sunos',
   aix: 'aix',
   // CPU architectures
@@ -104,7 +104,7 @@ function getAllReleases(request) {
 
         if ('macos' === os) {
           r.download += '-darwin';
-        } else if ('win' === os) {
+        } else if ('windows' === os) {
           r.download += '-win';
         } else {
           r.download += '-' + os;
diff --git a/pathman/install.ps1 b/pathman/install.ps1
new file mode 100644 (file)
index 0000000..dd729e4
--- /dev/null
@@ -0,0 +1 @@
+curl.exe -fsSL -A "$Env:WEBI_UA" "https://rootprojects.org/pathman/dist/windows/amd64/pathman.exe" -o "$Env:USERPROFILE\.local\bin\pathman.exe"