Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

## 6.0.0-dev

- Added `--dry` option to process images without writing output files.
- Removed `jpg` output format alias; use `jpeg` instead.
- Internal refactor from CommonJS to ESM.
- Updated `sharp` dependency to 0.35.3.
- Updated dependencies.
- Requires Node.js 20.10.
- Removed `jpg` output format alias; use `jpeg` instead.

## 5.3.0 (August 13, 2026)

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Commands:
pixel values made fully transparent

Global Options
--dry Process images without writing output files [boolean]
-i, --input Path to (an) image file(s) [array] [required] [default: stdin]
-o, --output Directory or URI template to write the image files to
[string] [required] [default: stdout]
Expand Down
7 changes: 7 additions & 0 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ const optimize = "Optimization Options";
const output = "Output Options";

const globalOptions = {
dry: {
alias: "n",
desc: "Process images without writing output files",
group: global,
type: "boolean",
},

// @see https://sharp.pixelplumbing.com/api-constructor/
input: {
alias: "i",
Expand Down
14 changes: 13 additions & 1 deletion lib/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,15 @@ export default {
format,
metadata,
});

if (context.dry) {
return transformer
.toBuffer({ resolveWithObject: true })
.then(({ info }) => Object.assign({}, info, { path: dest }));
}
return transformer
.toFile(dest)
.then((info) => Object.assign(info, { src, path: dest }));
.then((info) => Object.assign({}, info, { path: dest }));
});
});
return Promise.all(promises);
Expand All @@ -123,6 +129,12 @@ export default {
metadata,
});

if (context.dry) {
return transformer
.toBuffer({ resolveWithObject: true })
.then(({ info }) => info);
}

// Gather return value.
const info = {};
transformer.on("info", (_info) => Object.assign(info, _info));
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default (args, options = {}) => {
.parseAsync(args)
.then((argv) => {
const context = {
dry: argv.dry,
format: argv.format,
options: pick(argv, Object.keys(inputOptions)),
queue: argv["#queue"],
Expand Down
10 changes: 10 additions & 0 deletions test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,16 @@ describe(`${pkg.name} <options> [command..]`, () => {
});
});

describe("--dry", () => {
// Run.
before(() => cli.parseAsync(["--dry", ...ioFlags]));

// Tests.
it("must set the dry flag", () => {
expect(cli.parsed.argv).to.have.property("dry", true);
});
});

describe("--overshootDeringing", () => {
// Run.
before(() => cli.parseAsync(["--overshootDeringing", ...ioFlags]));
Expand Down
26 changes: 26 additions & 0 deletions test/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ describe("convert", () => {
expect(info.path).to.contain(".avif");
});
});
it("must not write a file during a dry run", () => {
const dryDest = path.join(dest, "dry.jpg");
const context = { ...createContext(), dry: true };
return convert.files([input], dryDest, context).then(([info]) => {
expect(info).to.have.property("format", "jpeg");
expect(info).to.have.property("size");
expect(info.path).to.equal(dryDest);
expect(fs.existsSync(dryDest)).to.be.false();
});
});
it("must pass the output extension format to queued handlers", () => {
const context = createContext();
let format;
Expand Down Expand Up @@ -185,5 +195,21 @@ describe("convert", () => {
})
.catch((err) => expect(err).to.equal(error));
});
it("must not write to the output stream during a dry run", () => {
const failingOutput = new Writable({
write(_chunk, _encoding, callback) {
callback(new Error("should not write output"));
},
});
return convert
.stream(fs.createReadStream(input), failingOutput, {
...createContext(),
dry: true,
})
.then((info) => {
expect(info).to.have.property("format", "jpeg");
expect(info).to.have.property("size");
});
});
});
});
Loading