UNPKG

4.88 kBJavaScriptView Raw
1const fs = require('fs');
2const path = require('path');
3const fsExtra = require('fs-extra');
4const Time = require('./Time');
5const Match = require('./Match');
6const Bundle = require('./Bundle');
7const createDiff = require('./createDiff');
8
9
10function Packer(option) {
11 this.option = option;
12 this.root = option.root;
13 this.dirs = {
14 curr: option.root,
15 cache: option.cache,
16 temp: path.join(option.cache, 'temp'),
17 diff: path.join(option.cache, 'diff')
18 };
19 this.bundle = {}; // curr: Bundle, diff: Bundle
20 this.difference = {}; // add 新增, del 删除, non 都存在(=> same change)
21 this.rules = new Match(option, option.release);
22 this.resource = null;
23 this.time = new Time();
24 this.initialized = false;
25}
26
27Packer.prototype.init = function() {
28 this.time.start('init');
29
30 this.initialized = true;
31
32 this.bundle.curr = new Bundle(this.dirs.curr, 'curr');
33
34 this.time.end('init');
35};
36
37Packer.prototype.diff = function() {
38 this.time.start('diff');
39
40 const difference = this.difference = { add: [], del: [], non: [] };
41
42 if (!this.bundle.curr) return difference;
43
44 this.dirs.diff = createDiff({
45 root: this.option.root,
46 git: this.option.git,
47 dir: this.dirs.diff,
48 tag: this.option.diff
49 });
50 this.bundle.diff = new Bundle(this.dirs.diff, 'diff');
51
52 const diff = {};
53 this.bundle.diff.getFile().forEach(item => {
54 diff[item.path] = item;
55 });
56
57 this.bundle.curr.getFile().forEach(item => {
58 const meta = {
59 path: item.path,
60 curr: item,
61 diff: diff[item.path]
62 };
63 if (meta.diff) {
64 difference.non.push(meta);
65 delete diff[item.path];
66 } else {
67 difference.add.push(meta);
68 }
69 });
70
71 Object.keys(diff).forEach(delPath => {
72 difference.del.push({
73 path: delPath,
74 curr: undefined,
75 diff: diff[delPath]
76 })
77 });
78
79 this.time.end('diff');
80
81 return difference;
82};
83
84Packer.prototype.match = function() {
85 this.time.start('match');
86
87 const difference = this.difference;
88
89 this.resource = [];
90
91 if (!(difference.add && difference.del && difference.non)) return this.resource;
92
93 const rules = this.rules;
94 const base = this.root;
95 const temp = this.dirs.temp;
96 this.resource = this.resource.concat(
97 difference.add.map(item => rules.test(item.path) > 0 ? item.curr : undefined),
98 difference.del.map(item => rules.test(item.path) > 0 ? undefined : item.diff),
99 difference.non.map(item => rules.test(item.path) > 0 ? item.curr : item.diff)
100 ).filter(item => !!item).map(file => {
101 const item = {
102 path: file.path,
103 src: file.absolute,
104 tmp: path.join(temp, file.path),
105 tar: path.join(base, file.path),
106 file: file,
107 };
108 return item;
109 });
110
111 this.time.end('match');
112
113 let same = 0;
114 this.resource.forEach(item => {
115 if (item.src === item.tar) {
116 same += 1;
117 } else {
118 }
119 });
120 console.log('total: ', this.resource.length);
121 console.log('same: ', same);
122 console.log('diff: ', this.resource.length - same);
123
124 return this.resource;
125};
126
127Packer.prototype.pack = function() {
128 this.time.start('pack');
129
130 if (!this.resource) return;
131
132 // TODO record log
133
134 // console.log('='.repeat(100));
135 // console.log('create temp bundle');
136 // console.log('-'.repeat(100));
137 this.resource.forEach(item => {
138 // TODO if item.src === item.tar, don't copy/move
139 // console.log('copy', item.src, '=>', item.tmp);
140 try {
141 fsExtra.copySync(item.src, item.tmp);
142 // fsExtra.moveSync(item.src, item.tmp);
143 } catch (e) {
144 throw new Error(e)
145 }
146 });
147
148 // console.log('clean root');
149 this.bundle.curr.getFile().forEach(item => {
150 try {
151 fsExtra.removeSync(item.absolute);
152 } catch (e) {
153 throw new Error(e)
154 }
155 });
156
157 // console.log('='.repeat(100));
158 // console.log('move temp to root');
159 // console.log('-'.repeat(100));
160 this.resource.forEach(item => {
161 // console.log('move', item.tmp, '=>', item.tar);
162 try {
163 fsExtra.moveSync(item.tmp, item.tar);
164 } catch (e) {
165 throw new Error(e)
166 }
167 });
168
169 this.time.end('pack');
170};
171
172Packer.prototype.clean = function() {
173 this.time.start('clean');
174
175 try {
176 fsExtra.removeSync(this.dirs.cache);
177 } catch (e) {
178 throw new Error(e)
179 }
180
181 this.time.end('clean');
182};
183
184Packer.prototype.run = function(callback) {
185 this.init();
186 this.diff();
187 this.match();
188 this.pack();
189 this.clean();
190
191 callback();
192};
193
194
195exports = module.exports = Packer;