Skip to content

Conversation

angular-robot
Copy link
Collaborator

This PR contains the following updates:

Package Type Update Change
zx (source) devDependencies major ^6.2.4 -> ^8.0.0

Release Notes

google/zx (zx)

v8.6.0: — Valve Vanguard

Compare Source

  • Enabled thenable params processing for $ literals #​1237
const a1 = $`echo foo`
const a2 = new Promise((resolve) => setTimeout(resolve, 20, ['bar', 'baz']))

await $`echo ${a1} ${a2}` // foo bar baz

v8.5.5: — PVC Wizard

Compare Source

Minor feature polish.

  • ProcessPromise and ProcessOutput lines() getters now accept a custom delimiter #​1220 #​1218
const cwd = tempdir()
const delimiter = '\0'

const p1 = $({
  cwd
})`touch foo bar baz; find ./ -type f -print0 -maxdepth 1`
(await p1.lines(delimiter)).sort() // ['./bar', './baz', './foo']
  
// or via options
const lines = []
const p2 = $({
  delimiter,
  cwd,
})`find ./ -type f -print0 -maxdepth 1`

for await (const line of p2) {
  lines.push(line)
}

lines.sort() // ['./bar', './baz', './foo']

v8.5.4: — Pipe Dreamer

Compare Source

v8.5.3: — Trap Master

Compare Source

  • Another portion of JSR related improvements #​1193 #​1192
  • Goods refactoring #​1195
    • Fixes expBackoff implementation
    • Sets $.log.output as default spinner() output
    • Makes configurable question() I/O
  • Added Graaljs compatability test #​1194
  • Docs improvements, usage examples updates #​1198

v8.5.2: — Threaded Perfection

Compare Source

v8.5.0: — Flow Splitter

Compare Source

In this release we're significantly expanding the zx setup capabilities.

zx@lite

Just core functions without extras, ~7x smaller than the full version.
#​1131

npm i zx@lite
npm i [email protected]

Detailed comparison: zx/versions

import { $ } from 'zx'
await $`echo foo`

Channels

We have completely reforged the distribution flow. Now zx is available in multiple formats:

### npm pkg from registry.npmjs.org
npm i zx        

### install directly from the GH
npm i google/zx 

### from GH the npm registry
npm i --registry=https://npm.pkg.github.com @​google/zx

### fetch from the JSR
### https://jsr.io/docs/using-packages

### @​webpod is temporary JSR scope until @​google/zx becomes ready, we'll migrate later
npx jsr add @​webpod/zx
deno add jsr:@​webpod/zx

### homebrew formula
### https://github.com/Homebrew/homebrew-core/blob/master/Formula/z/zx.rb
brew install zx

#​1141...
#​1157

Docker

If you'd prefer to run zx in a container, you can pull the image from the GH docker registry.
node:22-alpine is used as a base. #​1142 #​1145

docker pull ghcr.io/google/zx:8.5.0
docker run -t ghcr.io/google/zx:8.5.0 -e="await \$({verbose: true})\`echo foo\`"
docker run -t -i -v ./:/script ghcr.io/google/zx:8.5.0 script/t.js

Chores

  • Introduced fetch pipe helper to bypass string size limits #​1130 #​977
const p1 = fetch('https://example.com').pipe($`cat`)
const p2 = fetch('https://example.com').pipe`cat`
import { glob } from 'zx'
const packages = glob.sync(['package.json', 'packages/*/package.json'])
ZX_REGISTRY='https://custom-registry.example.com' zx script.js

v8.4.2

Compare Source

v8.4.1: – Rusty Elbow

Compare Source

Logger enhancements are arriving in this release. #​1119 #​1122 #​1123 #​1125

  • You can customize the output by defining your own formatters for each log entry kind.
$.log.formatters = {
  cmd: (entry: LogEntry) => `CMD: ${entry.cmd}`,
  fetch: (entry: LogEntry) => `FETCH: ${entry.url}`
  //...
}
  • Cmd highlighter now should properly detect bins and arguments. If still not, please report it in #​1122
  • Switched to TS 5.8 #​1120
  • Applied zizmor to check GHA workflows #​1126
  • Prettier is now enabled as a pre-commit hook #​1118

v8.4.0: – Drip Detective

Compare Source

Try the new batch of enhancements: npm i [email protected] https://www.npmjs.com/package/zx/v/8.4.0

Changes

  • The CLI option --prefer-local now allows linking both external binaries and packages #​1116 #​1117
const cwd = tmpdir()
const external = tmpdir()
await fs.outputJson(path.join(external, 'node_modules/a/package.json'), {
  name: 'a',
  version: '1.0.0',
  type: 'module',
  exports: './index.js',
})
await fs.outputFile(
  path.join(external, 'node_modules/a/index.js'),
  `
export const a = 'AAA'
`
)
const script = `
import {a} from 'a'
console.log(a);
`
const out = await $`zx --cwd=${cwd} --prefer-local=${external} --test <<< ${script}`
assert.equal(out.stdout, 'AAA\n')
  • The quote has been slightly changed for a conner case, when zx literal gets an array.
    #​999 #​1113
const p = $({prefix: '', postfix: ''})`echo ${[1, '', '*', '2']}`

// before
p.cmd //  `echo 1  $'*' 2`) 

// after
p.cmd //  `echo 1 $'' $'*' 2`) 
zx script.zx           # Unknown file extension "\.zx"
zx --ext=mjs script.zx # OK
const err = new Error('BrokenSpawn')
const o = await $({
  nothrow: true,
  spawn() {
    throw err
  },
})`echo foo`
o.ok       // false
o.exitCode // null
o.message  // BrokenSpawn...
o.cause    // err

v8.3.2: – Clogged Drain

Compare Source

Restrics unsafe vals usage on dotenv.stringify #​1093 #​1094

v8.3.1: – Perfect Seal

Compare Source

The release essence: introduced full-featured .env support #​461#​1060 #​1052 #​1043 #​1037 #​1032 #​1030 #​1022

API

envapi is a tiny 100 LOC dotenv-inspired parser and serializer that we've integrated into zx.

import { dotenv, fs } from 'zx'

// parse
const env = dotenv.parse('A=A\nFOO=BAR') // { A: 'A', FOO: 'BAR' }

// serialize
const raw = dotenv.stringify(env) // A=A\nFOO=BAR
await fs.writeFile('.env', raw)

// load
dotenv.load('.env') // { A: 'A', FOO: 'BAR' }

// update the process.env
dotenv.config('.env')
process.env.A // A
CLI
zx --env .env script.mjs
zx --env-file .env script.mjs
QnA

— Why not use dotenv directly?
— 1) Size does matter 2) We'd like to avoid internal vaults.

— Why not load .env by default?
— 1) Explicit is better than implicit 2) Runtime itself (like bun) may provide the feature.

Chore

v8.3.0: – Pipes of Steel

Compare Source

A few weeks ago zx took a part in OSS Library Night 🎉
Many thanks to the organizers and contributors who have boosted the project with their pull requests!

Today we are releasing the zx with a huge bunch of new features and improvements.

Features

API
  • Implemented [Symbol.asyncIterator] API for ProcessPromise #​984 #​998 #​1000
    Now you can iterate over the process output using for await loop from any point of the process execution.
const process = $`sleep 0.1; echo Chunk1; sleep 0.1; echo Chunk2; sleep 0.2; echo Chunk3; sleep 0.1; echo Chunk4;`
const chunks = []

await new Promise((resolve) => setTimeout(resolve, 250))
for await (const chunk of process) {
  chunks.push(chunk)
}

chunks.length //  4
chunks[0]     // 'Chunk1'
chunks[3]     // 'Chunk4'
  • zx version is available via JS API #​986
import { version } from 'zx'
const [major] = (version || '').split('.').map(Number)
if (major < 6)
  throw new Error('zx >= 6 is required')
Pipes
  • Enabled stream picking for pipe() #​1023
const p = $`echo foo >&2; echo bar`
const o1 = (await p.pipe.stderr`cat`).toString()
const o2 = (await p.pipe.stdout`cat`).toString()

assert.equal(o1, 'foo\n')  // <- piped from stderr
assert.equal(o2, 'bar\n')  // <- stdout
  • Added signal handling on piping #​992
const ac = new AbortController()
const { signal } = ac
const p = $({ signal, nothrow: true })`echo test`.pipe`sleep 999`
setTimeout(() => ac.abort(), 50)

try {
  await p
} catch ({ message }) {
  message // The operation was aborted
}
  • Added direct piping to file shortcut #​1001
// before
await $`echo "Hello, stdout!"`.pipe(fs.createWriteStream('/tmp/output.txt'))

// after
await $`echo "Hello, stdout!"`.pipe('/tmp/output.txt')
CLI
  • Provided $.defaults setting via ZX_-prefixed environment variables #​988 #​998
ZX_VERBOSE=true ZX_SHELL='/bin/bash' zx script.mjs
zx --env=/path/to/some.env script
  • Landed installation registry customization #​994
zx --install --registry=https://registry.yarnpkg.com script.mjs

Fixes

Docs

Chores

Merry Christmas! 🎄🎅🎁

v8.2.4: – Leaky Faucet

Compare Source

  • Fixed bun async_hooks compatibility #​959

v8.2.3: – Golden Wrench

Compare Source

This release continues the work on pipe API enhancements:

const { stdout } = await $({ halt: true })`echo "hello"`
 .pipe`awk '{print $1" world"}'`
 .pipe`tr '[a-z]' '[A-Z]'`
 .run()

stdout // 'HELLO WORLD'
  • Let $ be piped directly from streams #​953
const getUpperCaseTransform = () =>
  new Transform({
    transform(chunk, encoding, callback) {
      callback(null, String(chunk).toUpperCase())
    },
  })

// $ > stream (promisified) > $ 
const o1 = await $`echo "hello"`
  .pipe(getUpperCaseTransform())
  .pipe($`cat`)

o1.stdout //  'HELLO\n'

// stream > $
const file = tempfile()
await fs.writeFile(file, 'test')
const o2 = await fs
  .createReadStream(file)
  .pipe(getUpperCaseTransform())
  .pipe($`cat`)

o2.stdout //  'TEST'
const file = tempfile()
const fileStream = fs.createWriteStream(file)
const p = $`echo "hello"`
  .pipe(getUpperCaseTransform())
  .pipe(fileStream)
const o = await p

p instanceof WriteStream             // true
o instanceof WriteStream             // true
o.stdout                             // 'hello\n'
o.exitCode;                          // 0
(await fs.readFile(file)).toString() // 'HELLO\n'

We've also slightly tweaked up dist contents for better compatibility with bundlers #​957

v8.2.2

Compare Source

What's Changed

Full Changelog: google/zx@8.2.1...8.2.2

v8.2.1

Compare Source

  • #​936 fixes endless streams piping
  • #​930 enables custom extensions support

v8.2.0

Compare Source

Pipes supercharge today! 🚀

Features

  • Delayed piping. You can fill dependent streams at any time during the origin process lifecycle (even when finished) without losing data. #​914
const result = $`echo 1; sleep 1; echo 2; sleep 1; echo 3`
const piped1 = result.pipe`cat`
let piped2

setTimeout(() => {
  piped2 = result.pipe`cat`
}, 1500)

await piped1
assert.equal((await piped1).toString(), '1\n2\n3\n')
assert.equal((await piped2).toString(), '1\n2\n3\n')
const file = tempfile()
const fileStream = fs.createWriteStream(file)
const p = $`echo "hello"`
  .pipe(
    new Transform({
      transform(chunk, encoding, callback) {
        callback(null, String(chunk).toUpperCase())
      },
    })
  )
  .pipe(fileStream)

p instanceof WriteStream             // true
await p === fileStream               // true
(await fs.readFile(file)).toString() // 'HELLO\n'

Chore

v8.1.9

Compare Source

Today's release is a minor update that includes:

Enhancements

  • We have replaced ProcessOutput fields with lazy getters to reduce mem consumption #​903, #​908
  • Reduced ReDos risks for codeblock patterns #​906
  • Kept argv reference on update #​916
  • Strengthened Shell interface to properly handle sync mode #​915:
expectType<ProcessPromise>($`cmd`)
expectType<ProcessPromise>($({ sync: false })`cmd`)
expectType<ProcessOutput>($({ sync: true })`cmd`)
expectType<ProcessOutput>($.sync`cmd`)

Fixes

v8.1.8

Compare Source

  • Apply the proper TeplateStringArray detection #​904, #​905
  • PromiseProcess got lazy getters to optimize mem usage #​903

v8.1.7

Compare Source

Step by step on the road to improvements

Fixes

Finally, we've fixed the issue with piped process rejection #​640 #​899:

const p1 = $`exit 1`.pipe($`echo hello`)
try {
  await p1
} catch (e) {
  assert.equal(e.exitCode, 1)
}

const p2 = await $({ nothrow: true })`echo hello && exit 1`.pipe($`cat`)
assert.equal(p2.exitCode, 0)
assert.equal(p2.stdout.trim(), 'hello')

Enhancements

Added cmd display to ProcessPromise #​891:

const foo = 'bar'
const p = $`echo ${foo}`

p.cmd // 'echo bar'

and duration field to ProcessOutput #​892:

const p = $`sleep 1`.nothrow()
const o = await p

o.duration // ~1000 (in ms)

Enabled zurk-like pipe string literals #​900:

const p = await $`echo foo`.pipe`cat`
p.stdout.trim() // 'foo'

v8.1.6

Compare Source

Improvements & Fixes
  • The $.preferLocal option now also accepts a directory #​886, #​887.
$.preferLocal = true             // injects node_modules/.bin to the $PATH
$.preferLocal = '/foo/bar'       // attaches /foo/bar to the $PATH
$.preferLocal = ['/bar', '/baz'] // now the $PATH includes both /bar and /baz

Why not just $.env['PATH'] = 'extra:' + '$.env['PATH']?
Well, the API internally does the same, but also handles the win paths peculiarities.

  • Provided $.killSignal option for the symmetry with the $.timeoutSignal. You can override the default termination flow #​885:
$.killSignal = 'SIGKILL'

const p = $({nothrow: true})`sleep 10000`
setTimeout(p.kill, 100)
  
(await p).signal // SIGKILL
  • $ opt presets became chainable #​883:
const $$ = $({ nothrow: true })
assert.equal((await $$`exit 1`).exitCode, 1)

const $$$ = $$({ sync: true }) // Both {nothrow: true, sync: true} are applied
assert.equal($$$`exit 2`.exitCode, 2)
  • Enhanced the internal Duration parser #​884:
const p = $({timeout: '1mss'})`sleep 999` // raises an error now
  • Abortion signal listeners are now removed after the process completes #​881, #​889, zurk#12, zurk#13.
  • Extended integration tests matrix, added nodejs-nightly builds and TS dev snapshots #​888

v8.1.5

Compare Source

We've rolled out a new release!

Fixes

  • Added the minimist typings to the dts bundle. #​872 brings the fix.
  • Re-enabled the YAML extra
    API. #​870 #​879

Chores

  • Clarified cd(), within() and syncProcessCwd() interactions. #​878
  • Included mention of the cwd option in the documentation. #​868
  • Test enhancements. #​877 #​880

v8.1.4

Compare Source

We continue optimizing bundles and CI/CD pipelines.

  • Update @​webpod/ps to v0.0.0-beta.7 to sync internal zurk version. #​855
  • Split vendor chunk to reduce the zx/core entry size. #​856
  • Add bundle size check. #​857
  • Refactor the testing flow, remove duplicated tasks. #​861
  • Add missing types for the global defaults. #​864
  • Omit redundant YAML API extras. #​866

Which gives us: 897 kB → 829 kB (-7.58%)

v8.1.3

Compare Source

Nothing special today. We just keep improving the implementation.

Features

import {$} from 'zx'
  • zx/cli exports its inners to allow more advanced usage.
    Imagine, your own CLI tool that uses zx as a base:
    #​828
#!/usr/bin/env node

import './index.mjs'
import {main} from 'zx/cli'

main()
  • Provide intermediate store configuration for fine-grained control of memory usage.
    #​650, #​849
const getFixedSizeArray = (size) => {
  const arr = []
  return new Proxy(arr, {
    get: (target, prop) =>
      prop === 'push' && arr.length >= size
        ? () => {}
        : target[prop],
  })
}
const store = {
  stdout: getFixedSizeArray(1),
  stderr: getFixedSizeArray(1),
  stdall: getFixedSizeArray(0),
}

const p = await $({ store })`echo foo`

p.stdout.trim() //  'foo'
p.toString()    // ''
  • Introduced sync methods for ps:
    #​840
import { ps } from 'zx'

const list1 = await ps()
const list2 = await tree()

// new methods
const list3 = ps.sync()
const list4 = tree.sync()

Chore

v8.1.2

Compare Source

Every new zx version is better than previous one. What have we here?

Features

  • Added ProcessPromise.verbose() to enhance debugging experience.
    #​820, #​710
const p = $`echo foo`
p.quiet()        // enable silent mode
p.quiet(false)   // then disable
p.verbose()      // enable verbose/debug mode
p.verbose(false) // and turn it off

await p
  • Aligned ProcessPromise.isSmth() API:
    #​823
const p = $`echo foo`

p.isHalted()
p.isVerbose()
p.isQuiet()
p.isNothrow()

Bug Fixes

  • fix: apply EOL ensurer to the last chunk only #​825
  • fix(cli): return exit code 1 on incorrect inputs #​826
  • fix: set cjs bundle as legacy main entrypoint #​827

Chore

v8.1.1

Compare Source

This release brings a pinch of sugar and minor fixes.

Features
  • Introduced $.preferLocal option to prefer node_modules/.bin located binaries over globally system installed ones.
    #​798
$.preferLocal = true

await $`c8 npm test`

await $({ preferLocal: true })`eslint .`
const p = $`echo 'foo\nbar'`

await p.text()        // foo\n\bar\n
await p.text('hex')   //  666f6f0a0861720a
await p.buffer()      //  Buffer.from('foo\n\bar\n')
await p.lines()       // ['foo', 'bar']
await $`echo '{"foo": "bar"}'`.json() // {foo: 'bar'}
  • ProcessPromise now exposes its signal reference.
    #​816
const p = $`sleep 999`
const {signal} = p

const res = fetch('https://example.com', {signal})

setTimeout(() => p.abort('reason'), 1000)
Fixes
  • CLI flag --quiet is mapped to $.quiet option. #​813
  • Module conditional exports are properly sorted now. #​812
  • A newline character is appended to the output of ProcessPromise if it's missing. #​810

v8.1.0

Compare Source

This new release is a big deal. It brings significant improvements in reliability and compatibility.

New features

Added usePwsh() helper to switch to PowerShell v7+ #​790

import {usePwsh, useBash} from 'zx'

usePwsh()
$.shell // 'pwsh'

useBash()
$.shell // 'bash'

timeout is now configurable $ opts #​796

import {$} from 'zx'

await $({ timeout: 100 })`sleep 999`

$.timeout = 1000            // Sets default timeout for all commands
$.timeoutSignal = 'SIGKILL' // Sets signal to send on timeout

await $`sleep 999`

Added --cwd option for CLI #​804

zx --cwd=/some/path script.js

Introduced tmpdir and tmpfile helpers #​803

import {tmpdir, tmpfile} from 'zx'

t1 = tmpdir()          // /os/based/tmp/zx-1ra1iofojgg/
t2 = tmpdir('foo')     // /os/based/tmp/zx-1ra1iofojgg/foo/

f1 = tmpfile()         // /os/based/tmp/zx-1ra1iofojgg
f2 = tmpfile('f.txt')  // /os/based/tmp/zx-1ra1iofojgg/foo.txt
f3 = tmpfile('f.txt', 'string or buffer')
  • Support CRLF for markdown script #​788
  • Added help digest for man #​806
  • Added compatibility with Deno 1.x. → zx seems to be working with Deno 1.x.

v8.0.2

Compare Source

In this release:

  • Added configurable detached option (#​782)
  • Fixed pkg typings entries for tsd tests (#​780)

v8.0.1

Compare Source

In this release:

  • Added feature: add stdio option (#​772)
  • Added feature: support signal opt (#​769)
  • Fixed: additional process.kill fallback for bun (#​770)

v8.0.0

Compare Source

We are thrilled to announce the release of zx v8.0.0! 🎉

With this release, we have introduced a lot of new features, improvements, and bug fixes.
We have also made some breaking changes, so please read the following release notes carefully.

🚀 New Shiny Features

Squashed deps: we use esbuild with custom plugins to forge js bundles and dts-bundle-generator for typings 2acb0f, #​722

More safety, more stability and significantly reduced installation time. Zx now is ~20x smaller.

Options presets are here. To implement this, we have also completely refactored the zx core, and now it's available as a separate package – zurk\ aeec7a, #​733, #​600

const $$ = $({quiet: true})
await $$`echo foo`

$({nothrow: true})`exit 1`

We have introduced $.sync() API\ 1f8c8b, #​738, #​681, 1d8aa9, #​739

import {$} from 'zx'

const { output } = $.sync`echo foo` // foo

You can also override the internal API to implement pools, test mocking, etc.

$.spawnSync = () => {} // defaults to `child_process.spawnSync`

The input option is now available to pass data to the command.\ b38972, #​736

const p1 = $({ input: 'foo' })`cat`
const p2 = $({ input: Readable.from('bar') })`cat`
const p3 = $({ input: Buffer.from('baz') })`cat`
const p4 = $({ input: p3 })`cat`
const p5 = $({ input: await p3 })`cat`

AbortController has been introduced to abort the command execution. It's available via the ac option.\ fa4a7b, #​734, #​527

const ac = new AbortController()
const p = $({ ac })`sleep 9999`

setTimeout(() => ac.abort(), 100)

If not specified, the default instance will be used. Abortion trigger is also available via PromiseResponse:

const p = $`sleep 9999`
setTimeout(() => p.abort(), 100)

kill method is exposed now. To terminate any (not only zx starter) process:

import { kill } from 'zx'

await kill(123)
await kill(123, 'SIGKILL')

Btw, we have replaced ps-tree with @​webpod/ps & @​webpod/ingrid, and exposed ps util:

import {ps} from 'zx'

const children = await ps.tree(123)
/**
 [
 {pid: 124, ppid: 123},
 {pid: 125, ppid: 123}
 ]
 */
const children2 = await ps.tree({pid: 123, recursive: true})
/**
 [
 {pid: 124, ppid: 123},
 {pid: 125, ppid: 123},

 {pid: 126, ppid: 124},
 {pid: 127, ppid: 124},
 {pid: 128, ppid: 124},

 {pid: 129, ppid: 125},
 {pid: 130, ppid: 125},
 ]
 */

Introduced $.postfix option. It's like a $.prefix, but for the end of the command. fb9554, #​756, #​536

import {$} from 'zx'

$.postfix = '; exit $LastExitCode' // for PowerShell compatibility

minimist API exposed\ #​661

import { minimist } from 'zx'

const argv = minimist(process.argv.slice(2), {})

Fixed npm package name pattern on --install mode 956dcc, #​659, #​660, #​663

import '@&#8203;qux/pkg'       // valid
import '@&#8203;qux/pkg/entry' // was invalid before and valid now
⚠️ Breaking changes

We've tried our best to avoid them, but it was necessary.

  1. $.verbose is set to false by default, but errors are still printed to stderr. Set $.quiet = true to suppress all output.\ cafb90, #​745, #​569

    $.verbose = true // everything works like in v7
    
    $.quiet = true // to completely turn off logging
  2. ssh API was dropped. Install webpod package instead.\ 8925a1, #​750

    // import {ssh} from 'zx' ↓
    import {ssh} from 'webpod'
    
    const remote = ssh('user@host')
    await remote`echo foo`
  3. zx is not looking for powershell anymore, on Windows by default. If you still need it, use the usePowerShell helper:\ 24dcf3, #​757

    import { usePowerShell, useBash } from 'zx'
    
    usePowerShell() // to enable powershell
    useBash()       // switch to bash, the default
  4. Process cwd synchronization between $ invocations is disabled by default. This functionality is provided via an async hook and can now be controlled directly.\ d79a63, #​765

    import { syncProcessCwd } from 'zx'
    
    syncProcessCwd() // restores legacy v7 behavior
🧰 Other Improvements

v7.2.3

Compare Source

What's Changed

New Contributors

Full Changelog: google/zx@7.2.2...7.2.3

v7.2.2

Compare Source

What's Changed

New Contributors

Full Changelog: google/zx@7.2.1...7.2.2

v7.2.1

Compare Source

What's Changed

New Contributors

Full Changelog: google/zx@7.2.0...7.2.1

v7.2.0

Compare Source

🐚 zx v7.2.0 release! 🎉

A tool for writing better scripts

zx

In this release:

  • Helpers retry() & spinner() now available in zx without the experimental flag.
  • Added support for ~~~ blocks in markdown scripts.
  • Updated npm dependencies.
  • Added support for ssh commands via webpod.

PS: Plan for the next v8 release.

v7.1.1

Compare Source

  • Fixed default shell on Windows: if bash is installed, use bash by default.

v7.1.0

Compare Source

Autoinstall

This release introduces a new flag --install which will parse and install all required or imported packages automatically.

import sh from 'tinysh'
sh.say('Hello, world!')

And running zx --install script.mjs will trigger installation of tinysh package! It even possible to specify a needed version in comment with @ symbol:

import sh from 'tinysh' // @&#8203;^1.0.0
PowerShell

Another big change is for Windows. Now, the default shell on Windows is powershell.exe.

This should fix a lot of issues with "dollar" signs.

Fixes
  • Minimist now correctly parses argv when using zx cli.

v7.0.8

Compare Source

What's Changed

Full Changelog: google/zx@7.0.7...7.0.8

v7.0.7

Compare Source

Now it's possible to do:

const my$ = $.bind(null)
const foo = await my$`echo foo`

v7.0.6

Compare Source

  • Bunch of fixes and improvements. ᕕ( ᐛ )ᕗ

v7.0.5

Compare Source

  • Fixed types definitions for autocomplete in VSCode #​466

v7.0.4

[Compare Source](htt


Configuration

📅 Schedule: Branch creation - "after 10:00pm every weekday,before 5:00am every weekday,every weekend" in timezone America/Tijuana, Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

See associated pull request for more information.
@angular-robot angular-robot requested a review from a team as a code owner June 25, 2025 07:38
@angular-robot angular-robot requested review from adolgachev and removed request for a team June 25, 2025 07:38
@angular-robot angular-robot added action: merge The PR is ready for merge by the caretaker area: build & ci Related the build and CI infrastructure of the project labels Jun 25, 2025
@angular-robot angular-robot requested a review from mmalerba June 25, 2025 07:38
@angular-robot angular-robot added action: merge The PR is ready for merge by the caretaker area: build & ci Related the build and CI infrastructure of the project labels Jun 25, 2025
@crisbeto crisbeto added the target: patch This PR is targeted for the next patch release label Jun 25, 2025
@crisbeto crisbeto merged commit b80dd55 into angular:main Jun 25, 2025
35 checks passed
@crisbeto
Copy link
Member

The changes were merged into the following branches: main, 20.0.x

crisbeto pushed a commit that referenced this pull request Jun 25, 2025
See associated pull request for more information.

(cherry picked from commit b80dd55)
@angular-robot angular-robot deleted the ng-renovate/zx-8-x branch June 25, 2025 08:06
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 31, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: build & ci Related the build and CI infrastructure of the project target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants