@profitlich/template-toolkit 2.8.4 ā 2.10.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/package.json +1 -1
- package/scripts/deploy.js +103 -67
package/package.json
CHANGED
package/scripts/deploy.js
CHANGED
|
@@ -24,6 +24,7 @@ async function createClient(accessOptions) {
|
|
|
24
24
|
const client = new ftp.Client();
|
|
25
25
|
client.ftp.verbose = false;
|
|
26
26
|
await client.access(accessOptions);
|
|
27
|
+
client.ftp.socket.setKeepAlive(true, 10000);
|
|
27
28
|
return client;
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -38,34 +39,35 @@ export async function runDeploy(mode, uploadTasks, options = {}) {
|
|
|
38
39
|
secure: true
|
|
39
40
|
};
|
|
40
41
|
|
|
42
|
+
const mainClient = new ftp.Client();
|
|
43
|
+
mainClient.ftp.verbose = false;
|
|
41
44
|
let activeProgressBar = null;
|
|
42
45
|
|
|
43
46
|
try {
|
|
44
47
|
console.log(`š Starting deployment for: ${modeUpper}`);
|
|
45
48
|
|
|
49
|
+
await mainClient.access(accessOptions);
|
|
50
|
+
mainClient.ftp.socket.setKeepAlive(true, 10000);
|
|
51
|
+
|
|
46
52
|
for (const task of uploadTasks) {
|
|
47
53
|
console.log(`\nProcessing Task: ${task.name}`);
|
|
48
54
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
const files = await glob(task.localPattern, {
|
|
56
|
+
nodir: true,
|
|
57
|
+
dot: true,
|
|
58
|
+
ignore: task.ignore
|
|
59
|
+
});
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
});
|
|
61
|
+
if (files.length === 0) {
|
|
62
|
+
console.log('No files found for this task.');
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
66
|
+
// Determine which files are newer than their remote counterparts
|
|
67
|
+
process.stdout.write(` Checking ${files.length} files...`);
|
|
68
|
+
const filesToUpload = [];
|
|
65
69
|
|
|
66
|
-
|
|
67
|
-
process.stdout.write(` Checking ${files.length} files...`);
|
|
68
|
-
const filesToUpload = [];
|
|
70
|
+
if (parallel <= 1) {
|
|
69
71
|
for (const file of files) {
|
|
70
72
|
const relativeFile = path.relative(task.localBase, file);
|
|
71
73
|
const remotePath = path.join(task.remoteDir, relativeFile).replace(/\\/g, '/');
|
|
@@ -73,64 +75,96 @@ export async function runDeploy(mode, uploadTasks, options = {}) {
|
|
|
73
75
|
filesToUpload.push({ file, remotePath });
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
|
-
|
|
78
|
+
} else {
|
|
79
|
+
const checkWorkerCount = Math.min(parallel, files.length);
|
|
80
|
+
const checkWorkers = await Promise.all(
|
|
81
|
+
Array.from({ length: checkWorkerCount }, () => createClient(accessOptions))
|
|
82
|
+
);
|
|
83
|
+
const checkQueue = [...files];
|
|
84
|
+
await Promise.all(checkWorkers.map(async (workerClient) => {
|
|
85
|
+
try {
|
|
86
|
+
while (true) {
|
|
87
|
+
const file = checkQueue.shift();
|
|
88
|
+
if (!file) break;
|
|
89
|
+
const relativeFile = path.relative(task.localBase, file);
|
|
90
|
+
const remotePath = path.join(task.remoteDir, relativeFile).replace(/\\/g, '/');
|
|
91
|
+
if (await isNewer(workerClient, file, remotePath)) {
|
|
92
|
+
filesToUpload.push({ file, remotePath });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
} finally {
|
|
96
|
+
workerClient.close();
|
|
97
|
+
}
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
77
100
|
|
|
78
|
-
|
|
79
|
-
console.log(' All files are up to date, skipping.');
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
101
|
+
process.stdout.write(` ${filesToUpload.length} changed.\n`);
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
hideCursor: true
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
activeProgressBar = progressBar;
|
|
91
|
-
progressBar.start(filesToUpload.length, 0);
|
|
92
|
-
|
|
93
|
-
if (parallel <= 1) {
|
|
94
|
-
for (const { file, remotePath } of filesToUpload) {
|
|
95
|
-
await mainClient.ensureDir(path.dirname(remotePath));
|
|
96
|
-
await mainClient.uploadFrom(file, remotePath);
|
|
97
|
-
progressBar.increment();
|
|
98
|
-
}
|
|
99
|
-
} else {
|
|
100
|
-
// Pre-create all required remote directories with the main client
|
|
101
|
-
const uniqueDirs = [...new Set(filesToUpload.map(({ remotePath }) => path.dirname(remotePath)))];
|
|
102
|
-
for (const dir of uniqueDirs) {
|
|
103
|
-
await mainClient.ensureDir(dir);
|
|
104
|
-
}
|
|
103
|
+
if (filesToUpload.length === 0) {
|
|
104
|
+
console.log(' All files are up to date, skipping.');
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
108
|
+
const progressBar = new cliProgress.SingleBar({
|
|
109
|
+
format: ' Upload |{bar}| {percentage}% {value}/{total} files {duration_formatted}',
|
|
110
|
+
barCompleteChar: 'ā',
|
|
111
|
+
barIncompleteChar: 'ā',
|
|
112
|
+
hideCursor: true
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
activeProgressBar = progressBar;
|
|
116
|
+
progressBar.start(filesToUpload.length, 0);
|
|
117
|
+
|
|
118
|
+
if (parallel <= 1) {
|
|
119
|
+
for (const { file, remotePath } of filesToUpload) {
|
|
120
|
+
await mainClient.ensureDir(path.dirname(remotePath));
|
|
121
|
+
await mainClient.uploadFrom(file, remotePath);
|
|
122
|
+
progressBar.increment();
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
// Pre-create all required remote directories with the main client
|
|
126
|
+
const uniqueDirs = [...new Set(filesToUpload.map(({ remotePath }) => path.dirname(remotePath)))];
|
|
127
|
+
for (const dir of uniqueDirs) {
|
|
128
|
+
await mainClient.ensureDir(dir);
|
|
129
|
+
}
|
|
111
130
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
131
|
+
// Spawn parallel worker connections
|
|
132
|
+
const workerCount = Math.min(parallel, filesToUpload.length);
|
|
133
|
+
const workers = await Promise.all(
|
|
134
|
+
Array.from({ length: workerCount }, () => createClient(accessOptions))
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
const queue = [...filesToUpload];
|
|
138
|
+
await Promise.all(workers.map(async (initialWorkerClient) => {
|
|
139
|
+
let workerClient = initialWorkerClient;
|
|
140
|
+
try {
|
|
141
|
+
while (true) {
|
|
142
|
+
const item = queue.shift();
|
|
143
|
+
if (!item) break;
|
|
144
|
+
let retries = 0;
|
|
115
145
|
while (true) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
146
|
+
try {
|
|
147
|
+
await workerClient.uploadFrom(item.file, item.remotePath);
|
|
148
|
+
break;
|
|
149
|
+
} catch (err) {
|
|
150
|
+
retries++;
|
|
151
|
+
workerClient.close();
|
|
152
|
+
if (retries >= 3) throw err;
|
|
153
|
+
await delay(1000 * retries);
|
|
154
|
+
workerClient = await createClient(accessOptions);
|
|
155
|
+
}
|
|
120
156
|
}
|
|
121
|
-
|
|
122
|
-
workerClient.close();
|
|
157
|
+
progressBar.increment();
|
|
123
158
|
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
activeProgressBar = null;
|
|
129
|
-
await delay(50);
|
|
130
|
-
|
|
131
|
-
} finally {
|
|
132
|
-
mainClient.close();
|
|
159
|
+
} finally {
|
|
160
|
+
workerClient.close();
|
|
161
|
+
}
|
|
162
|
+
}));
|
|
133
163
|
}
|
|
164
|
+
|
|
165
|
+
activeProgressBar.stop();
|
|
166
|
+
activeProgressBar = null;
|
|
167
|
+
await delay(50);
|
|
134
168
|
}
|
|
135
169
|
|
|
136
170
|
console.log('\nā
Deployment completed successfully!');
|
|
@@ -140,6 +174,8 @@ export async function runDeploy(mode, uploadTasks, options = {}) {
|
|
|
140
174
|
activeProgressBar.stop();
|
|
141
175
|
}
|
|
142
176
|
console.error('Deployment failed:', err);
|
|
177
|
+
} finally {
|
|
178
|
+
mainClient.close();
|
|
143
179
|
}
|
|
144
180
|
}
|
|
145
181
|
|