diff --git a/cli/js/deno.ts b/cli/js/deno.ts index c1b074f3d52e0f..887f60826022cd 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -85,7 +85,16 @@ export { ShutdownMode, shutdown } from "./net.ts"; -export { dir, env, exit, isTTY, execPath, hostname, loadavg } from "./os.ts"; +export { + dir, + env, + exit, + isTTY, + execPath, + hostname, + loadavg, + osRelease +} from "./os.ts"; export { permissions, PermissionName, diff --git a/cli/js/dispatch.ts b/cli/js/dispatch.ts index 93f6dc0552eec2..fc1c69a62d0e0b 100644 --- a/cli/js/dispatch.ts +++ b/cli/js/dispatch.ts @@ -81,6 +81,7 @@ export let OP_SIGNAL_BIND: number; export let OP_SIGNAL_UNBIND: number; export let OP_SIGNAL_POLL: number; export let OP_LOADAVG: number; +export let OP_OS_RELEASE: number; const PLUGIN_ASYNC_HANDLER_MAP: Map = new Map(); diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index d1770a15a766dd..0c94308691111f 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -52,6 +52,12 @@ declare namespace Deno { */ export function hostname(): string; + /** Get the OS release. Requires the `--allow-env` flag. + * + * console.log(Deno.osRelease()); + */ + export function osRelease(): string; + /** Exit the Deno process with optional exit code. */ export function exit(code?: number): never; diff --git a/cli/js/os.ts b/cli/js/os.ts index d3c0d1b7243945..7953c2cef7fa17 100644 --- a/cli/js/os.ts +++ b/cli/js/os.ts @@ -29,6 +29,15 @@ export function hostname(): string { return sendSync(dispatch.OP_HOSTNAME); } +/** Get OS release. + * Requires the `--allow-env` flag. + * + * console.log(Deno.osRelease()); + */ +export function osRelease(): string { + return sendSync(dispatch.OP_OS_RELEASE); +} + /** Exit the Deno process with optional exit code. */ export function exit(code = 0): never { sendSync(dispatch.OP_EXIT, { code }); diff --git a/cli/js/os_test.ts b/cli/js/os_test.ts index 325cbdaa6d5e48..905a4efaf51853 100644 --- a/cli/js/os_test.ts +++ b/cli/js/os_test.ts @@ -315,3 +315,19 @@ testPerm({ env: false }, function hostnamePerm(): void { } assert(caughtError); }); + +testPerm({ env: true }, function releaseDir(): void { + assertNotEquals(Deno.osRelease(), ""); +}); + +testPerm({ env: false }, function releasePerm(): void { + let caughtError = false; + try { + Deno.osRelease(); + } catch (err) { + caughtError = true; + assert(err instanceof Deno.Err.PermissionDenied); + assertEquals(err.name, "PermissionDenied"); + } + assert(caughtError); +}); diff --git a/cli/ops/os.rs b/cli/ops/os.rs index 10c5e247e07047..8e4f1e95db7721 100644 --- a/cli/ops/os.rs +++ b/cli/ops/os.rs @@ -21,6 +21,10 @@ pub fn init(i: &mut Isolate, s: &State) { i.register_op("get_dir", s.core_op(json_op(s.stateful_op(op_get_dir)))); i.register_op("hostname", s.core_op(json_op(s.stateful_op(op_hostname)))); i.register_op("loadavg", s.core_op(json_op(s.stateful_op(op_loadavg)))); + i.register_op( + "os_release", + s.core_op(json_op(s.stateful_op(op_os_release))), + ); } #[derive(Deserialize)] @@ -185,6 +189,16 @@ fn op_hostname( _zero_copy: Option, ) -> Result { state.check_env()?; - let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_owned()); + let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_string()); Ok(JsonOp::Sync(json!(hostname))) } + +fn op_os_release( + state: &State, + _args: Value, + _zero_copy: Option, +) -> Result { + state.check_env()?; + let release = sys_info::os_release().unwrap_or_else(|_| "".to_string()); + Ok(JsonOp::Sync(json!(release))) +} diff --git a/std/node/os.ts b/std/node/os.ts index 39209b4b74c063..f34551da9c2e03 100644 --- a/std/node/os.ts +++ b/std/node/os.ts @@ -161,9 +161,9 @@ export function platform(): string { return process.platform; } -/** Not yet implemented */ +/** Returns the operating system as a string */ export function release(): string { - notImplemented(SEE_GITHUB_ISSUE); + return Deno.osRelease(); } /** Not yet implemented */ diff --git a/std/node/os_test.ts b/std/node/os_test.ts index 2ceff79a4eb992..6ef123575f0b44 100644 --- a/std/node/os_test.ts +++ b/std/node/os_test.ts @@ -30,6 +30,13 @@ test({ } }); +test({ + name: "release is a string", + fn() { + assertEquals(typeof os.release(), "string"); + } +}); + test({ name: "getPriority(): PID must be a 32 bit integer", fn() { @@ -216,13 +223,6 @@ test({ Error, "Not implemented" ); - assertThrows( - () => { - os.release(); - }, - Error, - "Not implemented" - ); assertThrows( () => { os.setPriority(0);