cob-cli 2.28.0 → 2.29.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.
@@ -17,9 +17,9 @@ async function customize(filter, args) {
17
17
  checkVersion();
18
18
  if (!args.force) await checkWorkingCopyCleanliness();
19
19
 
20
- let repo = await getCustomizationRepo(filter,args);
21
- if (!args.local) await getCustomizationFiles(repo);
22
- await applyCustomization(repo);
20
+ let customizationRepo = await getCustomizationRepo(filter,args);
21
+ if (!args.local) await getCustomizationFiles(customizationRepo);
22
+ await applyCustomization(customizationRepo);
23
23
 
24
24
  console.log( colors.green("\nDone"), "\nCheck changes to your git working tree and try:" );
25
25
  console.log( "\tcob-cli test\n" );
@@ -39,7 +39,7 @@ async function getCustomizationRepo(filter, args) {
39
39
  if (args.local) {
40
40
  customizationRepos = JSON.parse(fs.readFileSync(cacheCustomizations))
41
41
  if (filter) {
42
- customizationRepos = customizationRepos.filter(repo => repo.name.indexOf(filter) != -1)
42
+ customizationRepos = customizationRepos.filter(customizationRepo => customizationRepo.name.indexOf(filter) != -1)
43
43
  }
44
44
  } else {
45
45
  // Get list of relevant customizations from github
@@ -59,8 +59,8 @@ async function getCustomizationRepo(filter, args) {
59
59
  throw new Error("\nError: ".red + " incompatible options, --local AND --cache\n");
60
60
  } else if(args.cache) {
61
61
  console.log("Caching all customizations...");
62
- for( let repo of customizationRepos) {
63
- await getCustomizationFiles(repo);
62
+ for( let customizationRepo of customizationRepos) {
63
+ await getCustomizationFiles(customizationRepo);
64
64
  }
65
65
  fs.writeFileSync( cacheCustomizations,
66
66
  JSON.stringify(customizationRepos, null, 2),
@@ -75,40 +75,40 @@ async function getCustomizationRepo(filter, args) {
75
75
  type: "list",
76
76
  name: "customization",
77
77
  message: "What customization do you want to apply?",
78
- choices: customizationRepos.map((repo) => repo.name).sort(),
78
+ choices: customizationRepos.map((customizationRepo) => customizationRepo.name).sort(),
79
79
  },
80
80
  ]);
81
81
 
82
- //Return the full repo info
83
- return customizationRepos.find((repo) => repo.name == answer.customization);
82
+ //Return the full customizationRepo info
83
+ return customizationRepos.find((customizationRepo) => customizationRepo.name == answer.customization);
84
84
  }
85
85
 
86
86
  /* ************************************************************************ */
87
- async function getCustomizationFiles(repo) {
87
+ async function getCustomizationFiles(customizationRepo) {
88
88
  const { xdgData } = await import("xdg-basedir");
89
89
  const baseDir = process.cwd();
90
90
  const cacheDir = path.resolve(xdgData,"cob-cli")
91
91
  if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
92
92
 
93
93
  process.chdir(cacheDir);
94
- if (!fs.existsSync(path.resolve(cacheDir,repo.name))) {
95
- console.log(" git " + repo.ssh_url);
96
- await git().clone(repo.ssh_url);
94
+ if (!fs.existsSync(path.resolve(cacheDir,customizationRepo.name))) {
95
+ console.log(" git " + customizationRepo.ssh_url);
96
+ await git().clone(customizationRepo.ssh_url);
97
97
  } else {
98
- console.log(" git pull " + repo.ssh_url);
99
- process.chdir(repo.name);
98
+ console.log(" git pull " + customizationRepo.ssh_url);
99
+ process.chdir(customizationRepo.name);
100
100
  await git().pull();
101
101
  }
102
102
  process.chdir(baseDir);
103
103
  }
104
104
 
105
105
  /* ************************************************************************ */
106
- async function applyCustomization(repo) {
107
- console.log("\nApplying " + repo.name + " customization ...");
106
+ async function applyCustomization(customizationRepo) {
107
+ console.log("\nApplying " + customizationRepo.name + " customization ...");
108
108
 
109
109
  // Get customization info from convention defined file (customize.js)
110
110
  const { xdgData } = await import("xdg-basedir");
111
- const customizationPath = path.resolve( xdgData, "cob-cli", repo.name);
111
+ const customizationPath = path.resolve( xdgData, "cob-cli", customizationRepo.name);
112
112
  const customizationFile = path.resolve( customizationPath, "customize.js");
113
113
  if (!fs.existsSync(customizationFile))
114
114
  throw new Error("\nError: ".red + " no customize.js file found\n");
@@ -123,31 +123,30 @@ async function applyCustomization(repo) {
123
123
 
124
124
  // Apply specific customization, if it exists, otherwise use default actions
125
125
  if (customization.actions) {
126
- customization.actions(repo.name, answers, copy, mergeFiles);
126
+ customization.actions(customizationRepo.name, answers, copyAndMerge);
127
127
  } else {
128
128
  // Default actions
129
- await copy(repo.name, process.cwd(), answers);
130
- await mergeFiles(repo.name);
129
+ copyAndMerge(customizationRepo.name, answers);
131
130
  }
132
131
 
133
132
  // Update customizations.json file
134
- updateCustomizationsVersions(repo.name, customization.version);
133
+ updateCustomizationsVersions(customizationRepo.name, customization.version);
135
134
  }
136
135
 
137
136
  /* ************************************************************************ */
138
- async function copy(repoName, target, substitutions = {}) {
137
+ async function copyAndMerge(customizationRepoName, substitutions = {}) {
139
138
  // https://www.npmtrends.com/copyfiles-vs-cpx-vs-ncp-vs-npm-build-tools
140
139
  // https://www.npmjs.com/package/ncp
141
140
  // https://www.npmjs.com/package/copyfiles
142
141
 
143
142
  let source
144
- if(repoName.indexOf("/") == 0) {
145
- // Based of repoName starting with "/" we assume this is already a fullpath
146
- source = repoName;
143
+ if(customizationRepoName.indexOf("/") == 0) {
144
+ // Based of customizationRepoName starting with "/" we assume this is already a fullpath
145
+ source = customizationRepoName;
147
146
  } else {
148
- // Otherwise assume repoName on standard cob-cli xdgData path
147
+ // Otherwise assume customizationRepoName on standard cob-cli xdgData path
149
148
  const { xdgData } = await import("xdg-basedir");
150
- source = path.resolve( xdgData, "cob-cli", repoName);
149
+ source = path.resolve( xdgData, "cob-cli", customizationRepoName);
151
150
  }
152
151
 
153
152
  console.log(" Copying template files ...");
@@ -164,30 +163,53 @@ async function copy(repoName, target, substitutions = {}) {
164
163
  ")"
165
164
  );
166
165
 
167
- // Source is on cob-cli repo and Destination on the server repo
168
- await ncp(
166
+ // Source is on cob-cli customizationRepo and Destination on the server repo
167
+ const target = process.cwd() // Always copy to directory where command is being executed, ie, the root directory of the server repo
168
+ const substitutionRegex = /__(((?!word).)*)__/g;
169
+ ncp(
169
170
  source,
170
171
  target,
171
172
  {
172
173
  clobber: true,
173
174
  filter: (src) => src.match(excludedFiles) == null,
174
- // TODO: comentado porque não funciona a copiar os ficheiros binários (em concreto as font no template/dashboards/dash)
175
- // transform(read, write) {
176
- // const replaceVars = new Transform({
177
- // transform: (chunk, encoding, done) => done(null,chunk.toString().replace(/__.+__/g, m => substitutions[m]))
178
- // })
179
- // read.pipe(replaceVars).pipe(write)
180
- // }
175
+ rename: function(target) {
176
+ // Don't rename __MERGE__ templates, they will be handled by the merge method
177
+ if (target.match(/__MERGE__/)) return target;
178
+
179
+ //get finalTarget from target with any existing substitution
180
+ const finalTarget = target.replace(substitutionRegex, (match,g1) => substitutions[g1] ? substitutions[g1] : match);
181
+
182
+ //if the directory of finalTarget doesn't exists it means that a replacement ocurred on the dirpath (ie, there was a /__.+__/ was on the dirpath), in which case we need to create the desired directory and remove the one just created by ncp
183
+ if (!fs.existsSync(path.dirname(finalTarget))) {
184
+ fs.mkdirSync(path.dirname(finalTarget), { recursive: true })
185
+ fs.rmdirSync(target.substring(0,target.lastIndexOf("__")+2), { recursive: true,force: false }) //NOTE: won't handle more than 1 substitution on the same dirpath
186
+ }
187
+ return finalTarget;
188
+ },
189
+ transform(read, write) {
190
+ const replaceVarsTransformFunction = new Transform({
191
+ transform: (chunk, encoding, done) => {
192
+ if(/\ufffd/.test(chunk) === true) {
193
+ // If chunk is binary don't change anything
194
+ done(null, chunk)
195
+ } else {
196
+ // Otherwise change any existing substitution
197
+ done(null,chunk.toString().replace(substitutionRegex, (match,g1) => substitutions[g1] ? substitutions[g1] : match))
198
+ }
199
+ }
200
+ })
201
+ read.pipe(replaceVarsTransformFunction).pipe(write)
202
+ }
181
203
  },
182
- (error) => error && error.map((e) => e.message).join("\n")
183
- );
184
-
185
- const dryrun = await fg(["**/*__*__*"], { onlyFiles: false, dot: true }); //Just to give time for OS to stabilize
186
- const files = await fg(["**/*__*__*"], { onlyFiles: false, dot: true });
187
- for(let file of files.filter(name => name.indexOf("node_modules") == -1)) {
188
- if (file.match(/__MERGE__/)) return;
189
- fs.renameSync( file, file.replace(/__(.+)__/g, (match,g1) => substitutions[g1]) );
190
- }
204
+ (error) => {
205
+ // If no error occurred then proced with merging files
206
+ if(!error) {
207
+ mergeFiles(customizationRepoName);
208
+ } else {
209
+ throw new Error(error.map((e) => e.message).join("\n"))
210
+ }
211
+ }
212
+ )
191
213
  }
192
214
 
193
215
  /* ************************************************************************ */
@@ -235,14 +257,12 @@ async function mergeFiles(block) {
235
257
  /* ************************************************************************ */
236
258
  function updateCustomizationsVersions(customizationKey, version) {
237
259
  const customizationsVersionsFile = "customizations.json";
238
- let customizationsVersions;
239
- try {
260
+ let customizationsVersions = {};
261
+ if(fs.existsSync(customizationsVersionsFile)) {
240
262
  const customizationsVersionsRawData = fs.readFileSync(customizationsVersionsFile);
241
263
  customizationsVersions = JSON.parse(customizationsVersionsRawData);
242
- } catch (err) {
243
- customizationsVersions = {};
244
264
  }
245
- customizationsVersions[customizationKey] = version;
265
+ customizationsVersions = {[customizationKey]: version, ...customizationsVersions}
246
266
 
247
267
  fs.writeFileSync(
248
268
  customizationsVersionsFile,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cob-cli",
3
- "version": "2.28.0",
3
+ "version": "2.29.0",
4
4
  "description": "A command line utility to help Cult of Bits partners develop with higher speed and reusing common code and best practices.",
5
5
  "preferGlobal": true,
6
6
  "repository": {