Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

installer upgrades #512

Merged
merged 40 commits into from
Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
be1d05c
installer: test installed module run correctly
axetroy Jun 19, 2019
13e167c
fix error
axetroy Jun 19, 2019
296e52b
update
axetroy Jun 19, 2019
109924f
update
axetroy Jun 19, 2019
143c03e
update
axetroy Jun 19, 2019
9a44ed6
update
axetroy Jun 19, 2019
b066a4a
add test
axetroy Jun 19, 2019
880dd11
update
axetroy Jun 19, 2019
43cd107
update
axetroy Jun 19, 2019
89bafa1
update
axetroy Jun 19, 2019
d886fdc
update
axetroy Jun 19, 2019
27f6b4f
fix install local module
axetroy Jun 19, 2019
a5f6acc
remove http/file_server.ts test case
axetroy Jun 19, 2019
c695792
merge master
axetroy Jun 19, 2019
153f9c6
add install local module test case
axetroy Jun 19, 2019
f0f5a38
fix test in windows
axetroy Jun 19, 2019
4b92265
add installed local module test case
axetroy Jun 19, 2019
a96d1f2
try fix windows test case
axetroy Jun 19, 2019
38f701d
try fix windows test case
axetroy Jun 19, 2019
f78763e
try fix windows test case
axetroy Jun 19, 2019
c58c512
split installer
bartlomieju Jun 19, 2019
891be4f
fix prompt on subsequent installation
bartlomieju Jun 19, 2019
656d49d
fix bad shebang
bartlomieju Jun 19, 2019
17e46ca
fmt
bartlomieju Jun 19, 2019
7ae9645
lint & fmt
bartlomieju Jun 19, 2019
4706dc6
fix tests
bartlomieju Jun 19, 2019
e266a89
add debug
bartlomieju Jun 19, 2019
a1a317a
update for windows
bartlomieju Jun 19, 2019
341047f
move more stuff to util
bartlomieju Jun 19, 2019
48720e0
review feedback
bartlomieju Jun 20, 2019
1d69620
lint
bartlomieju Jun 20, 2019
4b08554
remove uninstall command
bartlomieju Jun 20, 2019
1460eaa
reset CI
bartlomieju Jun 20, 2019
f8f49c5
fix tests
bartlomieju Jun 20, 2019
40247f3
support -d/--dir argument
bartlomieju Jun 20, 2019
aa71f58
remove console.log
bartlomieju Jun 20, 2019
a7a00e6
reset CI
bartlomieju Jun 20, 2019
24e8c44
fmt
bartlomieju Jun 20, 2019
571354b
factor out isRemoteUrl
bartlomieju Jun 20, 2019
e67a43a
lint
bartlomieju Jun 20, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions installer/install.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#!/usr/bin/env deno --allow-all
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
const { writeFile, chmod, run } = Deno;
import * as path from "../fs/path.ts";
import { exists } from "../fs/exists.ts";
import {
getInstallerDir,
yesNoPrompt,
createDirIfNotExists,
checkIfExistsInPath,
isWindows
} from "./util.ts";

const encoder = new TextEncoder();

enum Permission {
Read,
Write,
Net,
Env,
Run,
All
}

function getPermissionFromFlag(flag: string): Permission | undefined {
switch (flag) {
case "--allow-read":
return Permission.Read;
case "--allow-write":
return Permission.Write;
case "--allow-net":
return Permission.Net;
case "--allow-env":
return Permission.Env;
case "--allow-run":
return Permission.Run;
case "--allow-all":
return Permission.All;
case "-A":
return Permission.All;
}
}

function getFlagFromPermission(perm: Permission): string {
switch (perm) {
case Permission.Read:
return "--allow-read";
case Permission.Write:
return "--allow-write";
case Permission.Net:
return "--allow-net";
case Permission.Env:
return "--allow-env";
case Permission.Run:
return "--allow-run";
case Permission.All:
return "--allow-all";
}
return "";
}

async function generateExecutable(
filePath: string,
commands: string[]
): Promise<void> {
commands = commands.map((v): string => JSON.stringify(v));
// On Windows if user is using Powershell .cmd extension is need to run the
// installed module.
// Generate batch script to satisfy that.
const templateHeader =
"This executable is generated by Deno. Please don't modify it unless you " +
"know what it means.";
if (isWindows) {
const template = `% ${templateHeader} %
@IF EXIST "%~dp0\deno.exe" (
"%~dp0\deno.exe" ${commands.slice(1).join(" ")} %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.TS;=;%
${commands.join(" ")} %*
)
`;
const cmdFile = filePath + ".cmd";
await writeFile(cmdFile, encoder.encode(template));
await chmod(cmdFile, 0o755);
}

// generate Shell script
const template = `#!/bin/sh
# ${templateHeader}
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")

case \`uname\` in
*CYGWIN*) basedir=\`cygpath -w "$basedir"\`;;
esac

if [ -x "$basedir/deno" ]; then
"$basedir/deno" ${commands.slice(1).join(" ")} "$@"
ret=$?
else
${commands.join(" ")} "$@"
ret=$?
fi
exit $ret
`;
await writeFile(filePath, encoder.encode(template));
await chmod(filePath, 0o755);
}

export async function install(
moduleName: string,
bartlomieju marked this conversation as resolved.
Show resolved Hide resolved
moduleUrl: string,
flags: string[]
): Promise<void> {
const installerDir = getInstallerDir();
createDirIfNotExists(installerDir);

const filePath = path.join(installerDir, moduleName);

if (await exists(filePath)) {
const msg =
"⚠️ " +
moduleName +
" is already installed" +
", do you want to overwrite it?";
if (!(await yesNoPrompt(msg))) {
return;
}
}

// ensure script that is being installed exists
const ps = run({
args: ["deno", "fetch", "--reload", moduleUrl],
stdout: "inherit",
stderr: "inherit"
});

const { code } = await ps.status();

if (code !== 0) {
throw new Error("Failed to fetch module.");
}

const grantedPermissions: Permission[] = [];
const scriptArgs: string[] = [];

for (const flag of flags) {
const permission = getPermissionFromFlag(flag);
if (permission === undefined) {
scriptArgs.push(flag);
} else {
grantedPermissions.push(permission);
}
}

// if install local module
if (!/^https?:\/\//.test(moduleUrl)) {
moduleUrl = path.resolve(moduleUrl);
}

const commands = [
"deno",
"run",
...grantedPermissions.map(getFlagFromPermission),
moduleUrl,
...scriptArgs
];

await generateExecutable(filePath, commands);

console.log(`✅ Successfully installed ${moduleName}`);
console.log(filePath);

if (!checkIfExistsInPath(installerDir)) {
console.log("\nℹ️ Add ~/.deno/bin to PATH");
console.log(
" echo 'export PATH=\"$HOME/.deno/bin:$PATH\"' >> ~/.bashrc # change" +
" this to your shell"
);
}
}
Loading