Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Use @npmcli/run-script for exec, explore; add interactive exec - #2202

Merged
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping
Dec 4, 2020
Merged

Use @npmcli/run-script for exec, explore; add interactive exec#2202
ruyadorno merged 2 commits into
release/v7.1.0from
isaacs/better-script-escaping

Conversation

@isaacs

Copy link
Copy Markdown
Contributor

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.

Adds an interactive shell mode when npm exec is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.

Prevent weird behavior from npm explore ../blah. explore now can
only be used to explore packages that are actually found in the
relevant node_modules folder.

References

@isaacs
isaacs requested a review from nlfNovember 19, 2020 19:33
@isaacs
isaacs requested a review from a team as a code ownerNovember 19, 2020 19:33
@isaacs
isaacsforce-pushed the isaacs/better-script-escaping branch 2 times, most recently from b93460b to ec904f5CompareNovember 19, 2020 19:49
@ljharb

Copy link
Copy Markdown
Contributor

Can the npm exec shell "not do that" in a non-TTY?

@darcyclarkedarcyclarke added Release 7.x work is associated with a specific npm 7 release release: next These items should be addressed in the next release semver:minor new backwards-compatible feature labels Nov 24, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @ljharb's note, I think it would be good if we ensured this interactive mode wasn't something that could trip up CI environments... I've suggested two changes that should support that.

Comment threadlib/exec.js
const pathArr = [...PATH]

// nothing to maybe install, skip the arborist dance
if (!call && !args.length && !packages.length) {

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if(!call&&!args.length&&!packages.length){
if(!call&&!args.length&&!packages.length&&isTTY&&!ciDetect()){

Comment threaddocs/content/commands/npm-exec.md Outdated

Run without positional arguments or `--call`, this allows you to
interactively run commands in the same sort of shell environment that
`package.json` scripts are run.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
`package.json` scripts are run.
`package.json` scripts are run; Only available in TTY/non-CI environments.

Comment threadlib/exec.js
const fileExists = require('./utils/file-exists.js')
const PATH = require('./utils/path.js')

const cmd = (args, cb) => exec(args).then(() => cb()).catch(cb)

@darcyclarkedarcyclarkeNov 24, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the isTTY definition on line 197 & hoist it up.

Suggested change
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constcmd=(args,cb)=>exec(args).then(()=>cb()).catch(cb)
constisTTY=process.stdin.isTTY&&process.stdout.isTTY

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Hm, if stdin is not a TTY, then it just means it'll read from whatever it is, and close when it closes.

$ echo 'echo $npm_package_name' > cmd
$ node . exec < cmd
Entering npm script environment
Type 'exit' or ^D when finished
npm

But, yes, if it's CI and it is a TTY, we should not do that. And if it's not a TTY, we should probably not show the helpful help banner.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

So, wait, if it is in CI, and we abort, that means you can't run commands from stdin in CI, which seems like a suboptimal situation? What if you have a bunch of shell commands in a file, and want to run npm exec < file.sh in CI?

I think the only situation we should exit early in is if it's CI and a TTY, with a warning that we're doing so.

@isaacs

Copy link
Copy Markdown
ContributorAuthor

Updated with the logic described. Also simplified some of the isTTY checking, since it's really only stdin that we care about there. (If someone pipes the command to | tee output.log, then we should still behave the same way, since it's input availability that is relevant when prompting, but if you cat commands.sh | npm exec, then it should Just Work, and not give you a surprise prompt.)

@darcyclarkedarcyclarke added release: next These items should be addressed in the next release and removed release: next These items should be addressed in the next release labels Nov 27, 2020

@darcyclarkedarcyclarke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM

This removes all other arg/shell escaping mechanisms, as they are no
longer needed, and will be un-done by puka in @npmcli/run-script anyway.
Adds an interactive shell mode when `npm exec` is run without any
arguments, allowing users to interactively test out commands in an npm
script environment. Previously, this would do nothing, and just exit.
Prevent weird behavior from `npm explore ../blah`. `explore` now can
_only_ be used to explore packages that are actually found in the
relevant `node_modules` folder.
darcyclarke pushed a commit that referenced this pull request Dec 2, 2020
@darcyclarke
darcyclarkeforce-pushed the isaacs/better-script-escaping branch from 1df4876 to f864b7bCompareDecember 2, 2020 21:31
Credit: @isaacs
PR-URL: #2202Close: #2202
Reviewed-by: @darcyclarke
PR-URL: #2202
Credit: @isaacsClose: #2202
Reviewed-by: @ruyadorno
@ruyadorno
ruyadorno changed the base branch from latest to release/v7.1.0December 4, 2020 19:17
@ruyadorno
ruyadornoforce-pushed the isaacs/better-script-escaping branch from f864b7b to 4f94d42CompareDecember 4, 2020 19:17
@ruyadorno
ruyadorno merged commit 4f94d42 into release/v7.1.0Dec 4, 2020
ruyadorno pushed a commit that referenced this pull request Dec 4, 2020
This was referenced Dec 4, 2020
@nlf
nlf deleted the isaacs/better-script-escaping branch March 28, 2022 16:59
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release: nextThese items should be addressed in the next releaseRelease 7.xwork is associated with a specific npm 7 releasesemver:minornew backwards-compatible feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@isaacs@ljharb@darcyclarke@ruyadorno