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
fix(deno): refactor to avoid prompts during module import (#2216) #2217
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, have you tested that the top level await works as expected.
@@ -21,22 +21,21 @@ const REQUIRE_ERROR = 'require is not supported by ESM'; | |||
const REQUIRE_DIRECTORY_ERROR = | |||
'loading a directory of commands is not supported yet for ESM'; | |||
|
|||
const DENO_ENV_PERMITTED: boolean = | |||
(await Deno.permissions.query({name: 'env'})).state === 'granted'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this work even though yargs is synchronous? (have you tested?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that you are correct in inferring that this will cause the import mainline code to execute following other purely synchronous imports. But, I believe, all imports will still execute before any module/user code. I've not seen or used any complex import recipes which would need a specific order of execution for the 'Yargs' module.
I am successfully using a fork with this patch in several user scripts, and I can post some examples. But that's just weak, "works on my machine", evidence. What would you think would help prove that this can be used safety without causing any disruptions?
relevant: Unexpected execution order (denoland/deno#14243)
Tbh I'm not a fan of this proposed solution. It makes permission errors silent. I imagine a situation where someone runs a on a CI platform with some environment variables but Proposed solution. Lazy evaluationInstead of preloading the environment object and Example#!/usr/bin/env -S deno run
function getcwd() {
return Deno.cwd()
}
console.log(Math.random() > 0.5 ? getcwd(): '') Only asks when We can simulate a no TTY environment with |
@rivy what are your thoughts on @Altair-Bueno's suggestion? It sounds pretty reasonable to me:
could be moved into |
Actually, After reading the code again I also noticed that yargs/lib/typings/common-types.ts Line 96 in 561fc7a
yargs/lib/platform-shims/deno.ts Line 79 in 561fc7a
Footnotes |
@bcoe , I'm happy with a revision to lazy evaluation if that works for the rest of your code. The current implementation also swallows permission denied errors, making them silent. I assumed that was planned graceful degradation. And, not deeply diving into the code, I was not sure about later use of the results of the two permission-requiring operations. So, I proposed this version as essentially a drop-in replacement, minus the UI prompt behavior. In general, as long as no permission requiring operations are executed within the mainline of imported module code, the noted UI prompting won't appear, ie, I'm happy to help with further changes or testing. |
@rivy could I bother you to rebase. I trust that this fix is working for you, let's land it. |
@bcoe, rebased and pushed. This "Works on my PC (TM)" 😄; but I'd hope that someone else would do a cursory test to make sure it's working elsewhere before releasing it. I've got an example deno script (
Note that a fresh reload of all dependencies does show some
In searching through lib\platform-shims\deno.ts, it looks like these are all from incorrectly specified dependencies within 'escalade', 'yargs_parser', and 'y18n'. Just specifying the versions of 'std' used in those will fix the warnings. And the specific modules that they are using from 'std' don't hit the problematic 'prompting' code introduced after v0.134.0, so they can use the most recent version of 'std' without introducing an undesired permission prompt. $ deno run -q -r "https://deno.land/x/escalade@v3.0.3/sync.ts"
Warning Implicitly using latest version (0.159.0) for https://deno.land/std/path/mod.ts
$ deno run -q -r "https://deno.land/x/yargs_parser@v20.2.4-deno/deno.ts"
Warning Implicitly using latest version (0.159.0) for https://deno.land/std/path/mod.ts
$ deno run -q -r "https://deno.land/x/y18n@v5.0.0-deno/deno.ts"
Warning Implicitly using latest version (0.159.0) for https://deno.land/std/path/mod.ts
Warning Implicitly using latest version (0.159.0) for https://deno.land/std/fmt/printf.ts I'll create some issues/PRs for the three modules when I get a chance. |
@bcoe, I've created the PRs to fix the |
Ping @bcoe. |
The PRs yargs/yargs-parser#464, and yargs/y18n#147 look complete. But it looks like @lukeed is concerned about the change to his code (lukeed/escalade#8). I've tried to explain the issue and correct the misperception, but he's ghosted me for the last month. The included function from Let me know... |
Hey @rivy, the Deno implementation in yargs has very much been meant as an experiment, with the primary use case still being Node.js. I'm hesitant to vendor additional code into yargs, purely for the benefit of Deno (I'd rather carry the warning for the time being until you figure things out with @lukeed. Is there perhaps a compromise where you pin to a range rather than a specific build? |
I understand this is a small hassle, but there are problems. First, @lukeed hasn't responded to a request for more discussion (for more than 6 weeks). So, figuring it out with him seems to be quite a low probability occurrence. Second, Deno differs substantially from NodeJS in that it doesn't use versions in the "semantic version" sense. Deno uses them as simple tags pinning a particular commit set as a "version". There is no implied semantics or ordering in the tag "version" names. The latest one is the "latest version" no matter the tag name (or prior tag names). So, no such thing as a version range would exist. And, last, the warning is an actual problem, not just a casual warning. By not setting a version, the imported module is free floating without any guardrails, importing whatever chronologically latest version has been uploaded. It's an open door for a future failure arising from the dependency itself, even with no local code changes. Fully specifying a dependency is the recommended best practice, including recs by the Deno team itself. Not specifying the version is an anti-pattern/code smell.
ref: https://medium.com/deno-the-complete-reference/dependency-management-in-deno-48f1c91ad84d
ref: denoland/deno#10822 For risk management and to promote robust code, I wouldn't import any code with this type of warning as a dependency into my code and strongly recommend to others that it's a bad idea. As for vendoring this code, you wouldn't be changing anything but the Deno platform shim code. And, currently, you're using two differing versions of escalade anyway, This is the entirety of the code used/imported into the deno platform shim... import { dirname, resolve } from 'https://deno.land/std/path/mod.ts'
export type Callback = (directory: string, files: string[]) => string | false | void;
function toItems(dir: string) {
let list = [];
for (let tmp of Deno.readDirSync(dir)) {
list.push(tmp.name);
}
return list;
}
/** Requires `allow-read` permission. */
export default function (start: string, callback: Callback) {
let dir = resolve('.', start);
let stats = Deno.statSync(dir);
if (!stats.isDirectory) {
dir = dirname(dir);
}
while (true) {
let tmp = callback(dir, toItems(dir));
if (tmp) return resolve(dir, tmp);
dir = dirname(tmp = dir);
if (tmp === dir) break;
}
} Adding a version of this code to just the Deno platform shim code would be very easy and be truly only minimally different (I see only three lines requiring minor changes). Again, I'd like this to be a robust, long-lived Deno module, and I'm happy to help. And, thanks for taking the time to look at and discuss this issue. |
- specify import versions per best practice and to avoid Deno warnings - pin to std@0.134.0 to avoid Deno prompts # refs - ref: [fix(deno): specify import versions (avoids Deno warnings)](lukeed#8) - closed as dead after being ghosted by @lukeed - ref: [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217) ## related discussion/issues [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
- best practice and strongly needed b/c Deno does *not* use semantic versioning - avoids Deno warnings - also avoids Deno prompts # refs - [fix(deno): specify deps (avoids Deno warnings)](yargs#464) - closed for non-participation at 1 yr open - [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217 (comment)) ## related discussion/issues [refactor ~ implement *no-panic*/*no-prompt* changes](rivy/deno.dxx@a53375d) @@ <https://archive.is/Esp5e> [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
- best practice and strongly needed b/c Deno does *not* use semantic versioning - avoids Deno warnings - also avoids Deno prompts # refs - [fix(deno): specify deps (avoids Deno warnings)](yargs#464) - closed for non-participation at 1 yr open - [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217 (comment)) ## related discussion/issues [refactor ~ implement *no-panic*/*no-prompt* changes](rivy/deno.dxx@a53375d) @@ <https://archive.is/Esp5e> [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
- best practice and strongly needed b/c Deno does *not* use semantic versioning - avoids Deno warnings - also avoids Deno prompts # refs - [fix(deno): specify deps (avoids Deno warnings)](yargs#464) - closed for non-participation at 1 yr open - [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217 (comment)) ## related discussion/issues [refactor ~ implement *no-panic*/*no-prompt* changes](rivy/deno.dxx@a53375d) @@ <https://archive.is/Esp5e> [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
- best practice and strongly needed b/c Deno does *not* use semantic versioning - avoids Deno warnings - also avoids Deno prompts # refs - [fix(deno): specify deps (avoids Deno warnings)](yargs#464) - closed for non-participation at 1 yr open - [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217 (comment)) ## related discussion/issues [refactor ~ implement *no-panic*/*no-prompt* changes](rivy/deno.dxx@a53375d) @@ <https://archive.is/Esp5e> [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
- best practice and strongly needed b/c Deno does *not* use semantic versioning - avoids Deno warnings - also avoids Deno prompts # refs - [fix(deno): specify deps (avoids Deno warnings)](yargs#464) - closed for non-participation at 1 yr open - [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217 (comment)) ## related discussion/issues [refactor ~ implement *no-panic*/*no-prompt* changes](rivy/deno.dxx@a53375d) @@ <https://archive.is/Esp5e> [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
- best practice and strongly needed b/c Deno does *not* use semantic versioning - avoids Deno warnings - also avoids Deno prompts # refs - [fix(deno): specify deps (avoids Deno warnings)](yargs#464) - closed for non-participation at 1 yr open - [fix(deno): refactor to avoid prompts during module import](yargs/yargs#2217 (comment)) ## related discussion/issues [refactor ~ implement *no-panic*/*no-prompt* changes](rivy/deno.dxx@a53375d) @@ <https://archive.is/Esp5e> [fix(node): Make global.ts evaluate synchronously](denoland/deno_std#2098) [Execution order of imports in deno is unclear/unexpected](denoland/deno#14243) [std/node should avoid TLA](denoland/deno_std#2097) [HowTO test that a module is *no-panic* and *no-prompt* when statically imported?](denoland/deno/issues/#15356) [Discussion ~ Bring back permission prompt behind a flag](denoland/deno/issues/#3811) [Security prompt by default (instead of throw)](denoland/deno/issues/#10183) [Seeking a better UX for permissions](denoland/deno/issues/#11061) [Design Meeting 2021-07-29 ~ `Prompt by default`](denoland/deno/issues/#11767) [permission prompt problems](denoland/deno/issues/#11936) [`deno repl` has permissions by default?](denoland/deno/issues/#12665) [Bad UX with prompt by default](denoland/deno/issues/#13730) [DENO_NO_PROMPT env var support](denoland/deno/issues/#14208) [feat: Add DENO_NO_PROMPT variable](denoland/deno/issues/#14209)
Fix for Deno UI/UX prompt issue described in #2216.