logic-auto 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitconfig +2 -0
- package/.vscode/launch.json +155 -0
- package/README.md +13 -0
- package/index.js +9 -0
- package/jest.config.js +15 -0
- package/package.json +20 -0
- package/src/auto-task.js +357 -0
- package/src/automation.js +762 -0
- package/src/depend-resolver.js +471 -0
- package/src/original-path.js +337 -0
- package/src/source-batch.js +1027 -0
- package/test/base/mod1/__SaveFile.json +8 -0
- package/test/base/mod1/auto.js +12 -0
- package/test/base/mod1/dist/100.webp +0 -0
- package/test/base/mod1/dist/102-3.webp +0 -0
- package/test/base/mod1/dist/board.css +6 -0
- package/test/base/mod1/dist/board_m.css +6 -0
- package/test/base/mod1/dist/m3.html +16 -0
- package/test/base/mod1/out/bar.css +7 -0
- package/test/base/mod1/package.json +11 -0
- package/test/base/mod1/src/100.webp +0 -0
- package/test/base/mod1/src/102-3.webp +0 -0
- package/test/base/mod1/src/board.css +6 -0
- package/test/base/mod1/src/board_m.css +6 -0
- package/test/base/mod1/src/m3.html +16 -0
- package/test/base.test.js +19 -0
- package/test/index.test.js +33 -0
|
@@ -0,0 +1,1027 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const mm = require('micromatch');
|
|
4
|
+
const at = require('./auto-task');
|
|
5
|
+
const { NonTextFile, TextFile, VirtualFolder, OriginalPath } = require('./original-path');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 소스배치 클래스
|
|
9
|
+
*/
|
|
10
|
+
class SourceBatch {
|
|
11
|
+
/*_______________________________________*/
|
|
12
|
+
// public
|
|
13
|
+
pathType = 0; // (0:자동, 1:절대, 2:상대)
|
|
14
|
+
dupType = 1; // (0:하위참조, 1:중복제거, 2:중복허용)
|
|
15
|
+
isAlias = false; // 설치시 별칭 포함 여부
|
|
16
|
+
isRoot = true;
|
|
17
|
+
|
|
18
|
+
/*_______________________________________*/
|
|
19
|
+
// protected
|
|
20
|
+
static _instance = null;
|
|
21
|
+
_batchFile = [];
|
|
22
|
+
//_filter = [];
|
|
23
|
+
_task = null;
|
|
24
|
+
//_map = [];
|
|
25
|
+
|
|
26
|
+
/*_______________________________________*/
|
|
27
|
+
// private
|
|
28
|
+
_list = [];
|
|
29
|
+
|
|
30
|
+
constructor() {
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/*_______________________________________*/
|
|
34
|
+
// public method
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* TODO:: 제거 검토
|
|
38
|
+
* @returns {this}
|
|
39
|
+
*/
|
|
40
|
+
static getInstance() {
|
|
41
|
+
if (this._instance === null) {
|
|
42
|
+
this._instance = new this();
|
|
43
|
+
}
|
|
44
|
+
return this._instance;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 배치할 소스 추가 (컬렉션)
|
|
49
|
+
* @param {*} collection SourceCollection
|
|
50
|
+
* @param {*} location 배치 위치
|
|
51
|
+
* @param {*} isSave 저장 유무
|
|
52
|
+
*/
|
|
53
|
+
addCollection(collection, location) {
|
|
54
|
+
|
|
55
|
+
let ori, tar;
|
|
56
|
+
// TODO:: 타입 검사
|
|
57
|
+
for(let i = 0; i < collection.count; i++) {
|
|
58
|
+
ori = collection[i];
|
|
59
|
+
tar = new TargetSource(location, ori);
|
|
60
|
+
ori._setTarget(tar); // _target 설정
|
|
61
|
+
this._list.push(tar);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* 배칠할 소스 추가 (단일)
|
|
67
|
+
* @param {*} tar
|
|
68
|
+
*/
|
|
69
|
+
add(tar) {
|
|
70
|
+
if (tar instanceof TargetSource) this._list.push(tar);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* 전처리와 후처리 나누어야 함
|
|
75
|
+
*/
|
|
76
|
+
save() {
|
|
77
|
+
|
|
78
|
+
let autos;
|
|
79
|
+
|
|
80
|
+
function getMergeData(tar, isRoot) {
|
|
81
|
+
|
|
82
|
+
let data = '';
|
|
83
|
+
// 자식 순환 조회
|
|
84
|
+
for (let i = 0; i < tar._owned.length; i++) {
|
|
85
|
+
if (tar._owned[i].isMerge === true) data += getMergeData(tar._owned[i], isRoot) + '\n';
|
|
86
|
+
data += tar._owned[i].setData(isRoot) + '\n';
|
|
87
|
+
}
|
|
88
|
+
return data;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// 이벤트 발생
|
|
92
|
+
this._task._onSave();
|
|
93
|
+
|
|
94
|
+
// install map 처리
|
|
95
|
+
autos = this._task.entry._getAllList(true);
|
|
96
|
+
|
|
97
|
+
if (this._task.cursor === 'INSTALL') {
|
|
98
|
+
// 중복제거 처리
|
|
99
|
+
this.#deduplication(this.dupType);
|
|
100
|
+
|
|
101
|
+
// 단일오토 별칭 경로 제거
|
|
102
|
+
if (this.isAlias === false) this.#removeAlias();
|
|
103
|
+
|
|
104
|
+
// 맨 하위부터 처리한다.
|
|
105
|
+
for (let i = 0; i < autos.length; i++) {
|
|
106
|
+
// 초기화 : parent, child
|
|
107
|
+
autos[i].install.init();
|
|
108
|
+
|
|
109
|
+
// 인스톨 설정 처리
|
|
110
|
+
// autos[i].install.execute();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < autos.length; i++) {
|
|
114
|
+
// 초기화 : parent, child
|
|
115
|
+
// autos[i].install.init();
|
|
116
|
+
|
|
117
|
+
// 인스톨 설정 처리
|
|
118
|
+
autos[i].install.execute();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
124
|
+
// TextFile 일 경우 콘텐츠 설정
|
|
125
|
+
if (this._list[i]._original instanceof TextFile) {
|
|
126
|
+
this._list[i].setData(this.isRoot);
|
|
127
|
+
}
|
|
128
|
+
// 병합 파일 처리
|
|
129
|
+
if (this._list[i].isMerge === true) {
|
|
130
|
+
this._list[i].data = getMergeData(this._list[i], this.isRoot);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 타겟 저장
|
|
135
|
+
this.#saveFile();
|
|
136
|
+
|
|
137
|
+
// 이벤트 발생
|
|
138
|
+
this._task._onSaved();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* 배치파일저장소 파일 및 배치생성파일 삭제
|
|
143
|
+
*/
|
|
144
|
+
clear() {
|
|
145
|
+
|
|
146
|
+
const batchfile = this._task.entry.dir +path.sep+ '__SaveFile.json';
|
|
147
|
+
let fullPath;
|
|
148
|
+
|
|
149
|
+
for (let i = 0; i < this._batchFile.length; i++) {
|
|
150
|
+
fullPath = this._batchFile[i];
|
|
151
|
+
if (fs.existsSync(fullPath)) fs.unlinkSync(fullPath);
|
|
152
|
+
}
|
|
153
|
+
if (fs.existsSync(batchfile)) fs.unlinkSync(batchfile);
|
|
154
|
+
|
|
155
|
+
// 속성 초기화
|
|
156
|
+
this.isRoot = true;
|
|
157
|
+
this._batchFile = [];
|
|
158
|
+
this._list = [];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 배치파일 목록 얻기
|
|
163
|
+
* @returns {array}
|
|
164
|
+
*/
|
|
165
|
+
getBatchList() {
|
|
166
|
+
|
|
167
|
+
let rArr = [];
|
|
168
|
+
|
|
169
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
170
|
+
rArr.push(
|
|
171
|
+
{
|
|
172
|
+
ori: this._list[i]._original.fullPath,
|
|
173
|
+
tar: this._list[i].fullPath
|
|
174
|
+
}
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
return rArr;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* 경로 검사
|
|
183
|
+
* @param {string} fullPath
|
|
184
|
+
* @returns {*}
|
|
185
|
+
*/
|
|
186
|
+
validPath(fullPath) {
|
|
187
|
+
for(let i = 0; i < this._list.length; i++) {
|
|
188
|
+
if (this._list[i].fullPath === fullPath) return false;
|
|
189
|
+
}
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* 파일경로 중복발생시 새파일이름,이름_숫자
|
|
195
|
+
* @param {string} fullPath
|
|
196
|
+
* @returns {*}
|
|
197
|
+
*/
|
|
198
|
+
newFileName(fullPath) {
|
|
199
|
+
|
|
200
|
+
let obj, filename;
|
|
201
|
+
let delimiter = '_';
|
|
202
|
+
|
|
203
|
+
obj = path.parse(fullPath);
|
|
204
|
+
|
|
205
|
+
for(let i = 1; i < 100; i++) { // 100개로 제한
|
|
206
|
+
filename = obj.name + delimiter + i + obj.ext;
|
|
207
|
+
if (this.validPath(obj.dir + path.sep + filename)) return filename;
|
|
208
|
+
}
|
|
209
|
+
console.warn('[실패 newFileName()] ' + fullPath );
|
|
210
|
+
return obj.name; // 원래 이름 리턴
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/*_______________________________________*/
|
|
214
|
+
// private method
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* 배치파일 저장
|
|
218
|
+
*/
|
|
219
|
+
#saveFile() {
|
|
220
|
+
|
|
221
|
+
let isExists, dirname, fullPath, data, orignal, type, target;
|
|
222
|
+
const _this = this;
|
|
223
|
+
// TODO:: try 로 예외 처리함
|
|
224
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
225
|
+
target = this._list[i];
|
|
226
|
+
if (target.isSave === true && target.isExcept === false) {
|
|
227
|
+
type = target.type;
|
|
228
|
+
orignal = target._original;
|
|
229
|
+
// 텍스트 파일의 경우
|
|
230
|
+
if (type === 30) {
|
|
231
|
+
fullPath = target.fullPath;
|
|
232
|
+
data = target.data;
|
|
233
|
+
dirname = path.dirname(fullPath);
|
|
234
|
+
isExists = fs.existsSync(dirname); // 디렉토리 검사
|
|
235
|
+
if(!isExists) {
|
|
236
|
+
fs.mkdirSync(dirname, {recursive: true} ); // 디렉토리 만들기
|
|
237
|
+
}
|
|
238
|
+
fs.writeFileSync(fullPath, data, 'utf8');
|
|
239
|
+
this.#addBatchFile(fullPath); // 배치 로그 등록
|
|
240
|
+
|
|
241
|
+
// 비텍스트 파일의 경우
|
|
242
|
+
} else if (type === 20) {
|
|
243
|
+
fullPath = target.fullPath;
|
|
244
|
+
dirname = path.dirname(fullPath);
|
|
245
|
+
isExists = fs.existsSync(dirname); // 디렉토리 검사
|
|
246
|
+
if(!isExists) {
|
|
247
|
+
fs.mkdirSync(dirname, {recursive: true} ); // 디렉토리 만들기
|
|
248
|
+
}
|
|
249
|
+
// 복사
|
|
250
|
+
fs.copyFileSync(orignal.fullPath, fullPath)
|
|
251
|
+
this.#addBatchFile(fullPath);
|
|
252
|
+
|
|
253
|
+
// (가상) 폴더의 경우
|
|
254
|
+
} else if (type === 30) {
|
|
255
|
+
fullPath = target.fullPath;
|
|
256
|
+
isExists = fs.existsSync(fullPath);
|
|
257
|
+
if(!isExists) {
|
|
258
|
+
fs.mkdirSync(fullPath, {recursive: true} ); // 디렉토리 만들기
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
// 배치 로그 저장
|
|
264
|
+
this.#saveBatchFile();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* 배치파일저장소 저장
|
|
269
|
+
*/
|
|
270
|
+
#saveBatchFile() {
|
|
271
|
+
// batchFile
|
|
272
|
+
let data = JSON.stringify(this._batchFile, null, '\t');
|
|
273
|
+
fs.writeFileSync(this._task.entry.dir +path.sep+ '__SaveFile.json', data, 'utf8');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* 배치파일저장소에 저장파일 로그 추가
|
|
278
|
+
* @param {str} savePath
|
|
279
|
+
*/
|
|
280
|
+
#addBatchFile(savePath) {
|
|
281
|
+
if (this._batchFile.indexOf(savePath) < 0) this._batchFile.push(savePath);
|
|
282
|
+
if (this._task?.isLog) console.log('SAVE : ' + savePath);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* 중복된 타겟소스를 제거후 별칭 경로를 제거한다.
|
|
287
|
+
* @param {number} depType 0 자동, 1 전체중복제거, 2 전체중복허용
|
|
288
|
+
* 방법1. for 중복 오토를 찾은 후, for 대상타겟 갯수만큼, 비교해서 같으면 합침 [추천]
|
|
289
|
+
* 방법2. for 유일한 파일 목록을 추출후, for 중복되는 타겟를 찾음
|
|
290
|
+
*/
|
|
291
|
+
#deduplication(depType) {
|
|
292
|
+
// TODO:: isStatic 처리는 어디서??
|
|
293
|
+
|
|
294
|
+
const all = this._task.entry._getAllList(true);
|
|
295
|
+
let list = [];
|
|
296
|
+
let dupAuto = [];
|
|
297
|
+
let dupTar;
|
|
298
|
+
let newTar;
|
|
299
|
+
let _this = this;
|
|
300
|
+
// let arrTarget = [];
|
|
301
|
+
|
|
302
|
+
if (depType === 1) {
|
|
303
|
+
list = all;
|
|
304
|
+
} else if (depType === 0) {
|
|
305
|
+
all.forEach( v, i => {
|
|
306
|
+
if (v.install.isOverlap === false) list.push(v);
|
|
307
|
+
});
|
|
308
|
+
} else return;
|
|
309
|
+
|
|
310
|
+
// 중복 auto 조회
|
|
311
|
+
list.forEach((v, i) => {
|
|
312
|
+
if (list.some((vv, ii) => {
|
|
313
|
+
return i !== ii && v instanceof vv.constructor && !dupAuto.find( vvv => {
|
|
314
|
+
return vvv.name === v.name; // REVIEW:: 인스턴스타입으로 변경 필요 검토 ??
|
|
315
|
+
});
|
|
316
|
+
})) dupAuto.push(v); // 중복된 auto 삽입
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
dupAuto.forEach(auto => {
|
|
320
|
+
this._list.forEach(tar => {
|
|
321
|
+
// 대상 찾기
|
|
322
|
+
if (tar._original._auto === auto) {
|
|
323
|
+
dupTar = []; // 초기화
|
|
324
|
+
this._list.forEach(dup => {
|
|
325
|
+
// 대상과 원본경로가 같은 소스 찾기
|
|
326
|
+
if (tar !== dup && dup._original.fullPath === tar._original.fullPath) {
|
|
327
|
+
// 텍스트가 아니거나 텍스트이면서 data 가 같은 경우
|
|
328
|
+
if (tar.type !== 30 || (tar.type === 30 && tar.data === dup.data)) {
|
|
329
|
+
dupTar.push(dup);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
// 중복이 있는 경우
|
|
335
|
+
if (dupTar.length > 0) {
|
|
336
|
+
newTar = tar.clone();
|
|
337
|
+
newTar.subPath = auto.modName + path.sep + tar._original.subPath; // set 에 설정
|
|
338
|
+
_this.add(newTar);
|
|
339
|
+
// 부모 변경
|
|
340
|
+
tar.owner = newTar;
|
|
341
|
+
tar.isSave = false;
|
|
342
|
+
dupTar.forEach(val => {
|
|
343
|
+
val.owner = newTar;
|
|
344
|
+
val.isSave = false;
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* 경로 및 파일 중복 제거시, 모듈명 + 별칭 >> 모듈명으로 변경
|
|
354
|
+
*/
|
|
355
|
+
#removeAlias() {
|
|
356
|
+
|
|
357
|
+
const all = this._task.entry._getAllList(false); // entry 는 별칭이 없으므로
|
|
358
|
+
let dupAuto = [], singleAuto = [];
|
|
359
|
+
let sigleTar = [];
|
|
360
|
+
|
|
361
|
+
// 중복 오토 조회
|
|
362
|
+
all.forEach((v, i) => {
|
|
363
|
+
if (all.some((vv, ii) => {
|
|
364
|
+
return i !== ii && v instanceof vv.constructor && !dupAuto.find( vvv => {
|
|
365
|
+
return vvv.name === v.name;
|
|
366
|
+
});
|
|
367
|
+
})) dupAuto.push(v); // 중복된 auto 삽입
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
// 단일 오토 조회
|
|
371
|
+
all.forEach( v => {
|
|
372
|
+
if (dupAuto.some( vv => {
|
|
373
|
+
return !(v instanceof vv.constructor);
|
|
374
|
+
})) singleAuto.push(v); // 단일 auto 삽입
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
singleAuto.forEach(auto => {
|
|
378
|
+
this._list.forEach(tar => {
|
|
379
|
+
// 대상 찾기
|
|
380
|
+
if (tar._original._auto === auto) {
|
|
381
|
+
tar.subPath = auto.modName + path.sep + tar._original.subPath;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
console.log(1)
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* 대상소스 클래스
|
|
392
|
+
*/
|
|
393
|
+
class TargetSource {
|
|
394
|
+
|
|
395
|
+
/*_______________________________________*/
|
|
396
|
+
// public
|
|
397
|
+
isSave = true; // 저장유무, 활성화 상태
|
|
398
|
+
isExcept = false; // save 시점에 제외 여부
|
|
399
|
+
isMerge = false; // 병합 여부
|
|
400
|
+
referType = 0; // 참조하는 타입
|
|
401
|
+
refedType = 0; // 참조되어지는 타입
|
|
402
|
+
type = 0; // 소스타입
|
|
403
|
+
data = null;
|
|
404
|
+
|
|
405
|
+
/*_______________________________________*/
|
|
406
|
+
// protected
|
|
407
|
+
_original = null;
|
|
408
|
+
_owner = null;
|
|
409
|
+
_owned = [];
|
|
410
|
+
_batch = SourceBatch.getInstance();
|
|
411
|
+
|
|
412
|
+
/*_______________________________________*/
|
|
413
|
+
// private
|
|
414
|
+
#dir = null;
|
|
415
|
+
#location = null;
|
|
416
|
+
#fullPath = null;
|
|
417
|
+
|
|
418
|
+
/*_______________________________________*/
|
|
419
|
+
// property
|
|
420
|
+
get fullPath() {
|
|
421
|
+
// return this.#fullPath;
|
|
422
|
+
return this._owner === null ? this.#fullPath : this._owner.fullPath;
|
|
423
|
+
}
|
|
424
|
+
get dir() {
|
|
425
|
+
// return this.#dir;
|
|
426
|
+
return this._owner === null ? this.#dir : this._owner.dir;
|
|
427
|
+
}
|
|
428
|
+
set dir(val) {
|
|
429
|
+
// this.#dir = val;
|
|
430
|
+
if (this._owner === null) this.#dir = val;
|
|
431
|
+
else this._owner.dir = val;
|
|
432
|
+
}
|
|
433
|
+
get location() {
|
|
434
|
+
// return this.#location;
|
|
435
|
+
return this._owner === null ? this.#location : this._owner.location;
|
|
436
|
+
}
|
|
437
|
+
get name() {
|
|
438
|
+
return path.basename(this.fullPath);
|
|
439
|
+
}
|
|
440
|
+
get subDir() {
|
|
441
|
+
return path.dirname(this.subPath);
|
|
442
|
+
}
|
|
443
|
+
get subPath() {
|
|
444
|
+
return path.relative(this.dir + path.sep + this.location, this.fullPath);
|
|
445
|
+
}
|
|
446
|
+
set subPath(val) {
|
|
447
|
+
// this.#fullPath = this.dir + path.sep + this.location + path.sep + val;
|
|
448
|
+
if (this._owner === null) this.#fullPath = this.#dir + path.sep + this.#location + path.sep + val;
|
|
449
|
+
else this._owner.subPath = val;
|
|
450
|
+
}
|
|
451
|
+
get localDir() {
|
|
452
|
+
return path.dirname(this.localPath);
|
|
453
|
+
}
|
|
454
|
+
get localPath() {
|
|
455
|
+
return path.relative(this.dir, this.fullPath);
|
|
456
|
+
}
|
|
457
|
+
set owner(val) {
|
|
458
|
+
this._owner = val; // 소유자
|
|
459
|
+
val._owned.push(this); // 사용된곳 설정
|
|
460
|
+
}
|
|
461
|
+
get owner() {
|
|
462
|
+
return this._owner;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
*
|
|
467
|
+
* @param {*} location
|
|
468
|
+
* @param {*} ori? 선택사항
|
|
469
|
+
*/
|
|
470
|
+
constructor(location, ori) {
|
|
471
|
+
|
|
472
|
+
let entry = this._batch._task.entry;
|
|
473
|
+
let auto = null;
|
|
474
|
+
|
|
475
|
+
this.#location = location;
|
|
476
|
+
|
|
477
|
+
if (ori instanceof OriginalPath) {
|
|
478
|
+
this._original = ori;
|
|
479
|
+
auto = ori._auto;
|
|
480
|
+
this.#setType(ori);
|
|
481
|
+
this.#initPath();
|
|
482
|
+
if (location === entry.LOC.INS) auto.install.add(this);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/*_______________________________________*/
|
|
487
|
+
// public method
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* 소스 내용(data) 설정
|
|
491
|
+
* @param {*} isRoot 절대경로시 location 경로 포함 여부 (install 시점)
|
|
492
|
+
*/
|
|
493
|
+
setData(isRoot = true) {
|
|
494
|
+
|
|
495
|
+
let ori, data, arrObj = [], list, change, refSrc, localDir;
|
|
496
|
+
let dir, entry;
|
|
497
|
+
let type, absolute, relative;
|
|
498
|
+
|
|
499
|
+
ori = this._original;
|
|
500
|
+
data = ori.data;
|
|
501
|
+
arrObj = []; // 초기화
|
|
502
|
+
entry = this._batch._task.entry;
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
for (let ii = 0; ii < ori._dep.length; ii++) {
|
|
506
|
+
|
|
507
|
+
// _dep 객체에 pos 가 존재할 경우만 처리 !!
|
|
508
|
+
if (typeof ori._dep[ii].pos !== 'object') continue;
|
|
509
|
+
|
|
510
|
+
refSrc = ori._dep[ii].ref;
|
|
511
|
+
// 1) 타겟소스가 없을 경우
|
|
512
|
+
if (refSrc._target === null || refSrc._target.fullPath === null) {
|
|
513
|
+
|
|
514
|
+
dir = path.dirname(this.fullPath);
|
|
515
|
+
relative = path.relative(dir, refSrc.fullPath); // 상대경로 (오토기준)
|
|
516
|
+
|
|
517
|
+
if (entry === refSrc._auto) {
|
|
518
|
+
absolute = path.sep + refSrc.localPath;
|
|
519
|
+
} else { // 하위의 경우
|
|
520
|
+
if ( refSrc.dir.indexOf(entry.dir) < 0) { // 앤트리 하위 여부 검사
|
|
521
|
+
throw new Error(' 절대경로를 사용할려면 하위오토는 앤트리 오토의 하위에 있어야 합니다. fail...');
|
|
522
|
+
}
|
|
523
|
+
localDir = path.relative(entry.dir, refSrc.dir);
|
|
524
|
+
absolute = path.sep + localDir + path.sep + refSrc.localPath;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// 2) 타겟소스가 있을 경우
|
|
528
|
+
} else {
|
|
529
|
+
|
|
530
|
+
dir = path.dirname(this.fullPath);
|
|
531
|
+
relative = path.relative(dir, refSrc._target.fullPath);
|
|
532
|
+
|
|
533
|
+
if (entry === refSrc._auto) { // 엔트리의 경우
|
|
534
|
+
if (isRoot) absolute = path.sep + refSrc._target.localPath; // root 기준 절대경로
|
|
535
|
+
else absolute = path.sep + refSrc._target.subPath; // location 기준 절대경로
|
|
536
|
+
} else { // 엔트리 외(하위)의 경우
|
|
537
|
+
// 앤트리 하위 여부 검사
|
|
538
|
+
if ( refSrc._target.dir.indexOf(entry.dir) < 0) {
|
|
539
|
+
throw new Error(' 절대경로를 사용할려면 하위오토는 앤트리 오토의 하위에 있어야 합니다. fail...');
|
|
540
|
+
}
|
|
541
|
+
localDir = path.relative(entry.dir, refSrc._target.dir);
|
|
542
|
+
if (localDir.length > 0) {
|
|
543
|
+
absolute = path.sep + localDir + path.sep + refSrc._target.localPath;
|
|
544
|
+
} else { // 'install', 'depend' 의 경우
|
|
545
|
+
if (isRoot) absolute = path.sep + refSrc._target.localPath;
|
|
546
|
+
else absolute = path.sep + refSrc._target.subPath;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
for (let iii = 0; iii < ori._dep[ii].pos.length; iii++) {
|
|
552
|
+
list = ori._dep[ii].pos[iii];
|
|
553
|
+
|
|
554
|
+
// 경로 설정
|
|
555
|
+
if (this._batch.pathType === 0 ) {
|
|
556
|
+
// type = this.pathType === 0 ? list.type : this.pathType;
|
|
557
|
+
if (this.referType === 0) {
|
|
558
|
+
if (ori._dep[ii].ref._target.refedType === 0) {
|
|
559
|
+
// pos 에서 파싱된 타입 설정
|
|
560
|
+
type = list.type;
|
|
561
|
+
} else {
|
|
562
|
+
// 참조된 대상을 타입 설정
|
|
563
|
+
type = ori._dep[ii].ref._target.refedType;
|
|
564
|
+
}
|
|
565
|
+
} else {
|
|
566
|
+
// 대상 파일의 참조 타입 설정
|
|
567
|
+
type = this.referType;
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
// 전체 경로 타입 설정
|
|
571
|
+
type = this._batch.pathType;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (type === 1) change = absolute;
|
|
575
|
+
else change = relative; // 기본상대경로
|
|
576
|
+
// else if (type === 2) change = relative;
|
|
577
|
+
|
|
578
|
+
arrObj.push({
|
|
579
|
+
idx: list.idx,
|
|
580
|
+
txt: list.key,
|
|
581
|
+
rep: change,
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
// 파일내용 저장
|
|
586
|
+
this.#replaceData(data, arrObj);
|
|
587
|
+
return this.data;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* 타겟소스 복제본 리턴
|
|
592
|
+
* @returns {this}
|
|
593
|
+
*/
|
|
594
|
+
clone() {
|
|
595
|
+
|
|
596
|
+
let obj = new TargetSource(this.location, this._original);
|
|
597
|
+
|
|
598
|
+
obj.isSave = this.isSave;
|
|
599
|
+
obj.isExcept = this.isExcept;
|
|
600
|
+
obj.referType = this.referType;
|
|
601
|
+
obj.refedType = this.refedType;
|
|
602
|
+
obj.data = this.data;
|
|
603
|
+
obj._original = this._original;
|
|
604
|
+
obj._owner = this._owner;
|
|
605
|
+
obj._owned = this._owned.map( (val) => {return val } );
|
|
606
|
+
obj._owned = this._owned;
|
|
607
|
+
obj._batch = this._batch;
|
|
608
|
+
obj.subPath = this.subPath;
|
|
609
|
+
|
|
610
|
+
return obj;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/*_______________________________________*/
|
|
614
|
+
// private method
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* fullPath, dir 속성을 설정한다.
|
|
618
|
+
*/
|
|
619
|
+
#initPath() {
|
|
620
|
+
|
|
621
|
+
let auto, src, useAuto, entry, alias, fullPath;
|
|
622
|
+
let location;
|
|
623
|
+
// const AutoTask = require('./auto-task');
|
|
624
|
+
entry = this._batch._task.entry;
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
src = this._original;
|
|
628
|
+
auto = src._auto;
|
|
629
|
+
location = this.location;
|
|
630
|
+
|
|
631
|
+
if (location == entry.LOC.DIS) {
|
|
632
|
+
if (entry === src._auto) {
|
|
633
|
+
fullPath = auto.dir + path.sep + entry.LOC.DIS + path.sep + src.subPath;
|
|
634
|
+
|
|
635
|
+
} else { // 하위 오토의 경우
|
|
636
|
+
useAuto = auto._owner;
|
|
637
|
+
alias = useAuto.modName +'-'+ auto.alias;
|
|
638
|
+
fullPath = auto.dir + path.sep + entry.LOC.DIS + path.sep + alias + path.sep + src.subPath;
|
|
639
|
+
}
|
|
640
|
+
this.#dir = auto.dir;
|
|
641
|
+
this.#fullPath = fullPath;
|
|
642
|
+
|
|
643
|
+
} else if (location == entry.LOC.DEP) {
|
|
644
|
+
alias = auto.alias;
|
|
645
|
+
fullPath = entry.dir + path.sep + entry.LOC.DEP + path.sep + alias + path.sep + src.subPath;
|
|
646
|
+
this.#dir = entry.dir;
|
|
647
|
+
this.#fullPath = fullPath;
|
|
648
|
+
|
|
649
|
+
} else if (location == entry.LOC.INS) {
|
|
650
|
+
alias = auto.alias ? auto.modName + path.sep + auto.alias : auto.modName;
|
|
651
|
+
fullPath = entry.dir + path.sep + entry.LOC.INS + path.sep + alias + path.sep + src.subPath;
|
|
652
|
+
this.#dir = entry.dir;
|
|
653
|
+
this.#fullPath = fullPath;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* 타입 설정
|
|
659
|
+
* @param {OriginalPath} ori
|
|
660
|
+
* @returns {*}
|
|
661
|
+
*/
|
|
662
|
+
#setType(ori) {
|
|
663
|
+
|
|
664
|
+
let type = 0;
|
|
665
|
+
|
|
666
|
+
if (ori instanceof VirtualFolder) this.type = 10;
|
|
667
|
+
if (ori instanceof NonTextFile) this.type = 20;
|
|
668
|
+
if (ori instanceof TextFile) this.type = 30;
|
|
669
|
+
|
|
670
|
+
return type;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* 파일내용(data) 을 배열에 맞게 교체한다.
|
|
675
|
+
* @param {*} data
|
|
676
|
+
* @param {*} arrObj
|
|
677
|
+
*/
|
|
678
|
+
#replaceData(data, arrObj) {
|
|
679
|
+
// replace
|
|
680
|
+
var obj;
|
|
681
|
+
var base_idx = 0, idx = 0;
|
|
682
|
+
var ori_data = data;
|
|
683
|
+
var ori_prev = '', ori_next = '';
|
|
684
|
+
|
|
685
|
+
// 배열 정렬
|
|
686
|
+
arrObj.sort(function (a,b) {
|
|
687
|
+
if (a.idx > b.idx) return 1;
|
|
688
|
+
if (a.idx === b.idx) return 0;
|
|
689
|
+
if (a.idx < b.idx) return -1;
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
for(var i = 0; i < arrObj.length; i++) {
|
|
693
|
+
obj = arrObj[i];
|
|
694
|
+
// rep 문자열검사
|
|
695
|
+
// txt 문자열 1 이상
|
|
696
|
+
// idx >
|
|
697
|
+
if (typeof obj.idx !== 'number' || typeof obj.txt !== 'string') {
|
|
698
|
+
console.warn('객체아님');
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
idx = obj.idx + base_idx; // 시작 인텍스
|
|
702
|
+
if (ori_data.substr(idx, obj.txt.length) === obj.txt) { // 검사
|
|
703
|
+
ori_prev = ori_data.slice(0, idx); // 앞 문자열
|
|
704
|
+
ori_next = ori_data.slice(idx + obj.txt.length); // 뒤 문자열
|
|
705
|
+
ori_data = ori_prev + obj.rep + ori_next;
|
|
706
|
+
base_idx = base_idx + obj.rep.length - obj.txt.length;
|
|
707
|
+
} else {
|
|
708
|
+
console.warn('실패 '+ obj);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
this.data = ori_data;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* 인스톨맵 클래스
|
|
717
|
+
*/
|
|
718
|
+
class InstallMap {
|
|
719
|
+
|
|
720
|
+
/*_______________________________________*/
|
|
721
|
+
// public
|
|
722
|
+
isOverlap = false;
|
|
723
|
+
|
|
724
|
+
/*_______________________________________*/
|
|
725
|
+
// protected
|
|
726
|
+
_auto = null;
|
|
727
|
+
_task = at.AutoTask.getInstance();
|
|
728
|
+
_parent = null;
|
|
729
|
+
_child = [];
|
|
730
|
+
_setup = [];
|
|
731
|
+
_merge = [];
|
|
732
|
+
_rename = [];
|
|
733
|
+
_except = [];
|
|
734
|
+
_list = [];
|
|
735
|
+
|
|
736
|
+
/*_______________________________________*/
|
|
737
|
+
// property
|
|
738
|
+
get targets() {
|
|
739
|
+
|
|
740
|
+
let arr = [];
|
|
741
|
+
|
|
742
|
+
for (let i = 0; i < this._child.length; i++) {
|
|
743
|
+
arr = arr.concat(this._child[i].targets);
|
|
744
|
+
}
|
|
745
|
+
for (let i = 0; i < this._list.length; i++) {
|
|
746
|
+
if (this._list[i].isSave === true) arr.push(this._list[i]);
|
|
747
|
+
}
|
|
748
|
+
return arr;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
constructor(auto, json) {
|
|
752
|
+
this._auto = auto;
|
|
753
|
+
if (json) this.#load(json);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/*_______________________________________*/
|
|
757
|
+
// public method
|
|
758
|
+
|
|
759
|
+
// 객체 얻기
|
|
760
|
+
getObject() {
|
|
761
|
+
|
|
762
|
+
var obj = {};
|
|
763
|
+
|
|
764
|
+
for (var prop in this) {
|
|
765
|
+
if (['_setup', '_merge', '_except', '_global', '_rename', 'isOverlap'].indexOf(prop) > -1) {
|
|
766
|
+
obj[prop.replace('_', '')] = this[prop];
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return obj;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* 타겟소스 추가
|
|
774
|
+
* @param {TargetSource} target
|
|
775
|
+
*/
|
|
776
|
+
add(target) {
|
|
777
|
+
this._list.push(target);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* 인스톨맵 초기화 : _parent, _child 설정
|
|
782
|
+
*/
|
|
783
|
+
init() {
|
|
784
|
+
|
|
785
|
+
const auto = this._auto;
|
|
786
|
+
|
|
787
|
+
if (auto._owner && auto._owner.install instanceof InstallMap) {
|
|
788
|
+
this._parent = auto._owner.install; // 부모 InstallMap 연결
|
|
789
|
+
auto._owner.install._child.push(this); // 자식 InstallMap 등록
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* 인트롤맵 처리 : 세팅 >> 이름변경 >> 병합 >> 제외
|
|
795
|
+
*/
|
|
796
|
+
execute() {
|
|
797
|
+
|
|
798
|
+
if (this._setup.length > 0) this.#execSetup();
|
|
799
|
+
if (this._rename.length > 0) this.#execRename();
|
|
800
|
+
if (this._merge.length > 0) this.#execMerge();
|
|
801
|
+
if (this._except.length > 0) this.#execExcept();
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/*_______________________________________*/
|
|
805
|
+
// private method
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* json 객체를 통해 객체 가져오기 (생성시)
|
|
809
|
+
* @param {JSON} json
|
|
810
|
+
*/
|
|
811
|
+
#load(json) {
|
|
812
|
+
|
|
813
|
+
let obj;
|
|
814
|
+
|
|
815
|
+
// setup obj
|
|
816
|
+
if (json.setup && Array.isArray(json.setup)) {
|
|
817
|
+
for (let i = 0; i < json.setup.length; i++) {
|
|
818
|
+
if (typeof json.setup[i] === 'object' && typeof json.setup[i].glob === 'string') {
|
|
819
|
+
this._setup.push(json.setup[i]);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
// merge obj
|
|
824
|
+
if (json.merge && Array.isArray(json.merge)) {
|
|
825
|
+
for (let i = 0; i < json.merge.length; i++) {
|
|
826
|
+
if (typeof json.merge[i] === 'object' && Array.isArray(json.merge[i].paths) && typeof json.merge[i].path === 'string') {
|
|
827
|
+
this._merge.push(json.merge[i]);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
// rename obj
|
|
832
|
+
if (json.rename && Array.isArray(json.rename)) {
|
|
833
|
+
for (let i = 0; i < json.rename.length; i++) {
|
|
834
|
+
if (typeof json.rename[i] === 'object' && typeof json.rename[i].glob === 'string' && (typeof json.rename[i].path === 'string' || typeof json.rename[i].dir === 'string')) {
|
|
835
|
+
this._rename.push(json.rename[i]);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
// except obj
|
|
840
|
+
if (json.except && Array.isArray(json.except)) {
|
|
841
|
+
for (let i = 0; i < json.except.length; i++) {
|
|
842
|
+
if (typeof json.except[i] === 'string') this._except.push(json.except[i]);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* setup 실행
|
|
849
|
+
*/
|
|
850
|
+
#execSetup() {
|
|
851
|
+
|
|
852
|
+
let obj, tars = [], arr = [];
|
|
853
|
+
|
|
854
|
+
for (let i = 0; i < this._setup.length; i++) {
|
|
855
|
+
|
|
856
|
+
obj = this._setup[i];
|
|
857
|
+
|
|
858
|
+
if (typeof obj.glob === 'string' && obj.glob.length > 0) {
|
|
859
|
+
arr = mm.match(this.targets.map((obj) => { return obj.subPath }), obj.glob);
|
|
860
|
+
}
|
|
861
|
+
if (arr.length > 0) {
|
|
862
|
+
tars = this.targets.filter((obj) => { return arr.indexOf(obj.subPath) > -1 })
|
|
863
|
+
|
|
864
|
+
if (obj.isExcept && typeof obj.isExcept === 'boolean') {
|
|
865
|
+
tars.map( (o) => { o.isExcept = obj.isExcept; });
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
if (obj.referType && typeof obj.referType === 'number') {
|
|
869
|
+
tars.map( (o) => { o.referType = obj.referType; });
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
if (obj.refedType && typeof obj.refedType === 'number') {
|
|
873
|
+
tars.map( (o) => { o.refedType = obj.refedType; });
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* 이름변경 실행
|
|
881
|
+
* - 단일 파일명 변경
|
|
882
|
+
* - 복수 경로 변경 (폴더)
|
|
883
|
+
*/
|
|
884
|
+
#execRename() {
|
|
885
|
+
|
|
886
|
+
let arr = [], obj, tars = [];
|
|
887
|
+
let entry = this._task.entry;
|
|
888
|
+
const batch = this._task.batch;
|
|
889
|
+
let fullPath, subPath;
|
|
890
|
+
|
|
891
|
+
for (let i = 0; i < this._rename.length; i++) {
|
|
892
|
+
obj = this._rename[i];
|
|
893
|
+
// 동시에 존재시 경고 후 처리 무시
|
|
894
|
+
if (typeof obj.path === 'string' && typeof obj.dir === 'string') {
|
|
895
|
+
console.warn('install.rename 객체에 path, dir 동시에 존재합니다. 하나만 사용하세요.');
|
|
896
|
+
continue;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (typeof obj.glob === 'string' && obj.glob.length > 0 && (obj.path || obj.dir)) {
|
|
900
|
+
arr = mm.match(this.targets.map((o) => { return o.subPath }), obj.glob);
|
|
901
|
+
// arr = mm.match( this.targetPaths, obj.glob);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (arr.length > 0) {
|
|
905
|
+
|
|
906
|
+
// tars = this._getTarget(arr);
|
|
907
|
+
tars = this.targets.filter((o) => { return arr.indexOf(o.subPath) > -1 })
|
|
908
|
+
|
|
909
|
+
// glob, path 처리
|
|
910
|
+
if (typeof obj.path === 'string' && obj.path.length > 0) {
|
|
911
|
+
if (arr.length !== 1) {
|
|
912
|
+
console.warn('install.rename 객체에 path 는 glob 하나마 매칭되어야 합니다.' + arr);
|
|
913
|
+
continue;
|
|
914
|
+
}
|
|
915
|
+
// static 검사
|
|
916
|
+
if (tars[0]._original.isStatic === true) {
|
|
917
|
+
console.warn('static 파일은 이름은 변경할 수 없습니다.' + tars[0]._original.fullPath);
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
subPath = obj.path;
|
|
921
|
+
fullPath = tars[0].dir + path.sep + tars[0].location + path.sep + subPath;
|
|
922
|
+
// 중복검사
|
|
923
|
+
if (!batch.validPath(fullPath)) {
|
|
924
|
+
subPath = path.dirname(subPath) + path.sep + batch.newFileName(fullPath);
|
|
925
|
+
console.warn('[중복파일 이름재정의] ' + fullPath + ' >> ' + subPath)
|
|
926
|
+
}
|
|
927
|
+
tars[0].subPath = subPath;
|
|
928
|
+
|
|
929
|
+
// glob, dir 처리
|
|
930
|
+
} else if (typeof obj.dir === 'string' && obj.dir.length > 0) {
|
|
931
|
+
|
|
932
|
+
for (let i = 0; i < tars.length; i++) {
|
|
933
|
+
// static 검사
|
|
934
|
+
if (tars[i]._original.isStatic === true) {
|
|
935
|
+
console.warn('static 파일은 이름은 변경할 수 없습니다.' + tars[i]._original.fullPath);
|
|
936
|
+
continue;
|
|
937
|
+
}
|
|
938
|
+
if (tars[i].type === 10) { // VirtualFolder
|
|
939
|
+
tars[i].subPath = obj.dir;
|
|
940
|
+
} else if (tars[i].type === 20 || tars[i].type === 30) { // TextFile & NonTextFile
|
|
941
|
+
|
|
942
|
+
subPath = obj.dir + path.sep + tars[i].name;
|
|
943
|
+
fullPath = tars[i].dir + path.sep + tars[i].location + path.sep + subPath;
|
|
944
|
+
// 중복검사
|
|
945
|
+
if (!batch.validPath(fullPath)) {
|
|
946
|
+
subPath = path.dirname(subPath) + path.sep + batch.newFileName(fullPath);
|
|
947
|
+
console.warn('[중복파일 이름재정의] ' + fullPath + ' >> ' + subPath)
|
|
948
|
+
}
|
|
949
|
+
tars[i].subPath = subPath;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* 파일 머지는 특수한 경우이다. 타겟소스의 타입이 텍스트의 경우만 유효하다.
|
|
959
|
+
*/
|
|
960
|
+
#execMerge() {
|
|
961
|
+
|
|
962
|
+
let obj, arr = [], tars = [], newTar;
|
|
963
|
+
const entry = this._task.entry;
|
|
964
|
+
const batch = this._task.batch;
|
|
965
|
+
|
|
966
|
+
for (let i = 0; i < this._merge.length; i++) {
|
|
967
|
+
|
|
968
|
+
obj = this._merge[i];
|
|
969
|
+
|
|
970
|
+
// 유효성 검사
|
|
971
|
+
if (typeof Array.isArray(obj.paths) && obj.paths.length > 0 && typeof obj.path === 'string' && obj.path.length > 0) {
|
|
972
|
+
obj.paths.forEach(v => {
|
|
973
|
+
if (typeof v === 'string' && v.length > 0) arr.push(v);
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
if (arr.length > 0) {
|
|
977
|
+
|
|
978
|
+
arr.forEach(v => {
|
|
979
|
+
let find = this.targets.find(vv => { return vv.subPath === v });
|
|
980
|
+
if (find) tars.push(find);
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
if (tars.length > 0) {
|
|
984
|
+
newTar = new TargetSource(entry.LOC.INS, null);
|
|
985
|
+
newTar.dir = entry.dir;
|
|
986
|
+
newTar.type = 30;
|
|
987
|
+
newTar.subPath = obj.path;
|
|
988
|
+
newTar.data = '';
|
|
989
|
+
newTar.isMerge = true;
|
|
990
|
+
|
|
991
|
+
tars.forEach(v => {
|
|
992
|
+
if (v.type === 30) {
|
|
993
|
+
newTar.data += v._original.data + '\n'; // TODO:: 삭제해야함 isMerge = true
|
|
994
|
+
v.owner = newTar;
|
|
995
|
+
v.isSave = false;
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
batch.add(newTar);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* install 시 제외 파일 설정
|
|
1006
|
+
*/
|
|
1007
|
+
#execExcept() {
|
|
1008
|
+
|
|
1009
|
+
let str, tars = [], arr = [];
|
|
1010
|
+
|
|
1011
|
+
for (let i = 0; i < this._except.length; i++) {
|
|
1012
|
+
str = this._except[i];
|
|
1013
|
+
if (typeof str === 'string' && str.length > 0) {
|
|
1014
|
+
arr = mm.match(this.targets.map((obj) => { return obj.subPath }), str);
|
|
1015
|
+
|
|
1016
|
+
if (arr.length > 0) {
|
|
1017
|
+
tars = this.targets.filter((obj) => { return arr.indexOf(obj.subPath) > -1 })
|
|
1018
|
+
tars.map( (o) => { o.isExcept = true; });
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
exports.SourceBatch = SourceBatch;
|
|
1026
|
+
exports.TargetSource = TargetSource;
|
|
1027
|
+
exports.InstallMap = InstallMap;
|