UNPKG

4.92 kBJavaScriptView Raw
1var util = require('util'),
2 Submodule = require('./sub_module').Submodule,
3 Blob = require('./blob').Blob;
4
5var Tree = exports.Tree = function(repo, id, mode, name, contents) {
6 var _repo = repo, _id = id, _contents = contents, _mode = mode, _name = name;
7
8 // Internal properties
9 Object.defineProperty(this, "repo", { get: function() { return _repo; }, set: function(value) { _repo = value; }, enumerable: true});
10 Object.defineProperty(this, "id", { get: function() { return _id; }, set: function(value) { _id = value; }, enumerable: true});
11 Object.defineProperty(this, "mode", { get: function() { return _mode; }, set: function(value) { _mode = value; }, enumerable: true});
12 Object.defineProperty(this, "name", { get: function() { return _name; }, set: function(value) { _name = value; }, enumerable: true});
13 Object.defineProperty(this, "contents", { get: function() {
14 _contents = lazy_reader(_repo, _id, 'contents', _contents);
15 return _contents;
16 }, set: function(value) { _contents = value; }, enumerable: true});
17
18 // Return the base name
19 Object.defineProperty(this, "basename", { get: function() {
20 if(_name) {
21 var parts = _name.split("/");
22 return parts[parts.length - 1];
23 } else {
24 return null;
25 }
26 }, enumerable: false});
27}
28
29var lazy_reader = function(repo, id, type, variable) {
30 if(variable != null) return variable;
31 // Control the flow
32 var done = false;
33 var value = [];
34
35 // Fetch the content
36 repo.git.ls_tree(id, [], {}, function(err, text) {
37 if(err) return done = true;
38 // Split the output
39 var lines = text.split("\n");
40 // Create objects for all the entries
41 for(var i = 0; i < lines.length; i++) {
42 Tree.content_from_string(repo, lines[i], function(err, entry) {
43 value.push(entry);
44 });
45 }
46
47 done = true;
48 })
49
50 while(!done) {};
51 return value ? value : '';
52}
53
54// Construct the contents of the tree
55// repo: the current rep
56// treeish: the reference
57// paths: optional array of directory paths to restrict the tree
58Tree.construct = function(repo, treeish, paths, callback) {
59 // Set the path to the default if it's null
60 paths = paths ? paths : [];
61 // Run the ls_tree command
62 repo.git.ls_tree(treeish, paths, function(err, output) {
63 if(err) return callback(err, output);
64 construct_initialize(repo, treeish, output, callback);
65 });
66}
67
68// Create a new instance of the tree class
69var construct_initialize = function(repo, id, text, callback) {
70 // Create a tree object
71 var tree = new Tree(repo, id, null, null, []);
72 var lines = text.trim().split("\n");
73 if(lines.length == 1 && lines[0] == '') lines = [];
74 // Fetch all the lines
75 for(var i = 0; i < lines.length; i++) {
76 Tree.content_from_string(repo, lines[i], function(err, entry) {
77 if(err) return callback(err, entry);
78 tree.contents.push(entry);
79 });
80 }
81
82 // Remove all the null entries
83 tree.contents = tree.contents.filter(function(entry) { return entry ? true : false; });
84 // Return the object
85 callback(null, tree);
86}
87
88Tree.content_from_string = function(repo, text, callback) {
89 // Split the text into parts and extract the variables
90 var parts = text.replace(/\t/, ' ').split(" ");
91 var mode = parts[0];
92 var type = parts[1];
93 var id = parts[2];
94 var name = parts[3];
95
96 if(type == "tree") {
97 callback(null, new Tree(repo, id, mode, name));
98 } else if(type == "blob") {
99 callback(null, new Blob(repo, id, mode, name));
100 } else if(type == "link") {
101 callback(null, new Blob(repo, id, mode, name));
102 } else if(type == "commit") {
103 callback(null, new Submodule(repo, id, mode, name));
104 } else {
105 callback("invalid type: " + type, null);
106 }
107}
108
109// Find the named object in this tree's contents
110//
111// Examples
112// Repo.new('/path/to/grit').tree/'lib'
113// // => //<Grit::Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
114// Repo.new('/path/to/grit').tree/'README.txt'
115// // => //<Grit::Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
116//
117// Returns Grit::Blob or Grit::Tree or nil if not found
118Tree.prototype.find = function(file) {
119 var self = this;
120
121 if(file.match(/\//)) {
122 var paths = file.split('/');
123 paths.length > 0 && paths[paths.length - 1] == '' ? paths.pop() : null;
124 return paths.map(function(x) {
125 return self && (self = self.find(x));
126 });
127 } else {
128 var results = self.contents.filter(function(c) {
129 return c.name == file;
130 })
131
132 return results.length == 1 ? results[0] : null;
133 }
134}
135
136Tree.create = function(repo, attributes, callback) {
137 var args = Array.prototype.slice.call(arguments, 1);
138 callback = args.pop();
139 attributes = args.length ? args.shift() : {};
140
141 var tree = new Tree(repo);
142 for(var name in attributes) {
143 tree[name] = attributes[name];
144 }
145
146 callback(null, tree);
147}
148
149
150
151
152
153
154
155
156
157
158
159