Make Deno.execPath a function (#2743)

And throws without allow-env
This commit is contained in:
Kevin (Kun) "Kassimo" Qian 2019-08-06 14:05:47 -07:00 committed by Ryan Dahl
parent ccee2f01ba
commit 4519f9a50d
6 changed files with 69 additions and 26 deletions

View file

@ -77,6 +77,8 @@ union Any {
Truncate,
HomeDir,
HomeDirRes,
ExecPath,
ExecPathRes,
Utime,
WorkerGetMessage,
WorkerGetMessageRes,
@ -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;
@ -468,6 +469,12 @@ table HomeDirRes {
path: string;
}
table ExecPath {}
table ExecPathRes {
path: string;
}
table Utime {
filename: string;
atime: uint64;

View file

@ -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),
@ -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);
@ -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()
},
@ -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<'_>,

View file

@ -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.
@ -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);
@ -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;
}

View file

@ -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);
});

View file

@ -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,

View file

@ -1 +1 @@
console.log(Deno.execPath);
console.log(Deno.execPath());