summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--installer/README.md47
-rw-r--r--installer/mod.ts156
-rw-r--r--installer/test.ts299
-rw-r--r--installer/testdata/args.ts9
-rw-r--r--installer/testdata/echo.ts6
5 files changed, 388 insertions, 129 deletions
diff --git a/installer/README.md b/installer/README.md
index 7c7e9e5a7..6f0435730 100644
--- a/installer/README.md
+++ b/installer/README.md
@@ -4,50 +4,65 @@ Install remote or local script as executables.
## Installation
-`installer` can be install using iteself:
+`installer` can be install using itself:
```sh
deno -A https://deno.land/std/installer/mod.ts deno_installer https://deno.land/std/installer/mod.ts -A
```
-Installer uses `~/.deno/bin` to store installed scripts so make sure it's in `$PATH`
-
-```
-echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.bashrc # change this to your shell
-```
-
## Usage
Install script
```sh
+# remote script
$ deno_installer file_server https://deno.land/std/http/file_server.ts --allow-net --allow-read
-> Downloading: https://deno.land/std/http/file_server.ts
+> [1/1] Compiling https://deno.land/std/http/file_server.ts
>
> ✅ Successfully installed file_server.
+> ~/.deno/bin/file_server
# local script
$ deno_installer file_server ./deno_std/http/file_server.ts --allow-net --allow-read
-> Looking for: /dev/deno_std/http/file_server.ts
+> [1/1] Compiling file:///dev/deno_std/http/file_server.ts
>
> ✅ Successfully installed file_server.
+> ~/.deno/bin/file_server
```
-Use installed script:
+Run installed script:
```sh
$ file_server
HTTP server listening on http://0.0.0.0:4500/
```
-Update installed script
+## Custom installation directory
+
+By default installer uses `~/.deno/bin` to store installed scripts so make sure it's in your `$PATH`.
+
+```
+echo 'export PATH="$HOME/.deno/bin:$PATH"' >> ~/.bashrc # change this to your shell
+```
+
+If you prefer to change installation directory use `-d` or `--dir` flag.
+
+```
+$ deno_installer --dir /usr/local/bin file_server ./deno_std/http/file_server.ts --allow-net --allow-read
+> [1/1] Compiling file:///dev/deno_std/http/file_server.ts
+>
+> ✅ Successfully installed file_server.
+> /usr/local/bin/file_server
+```
+
+## Update installed script
```sh
$ deno_installer file_server https://deno.land/std/http/file_server.ts --allow-net --allow-read
> ⚠️ file_server is already installed, do you want to overwrite it? [yN]
> y
>
-> Downloading: https://deno.land/std/http/file_server.ts
+> [1/1] Compiling file:///dev/deno_std/http/file_server.ts
>
> ✅ Successfully installed file_server.
```
@@ -60,10 +75,14 @@ $ deno_installer --help
Install remote or local script as executables.
USAGE:
- deno https://deno.land/std/installer/mod.ts EXE_NAME SCRIPT_URL [FLAGS...]
+ deno -A https://deno.land/std/installer/mod.ts [OPTIONS] EXE_NAME SCRIPT_URL [FLAGS...]
ARGS:
EXE_NAME Name for executable
SCRIPT_URL Local or remote URL of script to install
- [FLAGS...] List of flags for script, both Deno permission and script specific flag can be used.
+ [FLAGS...] List of flags for script, both Deno permission and script specific
+ flag can be used.
+
+OPTIONS:
+ -d, --dir <PATH> Installation directory path (defaults to ~/.deno/bin)
```
diff --git a/installer/mod.ts b/installer/mod.ts
index f247c6fd3..d7ab125b3 100644
--- a/installer/mod.ts
+++ b/installer/mod.ts
@@ -1,25 +1,34 @@
#!/usr/bin/env deno --allow-all
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-const {
- args,
- env,
- readDirSync,
- mkdirSync,
- writeFile,
- exit,
- stdin,
- chmod,
- remove,
- run
-} = Deno;
+const { env, stdin, args, exit, writeFile, chmod, run } = Deno;
+import { parse } from "../flags/mod.ts";
import * as path from "../fs/path.ts";
import { exists } from "../fs/exists.ts";
+import { ensureDir } from "../fs/ensure_dir.ts";
const encoder = new TextEncoder();
const decoder = new TextDecoder("utf-8");
-const isWindows = Deno.platform.os === "win";
// Regular expression to test disk driver letter. eg "C:\\User\username\path\to"
const driverLetterReg = /^[c-z]:/i;
+const isWindows = Deno.platform.os === "win";
+
+function showHelp(): void {
+ console.log(`deno installer
+ Install remote or local script as executables.
+
+USAGE:
+ deno -A https://deno.land/std/installer/mod.ts [OPTIONS] EXE_NAME SCRIPT_URL [FLAGS...]
+
+ARGS:
+ EXE_NAME Name for executable
+ SCRIPT_URL Local or remote URL of script to install
+ [FLAGS...] List of flags for script, both Deno permission and script specific
+ flag can be used.
+
+OPTIONS:
+ -d, --dir <PATH> Installation directory path (defaults to ~/.deno/bin)
+`);
+}
enum Permission {
Read,
@@ -67,6 +76,20 @@ function getFlagFromPermission(perm: Permission): string {
return "";
}
+function getInstallerDir(): string {
+ // In Windows's Powershell $HOME environmental variable maybe null
+ // if so use $HOMEPATH instead.
+ let { HOME, HOMEPATH } = env();
+
+ const HOME_PATH = HOME || HOMEPATH;
+
+ if (!HOME_PATH) {
+ throw new Error("$HOME is not defined.");
+ }
+
+ return path.join(HOME_PATH, ".deno", "bin");
+}
+
async function readCharacter(): Promise<string> {
const byteArray = new Uint8Array(1024);
await stdin.read(byteArray);
@@ -81,14 +104,6 @@ async function yesNoPrompt(message: string): Promise<boolean> {
return input === "y" || input === "Y";
}
-function createDirIfNotExists(path: string): void {
- try {
- readDirSync(path);
- } catch (e) {
- mkdirSync(path, true);
- }
-}
-
function checkIfExistsInPath(filePath: string): boolean {
// In Windows's Powershell $PATH not exist, so use $Path instead.
// $HOMEDRIVE is only used on Windows.
@@ -120,33 +135,16 @@ function checkIfExistsInPath(filePath: string): boolean {
return false;
}
-function getInstallerDir(): string {
- // In Windows's Powershell $HOME environmental variable maybe null
- // if so use $HOMEPATH instead.
- let { HOME, HOMEPATH } = env();
-
- const HOME_PATH = HOME || HOMEPATH;
-
- if (!HOME_PATH) {
- throw new Error("$HOME is not defined.");
- }
-
- return path.join(HOME_PATH, ".deno", "bin");
+export function isRemoteUrl(url: string): boolean {
+ return /^https?:\/\//.test(url);
}
-function showHelp(): void {
- console.log(`deno installer
- Install remote or local script as executables.
-
-USAGE:
- deno https://deno.land/std/installer/mod.ts EXE_NAME SCRIPT_URL [FLAGS...]
-
-ARGS:
- EXE_NAME Name for executable
- SCRIPT_URL Local or remote URL of script to install
- [FLAGS...] List of flags for script, both Deno permission and script specific
- flag can be used.
-`);
+function validateModuleName(moduleName: string): boolean {
+ if (/^[a-z][\w-]*$/i.test(moduleName)) {
+ return true;
+ } else {
+ throw new Error("Invalid module name: " + moduleName);
+ }
}
async function generateExecutable(
@@ -176,7 +174,7 @@ async function generateExecutable(
}
// generate Shell script
- const template = `#/bin/sh
+ const template = `#!/bin/sh
# ${templateHeader}
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
@@ -200,17 +198,28 @@ exit $ret
export async function install(
moduleName: string,
moduleUrl: string,
- flags: string[]
+ flags: string[],
+ installationDir?: string
): Promise<void> {
- const installerDir = getInstallerDir();
- createDirIfNotExists(installerDir);
+ if (!installationDir) {
+ installationDir = getInstallerDir();
+ }
+ await ensureDir(installationDir);
+
+ // if install local module
+ if (!isRemoteUrl(moduleUrl)) {
+ moduleUrl = path.resolve(moduleUrl);
+ }
- const filePath = path.join(installerDir, moduleName);
+ validateModuleName(moduleName);
+ const filePath = path.join(installationDir, moduleName);
if (await exists(filePath)) {
const msg =
- "⚠️ ${moduleName} is already installed, " +
- "do you want to overwrite it?";
+ "⚠️ " +
+ moduleName +
+ " is already installed" +
+ ", do you want to overwrite it?";
if (!(await yesNoPrompt(msg))) {
return;
}
@@ -218,7 +227,7 @@ export async function install(
// ensure script that is being installed exists
const ps = run({
- args: ["deno", "fetch", moduleUrl],
+ args: ["deno", "fetch", "--reload", moduleUrl],
stdout: "inherit",
stderr: "inherit"
});
@@ -254,44 +263,35 @@ export async function install(
console.log(`✅ Successfully installed ${moduleName}`);
console.log(filePath);
- if (!checkIfExistsInPath(installerDir)) {
- console.log("\nℹ️ Add ~/.deno/bin to PATH");
+ if (!checkIfExistsInPath(installationDir)) {
+ console.log(`\nℹ️ Add ${installationDir} to PATH`);
console.log(
- " echo 'export PATH=\"$HOME/.deno/bin:$PATH\"' >> ~/.bashrc # change" +
+ " echo 'export PATH=\"" +
+ installationDir +
+ ":$PATH\"' >> ~/.bashrc # change" +
" this to your shell"
);
}
}
-export async function uninstall(moduleName: string): Promise<void> {
- const installerDir = getInstallerDir();
- const filePath = path.join(installerDir, moduleName);
-
- if (!(await exists(filePath))) {
- throw new Error(`ℹ️ ${moduleName} not found`);
- }
-
- await remove(filePath);
- if (isWindows) {
- await remove(filePath + ".cmd");
- }
- console.log(`ℹ️ Uninstalled ${moduleName}`);
-}
-
async function main(): Promise<void> {
- if (args.length < 3) {
+ const parsedArgs = parse(args.slice(1), { stopEarly: true });
+
+ if (parsedArgs.h || parsedArgs.help) {
return showHelp();
}
- if (["-h", "--help"].includes(args[1])) {
+ if (parsedArgs._.length < 2) {
return showHelp();
}
- const moduleName = args[1];
- const moduleUrl = args[2];
- const flags = args.slice(3);
+ const moduleName = parsedArgs._[0];
+ const moduleUrl = parsedArgs._[1];
+ const flags = parsedArgs._.slice(2);
+ const installationDir = parsedArgs.d || parsedArgs.dir;
+
try {
- await install(moduleName, moduleUrl, flags);
+ await install(moduleName, moduleUrl, flags, installationDir);
} catch (e) {
console.log(e);
exit(1);
diff --git a/installer/test.ts b/installer/test.ts
index 536e74c4f..c1baa0be1 100644
--- a/installer/test.ts
+++ b/installer/test.ts
@@ -1,13 +1,13 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-const { run, stat, makeTempDir, remove, env } = Deno;
+const { run, stat, makeTempDir, remove, env, readAll } = Deno;
import { test, runIfMain, TestFunction } from "../testing/mod.ts";
-import { assert, assertEquals, assertThrowsAsync } from "../testing/asserts.ts";
+import { assert, assertEquals } from "../testing/asserts.ts";
import { BufReader, EOF } from "../io/bufio.ts";
import { TextProtoReader } from "../textproto/mod.ts";
-import { install, uninstall } from "./mod.ts";
import * as path from "../fs/path.ts";
import * as fs from "../fs/mod.ts";
+import { install, isRemoteUrl } from "./mod.ts";
let fileServer: Deno.Process;
const isWindows = Deno.platform.os === "win";
@@ -37,13 +37,15 @@ function killFileServer(): void {
fileServer.stdout!.close();
}
-function installerTest(t: TestFunction): void {
+function installerTest(t: TestFunction, useOriginHomeDir = false): void {
const fn = async (): Promise<void> => {
await startFileServer();
const tempDir = await makeTempDir();
const envVars = env();
const originalHomeDir = envVars["HOME"];
- envVars["HOME"] = tempDir;
+ if (!useOriginHomeDir) {
+ envVars["HOME"] = tempDir;
+ }
try {
await t();
@@ -58,10 +60,14 @@ function installerTest(t: TestFunction): void {
}
installerTest(async function installBasic(): Promise<void> {
- await install("file_srv", "http://localhost:4500/http/file_server.ts", []);
+ await install(
+ "echo_test",
+ "http://localhost:4500/installer/testdata/echo.ts",
+ []
+ );
const { HOME } = env();
- const filePath = path.resolve(HOME, ".deno/bin/file_srv");
+ const filePath = path.resolve(HOME, ".deno/bin/echo_test");
const fileInfo = await stat(filePath);
assert(fileInfo.isFile());
@@ -71,11 +77,11 @@ installerTest(async function installBasic(): Promise<void> {
/* eslint-disable max-len */
`% This executable is generated by Deno. Please don't modify it unless you know what it means. %
@IF EXIST "%~dp0\deno.exe" (
- "%~dp0\deno.exe" "run" "http://localhost:4500/http/file_server.ts" %*
+ "%~dp0\deno.exe" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
- "deno" "run" "http://localhost:4500/http/file_server.ts" %*
+ "deno" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
)
`
/* eslint-enable max-len */
@@ -85,7 +91,7 @@ installerTest(async function installBasic(): Promise<void> {
assertEquals(
await fs.readFileStr(filePath),
/* eslint-disable max-len */
- `#/bin/sh
+ `#!/bin/sh
# This executable is generated by Deno. Please don't modify it unless you know what it means.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
@@ -94,10 +100,10 @@ case \`uname\` in
esac
if [ -x "$basedir/deno" ]; then
- "$basedir/deno" "run" "http://localhost:4500/http/file_server.ts" "$@"
+ "$basedir/deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
ret=$?
else
- "deno" "run" "http://localhost:4500/http/file_server.ts" "$@"
+ "deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
ret=$?
fi
exit $ret
@@ -106,15 +112,73 @@ exit $ret
);
});
-installerTest(async function installWithFlags(): Promise<void> {
- await install("file_server", "http://localhost:4500/http/file_server.ts", [
- "--allow-net",
- "--allow-read",
- "--foobar"
- ]);
+installerTest(async function installCustomDir(): Promise<void> {
+ const tempDir = await makeTempDir();
+
+ await install(
+ "echo_test",
+ "http://localhost:4500/installer/testdata/echo.ts",
+ [],
+ tempDir
+ );
+
+ const filePath = path.resolve(tempDir, "echo_test");
+ const fileInfo = await stat(filePath);
+ assert(fileInfo.isFile());
+
+ if (isWindows) {
+ assertEquals(
+ await fs.readFileStr(filePath + ".cmd"),
+ /* eslint-disable max-len */
+ `% This executable is generated by Deno. Please don't modify it unless you know what it means. %
+@IF EXIST "%~dp0\deno.exe" (
+ "%~dp0\deno.exe" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
+) ELSE (
+ @SETLOCAL
+ @SET PATHEXT=%PATHEXT:;.TS;=;%
+ "deno" "run" "http://localhost:4500/installer/testdata/echo.ts" %*
+)
+`
+ /* eslint-enable max-len */
+ );
+ }
+
+ assertEquals(
+ await fs.readFileStr(filePath),
+ /* eslint-disable max-len */
+ `#!/bin/sh
+# This executable is generated by Deno. Please don't modify it unless you know what it means.
+basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
+
+case \`uname\` in
+ *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
+esac
+
+if [ -x "$basedir/deno" ]; then
+ "$basedir/deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
+ ret=$?
+else
+ "deno" "run" "http://localhost:4500/installer/testdata/echo.ts" "$@"
+ ret=$?
+fi
+exit $ret
+`
+ /* eslint-enable max-len */
+ );
+});
+
+installerTest(async function installLocalModule(): Promise<void> {
+ let localModule = path.join(Deno.cwd(), "installer", "testdata", "echo.ts");
+ await install("echo_test", localModule, []);
const { HOME } = env();
- const filePath = path.resolve(HOME, ".deno/bin/file_server");
+ const filePath = path.resolve(HOME, ".deno/bin/echo_test");
+ const fileInfo = await stat(filePath);
+ assert(fileInfo.isFile());
+
+ if (isWindows) {
+ localModule = localModule.replace(/\\/g, "\\\\");
+ }
if (isWindows) {
assertEquals(
@@ -122,11 +186,11 @@ installerTest(async function installWithFlags(): Promise<void> {
/* eslint-disable max-len */
`% This executable is generated by Deno. Please don't modify it unless you know what it means. %
@IF EXIST "%~dp0\deno.exe" (
- "%~dp0\deno.exe" "run" "--allow-net" "--allow-read" "http://localhost:4500/http/file_server.ts" "--foobar" %*
+ "%~dp0\deno.exe" "run" "${localModule}" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
- "deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/http/file_server.ts" "--foobar" %*
+ "deno" "run" "${localModule}" %*
)
`
/* eslint-enable max-len */
@@ -136,7 +200,7 @@ installerTest(async function installWithFlags(): Promise<void> {
assertEquals(
await fs.readFileStr(filePath),
/* eslint-disable max-len */
- `#/bin/sh
+ `#!/bin/sh
# This executable is generated by Deno. Please don't modify it unless you know what it means.
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
@@ -145,10 +209,10 @@ case \`uname\` in
esac
if [ -x "$basedir/deno" ]; then
- "$basedir/deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/http/file_server.ts" "--foobar" "$@"
+ "$basedir/deno" "run" "${localModule}" "$@"
ret=$?
else
- "deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/http/file_server.ts" "--foobar" "$@"
+ "deno" "run" "${localModule}" "$@"
ret=$?
fi
exit $ret
@@ -157,26 +221,187 @@ exit $ret
);
});
-installerTest(async function uninstallBasic(): Promise<void> {
- await install("file_server", "http://localhost:4500/http/file_server.ts", []);
+installerTest(async function installWithFlags(): Promise<void> {
+ await install(
+ "echo_test",
+ "http://localhost:4500/installer/testdata/echo.ts",
+ ["--allow-net", "--allow-read", "--foobar"]
+ );
const { HOME } = env();
- const filePath = path.resolve(HOME, ".deno/bin/file_server");
+ const filePath = path.resolve(HOME, ".deno/bin/echo_test");
- await uninstall("file_server");
+ if (isWindows) {
+ assertEquals(
+ await fs.readFileStr(filePath + ".cmd"),
+ /* eslint-disable max-len */
+ `% This executable is generated by Deno. Please don't modify it unless you know what it means. %
+@IF EXIST "%~dp0\deno.exe" (
+ "%~dp0\deno.exe" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" %*
+) ELSE (
+ @SETLOCAL
+ @SET PATHEXT=%PATHEXT:;.TS;=;%
+ "deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" %*
+)
+`
+ /* eslint-enable max-len */
+ );
+ }
- assert(!(await fs.exists(filePath)));
- assert(!(await fs.exists(filePath + ".cmd")));
+ assertEquals(
+ await fs.readFileStr(filePath),
+ /* eslint-disable max-len */
+ `#!/bin/sh
+# This executable is generated by Deno. Please don't modify it unless you know what it means.
+basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
+
+case \`uname\` in
+ *CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
+esac
+
+if [ -x "$basedir/deno" ]; then
+ "$basedir/deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" "$@"
+ ret=$?
+else
+ "deno" "run" "--allow-net" "--allow-read" "http://localhost:4500/installer/testdata/echo.ts" "--foobar" "$@"
+ ret=$?
+fi
+exit $ret
+`
+ /* eslint-enable max-len */
+ );
});
-installerTest(async function uninstallNonExistentModule(): Promise<void> {
- await assertThrowsAsync(
- async (): Promise<void> => {
- await uninstall("file_server");
- },
- Error,
- "file_server not found"
+installerTest(async function installLocalModuleAndRun(): Promise<void> {
+ const localModule = path.join(Deno.cwd(), "installer", "testdata", "echo.ts");
+ await install("echo_test", localModule, ["hello"]);
+
+ const { HOME } = env();
+ const filePath = path.resolve(HOME, ".deno/bin/echo_test");
+ const fileInfo = await stat(filePath);
+ assert(fileInfo.isFile());
+
+ const ps = run({
+ args: ["echo_test" + (isWindows ? ".cmd" : ""), "foo"],
+ stdout: "piped"
+ });
+
+ if (!ps.stdout) {
+ assert(!!ps.stdout, "There should have stdout.");
+ return;
+ }
+
+ let thrown = false;
+
+ try {
+ const b = await readAll(ps.stdout);
+
+ const s = new TextDecoder("utf-8").decode(b);
+
+ assertEquals(s, "hello, foo");
+ } catch (err) {
+ console.error(err);
+ thrown = true;
+ } finally {
+ await remove(filePath);
+ ps.close();
+ }
+
+ assert(!thrown, "It should not throw an error");
+}, true); // set true to install module in your real $HOME dir.
+
+installerTest(async function installAndMakesureItCanRun(): Promise<void> {
+ await install(
+ "echo_test",
+ "http://localhost:4500/installer/testdata/echo.ts",
+ ["hello"]
);
+
+ const { HOME } = env();
+ const filePath = path.resolve(HOME, ".deno/bin/echo_test");
+ const fileInfo = await stat(filePath);
+ assert(fileInfo.isFile());
+
+ const ps = run({
+ args: ["echo_test" + (isWindows ? ".cmd" : ""), "foo"],
+ stdout: "piped"
+ });
+
+ if (!ps.stdout) {
+ assert(!!ps.stdout, "There should have stdout.");
+ return;
+ }
+
+ let thrown = false;
+
+ try {
+ const b = await readAll(ps.stdout);
+
+ const s = new TextDecoder("utf-8").decode(b);
+
+ assertEquals(s, "hello, foo");
+ } catch (err) {
+ console.error(err);
+ thrown = true;
+ } finally {
+ await remove(filePath);
+ ps.close();
+ }
+
+ assert(!thrown, "It should not throw an error");
+}, true); // set true to install module in your real $HOME dir.
+
+installerTest(async function installAndMakesureArgsRight(): Promise<void> {
+ await install(
+ "args_test",
+ "http://localhost:4500/installer/testdata/args.ts",
+ ["arg1", "--flag1"]
+ );
+
+ const { HOME } = env();
+ const filePath = path.resolve(HOME, ".deno/bin/args_test");
+ const fileInfo = await stat(filePath);
+ assert(fileInfo.isFile());
+
+ const ps = run({
+ args: ["args_test" + (isWindows ? ".cmd" : ""), "arg2", "--flag2"],
+ stdout: "piped"
+ });
+
+ if (!ps.stdout) {
+ assert(!!ps.stdout, "There should have stdout.");
+ return;
+ }
+
+ let thrown = false;
+
+ try {
+ const b = await readAll(ps.stdout);
+
+ const s = new TextDecoder("utf-8").decode(b);
+
+ const obj = JSON.parse(s);
+
+ assertEquals(obj[0], "arg1");
+ assertEquals(obj[1], "--flag1");
+ assertEquals(obj[2], "arg2");
+ assertEquals(obj[3], "--flag2");
+ } catch (err) {
+ console.error(err);
+ thrown = true;
+ } finally {
+ await remove(filePath);
+ ps.close();
+ }
+
+ assert(!thrown, "It should not throw an error");
+}, true); // set true to install module in your real $HOME dir.
+
+test(function testIsRemoteUrl(): void {
+ assert(isRemoteUrl("https://deno.land/std/http/file_server.ts"));
+ assert(isRemoteUrl("http://deno.land/std/http/file_server.ts"));
+ assert(!isRemoteUrl("file:///dev/deno_std/http/file_server.ts"));
+ assert(!isRemoteUrl("./dev/deno_std/http/file_server.ts"));
});
runIfMain(import.meta);
diff --git a/installer/testdata/args.ts b/installer/testdata/args.ts
new file mode 100644
index 000000000..484cab5ab
--- /dev/null
+++ b/installer/testdata/args.ts
@@ -0,0 +1,9 @@
+function args(args: string[]) {
+ const map = {};
+ for (let i = 0; i < args.length; i++) {
+ map[i] = args[i];
+ }
+ Deno.stdout.write(new TextEncoder().encode(JSON.stringify(map)));
+}
+
+args(Deno.args.slice(1));
diff --git a/installer/testdata/echo.ts b/installer/testdata/echo.ts
new file mode 100644
index 000000000..62ddd6d05
--- /dev/null
+++ b/installer/testdata/echo.ts
@@ -0,0 +1,6 @@
+function echo(args: string[]) {
+ const msg = args.join(", ");
+ Deno.stdout.write(new TextEncoder().encode(msg));
+}
+
+echo(Deno.args.slice(1));