Skip to content

Commit

Permalink
Make Deno.execPath a function (denoland#2743)
Browse files Browse the repository at this point in the history
And throws without allow-env
  • Loading branch information
kevinkassimo authored and ry committed Aug 6, 2019
1 parent ccee2f0 commit 4519f9a
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 26 deletions.
9 changes: 8 additions & 1 deletion cli/msg.fbs
Expand Up @@ -77,6 +77,8 @@ union Any {
Truncate,
HomeDir,
HomeDirRes,
ExecPath,
ExecPathRes,
Utime,
WorkerGetMessage,
WorkerGetMessageRes,
Expand Down Expand Up @@ -181,7 +183,6 @@ table StartRes {
cwd: string;
pid: uint32;
argv: [string];
exec_path: string;
main_module: string; // Absolute URL.
debug_flag: bool;
deps_flag: bool;
Expand Down Expand Up @@ -468,6 +469,12 @@ table HomeDirRes {
path: string;
}

table ExecPath {}

table ExecPathRes {
path: string;
}

table Utime {
filename: string;
atime: uint64;
Expand Down
44 changes: 31 additions & 13 deletions cli/ops.rs
Expand Up @@ -212,6 +212,7 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<CliDispatchFn> {
msg::Any::Cwd => Some(op_cwd),
msg::Any::Dial => Some(op_dial),
msg::Any::Environ => Some(op_env),
msg::Any::ExecPath => Some(op_exec_path),
msg::Any::Exit => Some(op_exit),
msg::Any::Fetch => Some(op_fetch),
msg::Any::FetchSourceFile => Some(op_fetch_source_file),
Expand Down Expand Up @@ -354,18 +355,6 @@ fn op_start(
let cwd_off =
builder.create_string(deno_fs::normalize_path(cwd_path.as_ref()).as_ref());

// Use permissions.allows_env() to bypass env request prompt.
let exec_path = if state.permissions.allows_env() {
let current_exe = std::env::current_exe().unwrap();
// Now apply URL parser to current exe to get fully resolved path, otherwise we might get
// `./` and `../` bits in `exec_path`
let exe_url = Url::from_file_path(current_exe).unwrap();
exe_url.to_file_path().unwrap().to_str().unwrap().to_owned()
} else {
"".to_owned()
};
let exec_path = builder.create_string(&exec_path);

let v8_version = version::v8();
let v8_version_off = builder.create_string(v8_version);

Expand Down Expand Up @@ -399,7 +388,6 @@ fn op_start(
v8_version: Some(v8_version_off),
deno_version: Some(deno_version_off),
no_color: !ansi::use_color(),
exec_path: Some(exec_path),
xeval_delim,
..Default::default()
},
Expand Down Expand Up @@ -1787,6 +1775,36 @@ fn op_home_dir(
))
}

fn op_exec_path(
state: &ThreadSafeState,
base: &msg::Base<'_>,
data: Option<PinnedBuf>,
) -> CliOpResult {
assert!(data.is_none());
let cmd_id = base.cmd_id();

state.check_env()?;

let builder = &mut FlatBufferBuilder::new();
let current_exe = std::env::current_exe().unwrap();
// Now apply URL parser to current exe to get fully resolved path, otherwise we might get
// `./` and `../` bits in `exec_path`
let exe_url = Url::from_file_path(current_exe).unwrap();
let path = exe_url.to_file_path().unwrap().to_str().unwrap().to_owned();
let path = Some(builder.create_string(&path));
let inner = msg::ExecPathRes::create(builder, &msg::ExecPathResArgs { path });

ok_buf(serialize_response(
cmd_id,
builder,
msg::BaseArgs {
inner: Some(inner.as_union_value()),
inner_type: msg::Any::ExecPathRes,
..Default::default()
},
))
}

fn op_resources(
_state: &ThreadSafeState,
base: &msg::Base<'_>,
Expand Down
26 changes: 18 additions & 8 deletions js/os.ts
Expand Up @@ -13,16 +13,10 @@ export let pid: number;
/** Reflects the NO_COLOR environment variable: https://no-color.org/ */
export let noColor: boolean;

/** Path to the current deno process's executable file.
* Requires the `--allow-env` flag, otherwise it'll be set to an empty `string`.
*/
export let execPath: string;

function setGlobals(pid_: number, noColor_: boolean, execPath_: string): void {
function setGlobals(pid_: number, noColor_: boolean): void {
assert(!pid);
pid = pid_;
noColor = noColor_;
execPath = execPath_;
}

/** Check if running in terminal.
Expand Down Expand Up @@ -127,7 +121,7 @@ export function start(

util.setLogDebug(startResMsg.debugFlag(), source);

setGlobals(startResMsg.pid(), startResMsg.noColor(), startResMsg.execPath()!);
setGlobals(startResMsg.pid(), startResMsg.noColor());

if (preserveDenoNamespace) {
util.immutableDefine(window, "Deno", window.Deno);
Expand Down Expand Up @@ -164,3 +158,19 @@ export function homeDir(): string {

return path;
}

export function execPath(): string {
const builder = flatbuffers.createBuilder();
const inner = msg.ExecPath.createExecPath(builder);
const baseRes = sendSync(builder, msg.Any.ExecPath, inner)!;
assert(msg.Any.ExecPathRes === baseRes.innerType());
const res = new msg.ExecPathRes();
assert(baseRes.inner(res) != null);
const path = res.path();

if (!path) {
throw new Error("Could not get home directory.");
}

return path;
}
12 changes: 10 additions & 2 deletions js/os_test.ts
Expand Up @@ -56,9 +56,17 @@ testPerm({ env: false }, function homeDirPerm(): void {
});

testPerm({ env: true }, function execPath(): void {
assertNotEquals(Deno.execPath, "");
assertNotEquals(Deno.execPath(), "");
});

testPerm({ env: false }, function execPathPerm(): void {
assertEquals(Deno.execPath, "");
let caughtError = false;
try {
Deno.execPath();
} catch (err) {
caughtError = true;
assertEquals(err.kind, Deno.ErrorKind.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
assert(caughtError);
});
2 changes: 1 addition & 1 deletion js/unit_test_runner.ts
Expand Up @@ -53,7 +53,7 @@ async function main(): Promise<void> {
const cliPerms = permsToCliFlags(perms);
// run subsequent tests using same deno executable
const args = [
Deno.execPath,
Deno.execPath(),
"run",
"--no-prompt",
...cliPerms,
Expand Down
2 changes: 1 addition & 1 deletion tests/exec_path.ts
@@ -1 +1 @@
console.log(Deno.execPath);
console.log(Deno.execPath());

0 comments on commit 4519f9a

Please sign in to comment.