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

mako-tree

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mako-tree - npm Package Compare versions

Comparing version 0.3.2 to 0.4.0

7

HISTORY.md
0.4.0 / 2015-10-28
==================
* adding tree.prune() to enable cleaning up orphaned files
* restoring concept of entries internally
* added cloning capability
0.3.2 / 2015-10-27

@@ -3,0 +10,0 @@ ==================

10

lib/file.js

@@ -9,6 +9,7 @@

class File {
constructor(location, tree) {
constructor(location, tree, entry) {
debug('initialize %s', location);
this.type = extension(location);
this.path = location;
this.entry = !!entry;
this.tree = tree;

@@ -40,2 +41,9 @@ }

}
clone(tree) {
let file = new File(this.location);
Object.assign(file, this);
file.tree = tree;
return file;
}
}

@@ -42,0 +50,0 @@

66

lib/tree.js

@@ -20,6 +20,6 @@

addFile(location) {
debug('adding node: %s', location);
addFile(location, entry) {
debug('adding node: %s (entry: %j)', location, !!entry);
if (!this.hasFile(location)) {
let file = new File(location, this);
let file = new File(location, this, !!entry);
this.graph.addNewVertex(location, file);

@@ -40,3 +40,3 @@ }

isEntry(location) {
return this.graph.outDegree(location) === 0;
return !!this.getFile(location).entry;
}

@@ -46,14 +46,14 @@

debug('listing entry files');
let entries = Array.from(this.graph.sinks()).map(function (vertex) {
return vertex[0];
});
let entries = Array.from(this.graph.sinks())
.filter(vertex => !!vertex[1].entry)
.map(vertex => vertex[0]);
if (from) {
debug('filtering out entry files not linked to %s', from);
entries = entries.filter(function (entry) {
entries = entries.filter(entry => {
return from === entry || this.graph.hasPath(from, entry);
}, this);
});
}
debug('%s entries found %j', entries.length, entries);
debug('%d entries found %j', entries.length, entries);
return entries;

@@ -67,3 +67,3 @@ }

addDependency(parent, child) {
debug('adding dependency %s to %s', child, parent);
debug('adding dependency %s -> %s', child, parent);
if (!this.hasFile(child)) this.addFile(child);

@@ -75,16 +75,10 @@ this.graph.addEdge(child, parent);

removeDependency(parent, child) {
debug('removing dependency %s from %s', child, parent);
debug('removing dependency %s -> %s', child, parent);
this.graph.removeEdge(child, parent);
// if nothing else depends on this node, let's remove it
if (this.graph.outDegree(child) === 0) {
debug('node %s no longer depended on, removing from tree', child);
this.removeFile(child);
}
}
moveDependency(from, to, child) {
debug('moving dependency %s from %s to %s', child, from, to);
this.addDependency(to, child);
this.removeDependency(from, child);
removeDependencies(parent) {
debug('removing all dependencies from %s', parent);
this.dependenciesOf(parent)
.forEach(child => this.removeDependency(parent, child));
}

@@ -97,5 +91,3 @@

return Array.from(deps).map(function (vertex) {
return vertex[0];
});
return Array.from(deps).map(vertex => vertex[0]);
}

@@ -108,5 +100,3 @@

return Array.from(deps).map(function (vertex) {
return vertex[0];
});
return Array.from(deps).map(vertex => vertex[0]);
}

@@ -121,2 +111,22 @@

}
clone() {
let tree = new Tree();
tree.graph = this.graph.clone(file => file.clone(tree), value => value);
return tree;
}
prune() {
debug('pruning orphaned files');
let entries = this.getEntries();
let files = this.topologicalOrder();
files
// filter out files that have some path to a valid entry
.filter(file => {
if (this.isEntry(file)) return false;
return !entries.some(entry => this.graph.hasPath(file, entry));
})
.forEach(file => this.graph.destroyVertex(file));
}
}

@@ -123,0 +133,0 @@

{
"name": "mako-tree",
"version": "0.3.2",
"version": "0.4.0",
"description": "The build tree structure used internally by mako",

@@ -5,0 +5,0 @@ "repository": "makojs/tree",

@@ -27,11 +27,11 @@

let tree = new Tree();
let a = tree.addFile('a');
let a = tree.addFile('a', true);
let b = tree.addFile('b');
tree.addDependency('a', 'b');
it('should return true if the file is a Entry', function () {
it('should return true if the file is flagged as an entry', function () {
assert.isTrue(a.isEntry());
});
it('should return false if the file is not a Entry', function () {
it('should return false if the file is not flagged as an entry', function () {
assert.isFalse(b.isEntry());

@@ -120,2 +120,44 @@ });

});
describe('#clone(tree)', function () {
it('should create a new copy of the file', function () {
let tree1 = new Tree();
let a1 = tree1.addFile('a');
let tree2 = new Tree();
let a2 = a1.clone(tree2);
assert.notStrictEqual(a1, a2);
assert.instanceOf(a2, File);
});
it('should copy additional properties', function () {
let tree1 = new Tree();
let a1 = tree1.addFile('a');
a1.contents = 'abc123';
let tree2 = new Tree();
let a2 = a1.clone(tree2);
assert.strictEqual(a1.contents, a2.contents);
});
it('should ensure that changes to type follow the clone', function () {
let tree1 = new Tree();
let a1 = tree1.addFile('a.txt');
a1.type = 'html';
let tree2 = new Tree();
let a2 = a1.clone(tree2);
assert.strictEqual(a1.type, a2.type);
});
it('should ensure that the tree is not used from the original', function () {
let tree1 = new Tree();
let a1 = tree1.addFile('a.txt');
a1.type = 'html';
let tree2 = new Tree();
let a2 = a1.clone(tree2);
assert.strictEqual(a2.tree, tree2);
});
});
});

@@ -31,3 +31,3 @@

describe('#addFile(location)', function () {
describe('#addFile(location, [entry])', function () {
it('should add a new vertex', function () {

@@ -47,2 +47,18 @@ let tree = new Tree();

});
context('with entry', function () {
it('should set the file as an entry', function () {
let tree = new Tree();
let a = tree.addFile('a', true);
assert.isTrue(a.entry);
});
it('should leave the file as not an entry by default', function () {
let tree = new Tree();
let a = tree.addFile('a');
assert.isFalse(a.entry);
});
});
});

@@ -97,3 +113,3 @@

let tree = new Tree();
tree.addFile('a');
tree.addFile('a', true);
tree.addFile('b');

@@ -113,5 +129,5 @@ tree.addFile('c');

let tree = new Tree();
tree.addFile('a');
tree.addFile('a', true);
tree.addFile('b');
tree.addFile('c');
tree.addFile('c', true);
tree.addFile('d');

@@ -131,5 +147,5 @@ tree.addFile('e');

let tree = new Tree();
tree.addFile('a');
tree.addFile('a', true);
tree.addFile('b');
tree.addFile('c');
tree.addFile('c', true);
tree.addFile('d');

@@ -149,11 +165,11 @@ tree.addFile('e');

let tree = new Tree();
tree.addFile('a');
tree.addFile('a', true);
tree.addFile('b');
tree.addDependency('a', 'b');
it('should return true when the file has no dependants', function () {
it('should return true when the file is flagged as an entry', function () {
assert.isTrue(tree.isEntry('a'));
});
it('should return false when the file is depended upon', function () {
it('should return false when the file is not flagged as an entry', function () {
assert.isFalse(tree.isEntry('b'));

@@ -236,8 +252,10 @@ });

});
});
it('should remove the unused nodes', function () {
describe('#removeDependencies(parent)', function () {
it('should remove the link between parent and all children', function () {
// a <- b
// <- c
let tree = new Tree();
tree.addFile('a');
tree.addFile('a', true);
tree.addFile('b');

@@ -248,49 +266,12 @@ tree.addFile('c');

// a <- b
tree.removeDependency('a', 'c');
tree.removeDependencies('a');
assert.isTrue(tree.hasFile('a'));
assert.isTrue(tree.hasFile('b'));
assert.isFalse(tree.hasFile('c'));
});
it('should not remove nodes that are still depended upon', function () {
// a <- c
// b <-
let tree = new Tree();
tree.addFile('a');
tree.addFile('b');
tree.addFile('c');
tree.addDependency('a', 'c');
tree.addDependency('b', 'c');
// a <- c
// b
tree.removeDependency('b', 'c');
assert.isTrue(tree.hasFile('a'));
assert.isTrue(tree.hasFile('b'));
assert.isTrue(tree.hasFile('c'));
assert.isFalse(tree.hasDependency('a', 'b'));
assert.isFalse(tree.hasDependency('a', 'c'));
});
});
describe('#moveDependency(from, to, child)', function () {
it('should transfer the dependency from <- to', function () {
// a <- b <- c
let tree = new Tree();
tree.addFile('a');
tree.addFile('b');
tree.addFile('c');
tree.addDependency('a', 'b');
tree.addDependency('b', 'c');
tree.moveDependency('b', 'a', 'c');
// a <- b
// <- c
assert.isTrue(tree.hasDependency('a', 'b'));
assert.isTrue(tree.hasDependency('a', 'c'));
assert.isFalse(tree.hasDependency('b', 'c'));
});
});
describe('#dependenciesOf(node, [recursive])', function () {

@@ -357,2 +338,95 @@ // a <- b <- c <- d

});
describe('#clone()', function () {
// a <- b
// <- c
let tree = new Tree();
tree.addFile('a');
tree.addFile('b');
tree.addFile('c');
tree.addDependency('a', 'b');
tree.addDependency('a', 'c');
it('should make a clone of the original', function () {
let clone = tree.clone();
assert.notStrictEqual(tree, clone);
assert.instanceOf(clone, Tree);
assert.strictEqual(tree.size(), clone.size());
assert.deepEqual(tree.topologicalOrder(), clone.topologicalOrder());
});
});
describe('#prune()', function () {
it('should only remove orphaned files', function () {
// a* <- b
// c
let tree = new Tree();
tree.addFile('a', true);
tree.addFile('b');
tree.addFile('c');
tree.addDependency('a', 'b');
tree.prune();
assert.strictEqual(tree.size(), 2);
assert.isFalse(tree.hasFile('c'));
});
it('should recursively remove orphaned trees', function () {
// a* <- b
// c <- d
let tree = new Tree();
tree.addFile('a', true);
tree.addFile('b');
tree.addFile('c');
tree.addFile('d');
tree.addDependency('a', 'b');
tree.addDependency('c', 'd');
tree.prune();
assert.strictEqual(tree.size(), 2);
assert.isFalse(tree.hasFile('c'));
assert.isFalse(tree.hasFile('d'));
});
it('should not remove dependencies that are still depended on elsewhere', function () {
// a* <- b <- c
// d <-
let tree = new Tree();
tree.addFile('a', true);
tree.addFile('b');
tree.addFile('c');
tree.addFile('d');
tree.addDependency('a', 'b');
tree.addDependency('b', 'c');
tree.addDependency('d', 'b');
tree.prune();
assert.deepEqual(tree.topologicalOrder(), [ 'c', 'b', 'a' ]);
});
it('should not properly handle a complex case', function () {
// a* <- b <- c <- d
// e <- f <-
let tree = new Tree();
tree.addFile('a', true);
tree.addFile('b');
tree.addFile('c');
tree.addFile('d');
tree.addFile('e');
tree.addFile('f');
tree.addDependency('a', 'b');
tree.addDependency('b', 'c');
tree.addDependency('c', 'd');
tree.addDependency('e', 'f');
tree.addDependency('f', 'c');
tree.prune();
assert.deepEqual(tree.topologicalOrder(), [ 'd', 'c', 'b', 'a' ]);
});
});
});
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