Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fs-transform

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fs-transform - npm Package Compare versions

Comparing version 3.1.0 to 3.2.0

script/preamble.sh

122

lib/script-generator.js
'use strict';
var isString = require('101/is-string');
var debug = require('debug');
var FsDriver = require('./fs-driver');
var debug = require('debug');
var trace = debug('fs-transform:script-generator:trace');
var fs = require('fs');
var path = require('path');

@@ -38,3 +41,3 @@ /**

return [
this.preamble(),
fs.readFileSync(path.resolve(__dirname, '../script/preamble.sh')),
this.ruleScripts.join('\n')

@@ -45,32 +48,2 @@ ].join('\n');

/**
* Generates the preamble for the shell script.
* @return {string} The preamble for the script.
*/
ScriptGenerator.prototype.preamble = function () {
var header = [
'#!/bin/bash\n',
'#',
'# Warning: this is a generated file, modifications may be overwritten.',
'#\n'
].join('\n');
var common = [
'_script_name=`basename $0`',
'search_files=\'.\'',
'warning() { echo "($_script_name) WARNING" $1; }',
'error() { echo "($_script_name) ERROR" $1; exit 1; }\n'
].join('\n');
var commandChecks = [
FsDriver.commands.map(function (name) {
return 'command -v ' + name + ' >/dev/null 2>&1 || {\n' +
' error "Missing required command: ' + name + '";\n' +
'}';
}).join('\n'),
].join('\n') + '\n';
return [header, common, commandChecks].join('\n');
};
/**
* Generates the script for the given rule and appends it to the script.

@@ -101,11 +74,4 @@ * @param {object} rule Rule for which to generate the script.

].join('\n') + '\n';
var body = [
'cp ' + rule.source + ' ' + rule.dest + ' || {',
' warning "Rule ' + index + ': unable to copy ' +
rule.source + ' to ' + rule.dest + '"',
'}'
].join('\n');
return [header, body, ''].join('\n');
var command = 'copy ' + rule.source + ' ' + rule.dest;
return [header, command, ''].join('\n');
};

@@ -127,11 +93,4 @@

].join('\n') + '\n';
var body = [
'mv ' + rule.source + ' ' + rule.dest + ' || {',
' warning "Rule ' + index + ': unable to rename ' +
rule.source + ' to ' + rule.dest + '"',
'}'
].join('\n');
return [header, body, ''].join('\n');
var command = 'rename ' + rule.source + ' ' + rule.dest;
return [header, command, ''].join('\n');
};

@@ -153,6 +112,8 @@

var excludes = "";
if (rule.excludes) {
header += ',\n' + '# excludes: [' + rule.excludes.join(', ') + ']\n';
excludes = rule.excludes.join(' ');
var excludes = '';
if (rule.exclude) {
header += ',\n' + '# excludes: [' + rule.exclude.join(', ') + ']\n';
excludes = rule.exclude.map(function (file) {
return './' + file;
}).join(' ');
}

@@ -167,22 +128,7 @@ else {

var body = [
'results=($(grep -rlI \'' + search + '\' $search_files))',
'excludes="' + excludes + '"',
'if ((${#results[@]} > 0)); then',
' for name in $results',
' do',
' if [[ ! $excludes =~ $name ]]; then',
' sed -i.last \'s/' + search + '/' + replace + '/g\' $name || {',
' warning "Rule ' + index + ': could not replace ' +
'\'' + search + '\' with \'' + replace + '\' in $name"',
' }',
' rm -f $name.last',
' fi',
' done',
'else',
' warning "Rule ' + index + ': no search results to replace."',
'fi'
].join('\n');
var params = [search, replace, excludes].map(function (param) {
return '\'' + param + '\'';
}).join(' ');
return [header, body, ''].join('\n');
return [header, 'replace ' + params, ''].join('\n');
};

@@ -204,10 +150,26 @@

var excludes = rule.files.map(function (name) {
return '\\( ! -name \'' + name + '\' \\)';
/*
rule.files should contain a list of string filenames to globally exclude
from all replace rules. This does two things:
1. Ensures that we only handle array entries that are strings
.filter(isString)
2. Maps the filename to a path relative to the root directory where the
script will be run.
For example, consider this list of files:
['A.txt', 'B.yml', {}]
The first step will filter only the ones that are strings (excluding the
{}). And the second step will produce the following string:
"./A.txt ./B.txt"
*/
var excludes = rule.files.filter(isString).map(function (name) {
return './' + name.replace(/["$]/g, '\\$1');
}).join(' ');
return [
header,
'search_files=`find . -type f ' + excludes + '`', ''
].join('\n');
var command = 'global_exclude="./$script_name ' + excludes + '"';
return [header, '', command, ''].join('\n');
};

@@ -422,5 +422,5 @@ 'use strict';

// 2.0 Filter out global excludes
// 2.0 Filter out global excludes and .git files
files = files.filter(function (file) {
return !~self._globalExcludes.indexOf(file);
return !~self._globalExcludes.indexOf(file) && !~file.indexOf('.git/');
});

@@ -427,0 +427,0 @@

{
"name": "fs-transform",
"version": "3.1.0",
"version": "3.2.0",
"description": "Fast, rule based, file system transformations.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -32,3 +32,4 @@ 'use strict';

read: read,
readMock: readMock
readMock: readMock,
writeFile: writeFile
};

@@ -118,1 +119,8 @@

}
/**
* Alias for system `fs.writeFile`.
*/
function writeFile() {
return fs.writeFile.apply(this, arguments);
}

@@ -17,2 +17,4 @@ var Lab = require('lab');

var debug = require('debug')('fs-transform:test');
describe('functional', function () {

@@ -236,45 +238,2 @@ beforeEach(fs.createTestDir);

describe('scripts', function() {
var scriptPath = fs.mock + '.script';
before(function (done) {
childProcess.exec('cp -r ' + fs.mock + ' ' + scriptPath, done);
});
after(function (done) {
var command = 'rm -rf ' + scriptPath;
childProcess.exec(command, {cwd: 'test/fixtures/'}, done);
});
it('should provide a shell script correctly transforms', function(done) {
var rules = [
{ action: 'replace', search: '\\sum', replace: '\\prod' },
{ action: 'copy', source: 'A', dest: 'A-copy' },
{ action: 'copy', source: 'B', dest: 'B-copy' },
{ action: 'rename', source: 'sub/C', dest: 'sub/C-rename' }
];
async.series([
function runScript(next) {
var command = 'bash ../script.sh';
childProcess.exec(command, {cwd: scriptPath}, function (err, data) {
next(err);
});
},
function runTransforms(next) {
Transformer.transform(fs.path, rules, next);
},
function getDiff(next) {
var command = 'diff -r ' + fs.path + ' ' + scriptPath;
childProcess.exec(command, function (err, diff) {
if (err && err.code > 1) { return next(err); }
expect(diff).to.be.empty();
next();
});
}
], done);
});
});
it('should provide a correct full diff', function(done) {

@@ -314,2 +273,100 @@ var rules = [

}); // end 'results'
describe('scripts', function() {
var scriptPath = fs.mock + '.script';
beforeEach(function (done) {
childProcess.exec('cp -r ' + fs.mock + ' ' + scriptPath, done);
});
afterEach(function (done) {
var command = 'rm -rf ' + scriptPath;
childProcess.exec(command, {cwd: 'test/fixtures/'}, done);
});
function compareScript(rules, done) {
var script;
async.series([
function generateScript(next) {
Transformer.transform(fs.path, rules, function (err, transformer) {
var script = transformer.getScript();
debug(script);
fs.writeFile(scriptPath + '/script.sh', script, next);
});
},
function runScript(next) {
childProcess.exec('bash script.sh', { cwd: scriptPath }, function (err, output) {
debug(output);
next(err);
});
},
function removeScript(next) {
childProcess.exec('rm -f ' + scriptPath + '/script.sh', next);
},
function getDiff(next) {
var command = 'diff -r ' + fs.path + ' ' + scriptPath;
childProcess.exec(command, function (err, diff) {
if (err && err.code > 1) { return next(err); }
debug(diff);
expect(diff).to.be.empty();
next();
});
}
], done);
}
it('should provide a shell script correctly transforms', function(done) {
var rules = [
{ action: 'replace', search: '\\sum', replace: '\\prod' },
{ action: 'copy', source: 'A', dest: 'A-copy' },
{ action: 'copy', source: 'B', dest: 'B-copy' },
{ action: 'rename', source: 'sub/C', dest: 'sub/C-rename' }
];
async.series([
function runScript(next) {
var command = 'bash ../script.sh';
childProcess.exec(command, {cwd: scriptPath}, function (err, data) {
next(err);
});
},
function runTransforms(next) {
Transformer.transform(fs.path, rules, next);
},
function getDiff(next) {
var command = 'diff -r ' + fs.path + ' ' + scriptPath;
childProcess.exec(command, function (err, diff) {
if (err && err.code > 1) { return next(err); }
expect(diff).to.be.empty();
next();
});
}
], done);
});
it('should correctly handle global excludes', function(done) {
compareScript([
{ action: 'exclude', files: ['sub/C', 'A'] },
{ action: 'replace', search: 'Mew', replace: 'Woof'}
], done);
});
it('should handle local replace excludes', function(done) {
compareScript([
{
action: 'replace',
search: 'Mew',
replace: 'Bark',
exclude: ['sub/C']
}
], done);
});
it('should always exclude .git files', function(done) {
compareScript([
{ action: 'replace', search: 'only_in_gitfile', replace: 'yus' }
], done);
});
}); // end 'scripts'
}); // end 'functional'

@@ -32,13 +32,17 @@ 'use strict';

describe('generate', function() {
var script;
var script = new ScriptGenerator();
beforeEach(function (done) {
script = new ScriptGenerator();
sinon.stub(script, 'preamble').returns('PREAMBLE');
sinon.stub(fs, 'readFileSync').returns('PREAMBLE\n');
done();
});
afterEach(function (done) {
fs.readFileSync.restore();
done();
});
it('should generate the preamble', function(done) {
script.generate();
expect(script.preamble.calledOnce).to.be.true();
expect(fs.readFileSync.calledOnce).to.be.true();
done();

@@ -49,3 +53,4 @@ });

script.ruleScripts = [4, 5, 6];
expect(script.generate()).to.equal('PREAMBLE\n4\n5\n6');
var result = script.generate();
expect(result).to.equal('PREAMBLE\n\n4\n5\n6');
done();

@@ -55,11 +60,2 @@ });

describe('preamble', function() {
it('should generate and return the preamble', function(done) {
expect(new ScriptGenerator().preamble()).to.equal(
fs.readFileSync('test/fixtures/script-preamble.sh').toString()
);
done();
});
}); // end 'preamble'
describe('addRule', function() {

@@ -169,8 +165,8 @@ var script;

replace: 'wat',
excludes: ['A.dmg', 'B.tar.gz']
exclude: ['A.dmg', 'B.tar.gz']
};
var index = 55;
expect(script.replace(rule, index)).to.equal(
fs.readFileSync('test/fixtures/replace.sh').toString()
);
var expected = fs.readFileSync('test/fixtures/replace.sh').toString();
var generated = script.replace(rule, index);
expect(generated).to.equal(expected);
done();

@@ -177,0 +173,0 @@ });

@@ -168,2 +168,29 @@ var Lab = require('lab');

it('should always exclude .git files', function(done) {
var rule = { search: 'metroid', replace: 'samus' };
var sed = sinon.stub(transformer.driver, 'sed').yields();
sinon.stub(transformer.driver, 'copy').yields();
sinon.stub(transformer.driver, 'remove').yields();
sinon.stub(transformer.driver, 'diff').yields();
sinon.stub(transformer.driver, 'grep').yields(null, [
'/etc/.git/file1.txt',
'/etc/.git/file2.txt',
'/etc/file3.txt',
'/etc/file4.txt'
].join('\n'));
transformer.replace(rule, function (err) {
expect(sed.callCount).to.equal(2);
expect(sed.calledWith('metroid', 'samus', '/etc/.git/file1.txt'))
.to.be.false();
expect(sed.calledWith('metroid', 'samus', '/etc/.git/file2.txt'))
.to.be.false();
expect(sed.calledWith('metroid', 'samus', '/etc/file3.txt'))
.to.be.true();
expect(sed.calledWith('metroid', 'samus', '/etc/file4.txt'))
.to.be.true();
done();
});
});
it('should appropriately apply exclude filters', function(done) {

@@ -170,0 +197,0 @@ var rule = {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc