Commit 9d5b3e4
Changed files (7)
test
fixtures
js-project
src/core.ts
@@ -34,6 +34,7 @@ import {
formatCmd,
getCallerLocation,
noop,
+ normalizeMultilinePieces,
parseDuration,
quote,
quotePowerShell,
@@ -137,10 +138,9 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
const promise = new ProcessPromise((...args) => ([resolve, reject] = args))
const cmd = buildCmd(
$.quote,
- pieces as TemplateStringsArray,
+ normalizeMultilinePieces(pieces as TemplateStringsArray),
args
) as string
-
const snapshot = getStore()
const sync = snapshot[syncExec]
const callback = () => promise.isHalted || promise.run()
src/util.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-import { chalk } from './vendor.js'
+import { chalk, parseLine } from './vendor.js'
export function noop() {}
@@ -24,6 +24,24 @@ export function isString(obj: any) {
return typeof obj === 'string'
}
+export function normalizeMultilinePieces(
+ pieces: TemplateStringsArray
+): TemplateStringsArray {
+ return Object.assign(
+ pieces.map((p, i) =>
+ p.trim()
+ ? parseLine(p)
+ .words.map(({ w, e }) => {
+ if (w === '\\') return ''
+ return w.trim() + (p[e + 1] === ' ' ? ' ' : '')
+ })
+ .join(' ')
+ : pieces[i]
+ ),
+ { raw: pieces.raw }
+ )
+}
+
export function quote(arg: string) {
if (/^[a-z0-9/_.\-@:=]+$/i.test(arg) || arg === '') {
return arg
src/vendor.ts
@@ -56,3 +56,4 @@ export { default as chalk, type ChalkInstance } from 'chalk'
export { default as which } from 'which'
export { default as minimist } from 'minimist'
export { default as ps } from '@webpod/ps'
+export { parseLine } from '@webpod/ingrid'
test/fixtures/js-project/package-lock.json
@@ -19,6 +19,7 @@
"@types/minimist": "^1.2.5",
"@types/node": ">=20.11.30",
"@types/which": "^3.0.3",
+ "@webpod/ingrid": "^0.0.0-beta.3",
"@webpod/ps": "^0.0.0-beta.2",
"c8": "^9.1.0",
"chalk": "^5.3.0",
test/core.test.js
@@ -48,6 +48,28 @@ describe('core', () => {
assert.equal((await $`echo -n ${''}`).toString(), '')
})
+ test('handles multiline literals', async () => {
+ assert.equal(
+ (
+ await $`echo foo
+ bar
+ "baz
+ qux"
+`
+ ).toString(),
+ 'foo bar baz\n qux\n'
+ )
+ assert.equal(
+ (
+ await $`echo foo \
+ bar \
+ baz \
+`
+ ).toString(),
+ 'foo bar baz\n'
+ )
+ })
+
test('can create a dir with a space in the name', async () => {
let name = 'foo bar'
try {
package-lock.json
@@ -16,6 +16,7 @@
"@types/minimist": "^1.2.5",
"@types/node": ">=20.11.30",
"@types/which": "^3.0.3",
+ "@webpod/ingrid": "^0.0.0-beta.3",
"@webpod/ps": "^0.0.0-beta.2",
"c8": "^9.1.0",
"chalk": "^5.3.0",
@@ -502,9 +503,9 @@
}
},
"node_modules/@webpod/ingrid": {
- "version": "0.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/@webpod/ingrid/-/ingrid-0.0.0-beta.2.tgz",
- "integrity": "sha512-TaA6xC1+lCkvPHSdD55fMF1mKe3xLy5NZpwbjoq3Zi1n0LU6XSFF2sD5SHAgnEHEzDxx8hDArNPvzZbF6uApdg==",
+ "version": "0.0.0-beta.3",
+ "resolved": "https://registry.npmjs.org/@webpod/ingrid/-/ingrid-0.0.0-beta.3.tgz",
+ "integrity": "sha512-PkorwT+q/MiIF+It47ORX0wCYHumOeMKwp5KX5WbUvbCeOtSB6b5UUC5FvzlijdwK/YPR+sOitQzyVSsRrMmJA==",
"dev": true
},
"node_modules/@webpod/ps": {
package.json
@@ -59,6 +59,7 @@
"@types/node": ">=20.11.30",
"@types/which": "^3.0.3",
"@webpod/ps": "^0.0.0-beta.2",
+ "@webpod/ingrid": "^0.0.0-beta.3",
"c8": "^9.1.0",
"chalk": "^5.3.0",
"depseek": "^0.4.1",