Skip to content

Commit

Permalink
Enable reading file/directory list from stdin
Browse files Browse the repository at this point in the history
This adds the `--stdin` flag, which makes jscodeshift read the list of
files and directories to process from standard input instead of command
line arguments.

Given that jscodeshift is getting input from multiple sources (file
list, transformer code, source code), there are obviously multiple
options for what should be accepted on the standard input.

My more longer term idea is to be able to accept any of these on stdin.
The first step is the file/directory list. I decided to add the
`--stdin` flag instead of reading from stdin by default, to require the
user to be explicit about their intention.

In the future I could imagine the other inputs being provided on stdin
by using `-` as argument value. This is in-line with other commands,
like `cat`. E.g. reading the transform from stdin could be done via
`--transform -`. Similarly getting the source code from stdin could be
done by passing `-` as a single positional argument.
  • Loading branch information
fkling committed Dec 3, 2018
1 parent 8eb9825 commit b6eaa0a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
29 changes: 26 additions & 3 deletions bin/__tests__/jscodeshift-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ var testUtils = require('../../utils/testUtils');
var createTransformWith = testUtils.createTransformWith;
var createTempFileWith = testUtils.createTempFileWith;

function readFile(path) {
return fs.readFileSync(path).toString();
}

function run(args, stdin, cwd) {
return new Promise(resolve => {
var jscodeshift = child_process.spawn(
Expand Down Expand Up @@ -64,19 +68,37 @@ describe('jscodeshift CLI', () => {
run(['-t', transformA, sourceA, sourceB]).then(
out => {
expect(out[1]).toBe('');
expect(fs.readFileSync(sourceA).toString()).toBe('transforma');
expect(fs.readFileSync(sourceB).toString()).toBe('transformb\n');
expect(readFile(sourceA)).toBe('transforma');
expect(readFile(sourceB)).toBe('transformb\n');
}
),
run(['-t', transformB, sourceC]).then(
out => {
expect(out[1]).toBe('');
expect(fs.readFileSync(sourceC).toString()).toBe(sourceC);
expect(readFile(sourceC)).toBe(sourceC);
}
)
]);
});

it('takes file list from stdin if --stdin is set', () => {
var sourceA = createTempFileWith('a');
var sourceB = createTempFileWith('b\n');
var sourceC = createTempFileWith('c');
var transformA = createTransformWith(
'return "transform" + fileInfo.source;'
);

return run(['--stdin', '-t', transformA], [sourceA, sourceB, sourceC].join('\n')).then(
out => {
expect(out[1]).toBe('');
expect(readFile(sourceA)).toBe('transforma');
expect(readFile(sourceB)).toBe('transformb\n');
expect(readFile(sourceC)).toBe('transformc');
}
);
});

it('does not transform files in a dry run', () => {
var source = createTempFileWith('a');
var transform = createTransformWith(
Expand Down Expand Up @@ -300,4 +322,5 @@ describe('jscodeshift CLI', () => {
);
});
})

});
27 changes: 21 additions & 6 deletions bin/jscodeshift.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,17 @@ const parser = require('../src/argsParser')
].join('\n');
},
},
stdin: {
help: 'read file/directory list from stdin',
flag: true,
default: false,
},
});

let options, positionalArguments;
try {
({options, positionalArguments} = parser.parse());
if (positionalArguments.length === 0) {
if (positionalArguments.length === 0 && !options.stdin) {
process.stderr.write(
'Error: You have to provide at least one file/directory to transform.' +
'\n\n---\n\n' +
Expand All @@ -120,8 +125,18 @@ try {
process.exit(exitCode);
}

Runner.run(
/^https?/.test(options.transform) ? options.transform : path.resolve(options.transform),
positionalArguments,
options
);
function run(paths, options) {
Runner.run(
/^https?/.test(options.transform) ? options.transform : path.resolve(options.transform),
paths,
options
);
}

if (options.stdin) {
let buffer = '';
process.stdin.on('data', data => buffer += data);
process.stdin.on('end', () => run(buffer.split('\n'), options));
} else {
run(positionalArguments, options);
}
2 changes: 2 additions & 0 deletions src/argsParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ function getHelpText(options) {
Usage: jscodeshift [OPTION]... PATH...
or: jscodeshift [OPTION]... -t TRANSFORM_PATH PATH...
or: jscodeshift [OPTION]... -t URL PATH...
or: jscodeshift [OPTION]... --stdin < file_list.txt
Apply transform logic in TRANSFORM_PATH (recursively) to every PATH.
If --stdin is set, each line of the standard input is used as a path.
Options:
"..." behind an option means that it can be supplied multiple times.
Expand Down

0 comments on commit b6eaa0a

Please sign in to comment.