@esgettext/tools 1.2.0 → 1.3.1

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.
@@ -27,6 +27,7 @@ exports.Install = void 0;
27
27
  const fs_1 = require("fs");
28
28
  const runtime_1 = require("@esgettext/runtime");
29
29
  const mkdirp = __importStar(require("mkdirp"));
30
+ const optspec_1 = require("../optspec");
30
31
  const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
31
32
  class Install {
32
33
  constructor(configuration) {
@@ -47,8 +48,8 @@ class Install {
47
48
  var _a, _b, _c, _d, _e, _f;
48
49
  return {
49
50
  locales: {
51
+ multi: true,
50
52
  alias: 'l',
51
- type: 'array',
52
53
  describe: gtx._('List of locale identifiers'),
53
54
  demandOption: true,
54
55
  default: (_a = this.configuration.po) === null || _a === void 0 ? void 0 : _a.locales,
@@ -129,8 +130,11 @@ class Install {
129
130
  }
130
131
  }
131
132
  run(argv) {
132
- this.init(argv);
133
133
  return new Promise(resolve => {
134
+ if (!(0, optspec_1.coerceOptions)(argv, this.args())) {
135
+ return resolve(1);
136
+ }
137
+ this.init(argv);
134
138
  const promises = [];
135
139
  for (let i = 0; i < this.locales.length; ++i) {
136
140
  const locale = this.locales[i];
@@ -233,7 +237,11 @@ class Install {
233
237
  installLocale(locale) {
234
238
  try {
235
239
  const directory = this.options.outputDirectory + '/' + locale + '/LC_MESSAGES';
236
- const outFile = directory + '/' + this.options.defaultDomain + '.' + this.options.outputFormat;
240
+ const outFile = directory +
241
+ '/' +
242
+ this.options.defaultDomain +
243
+ '.' +
244
+ this.options.outputFormat;
237
245
  const inFile = this.options.directory + '/' + locale + '.' + this.options.inputFormat;
238
246
  if (!(0, fs_1.existsSync)(directory)) {
239
247
  mkdirp.sync(directory);
@@ -37,6 +37,7 @@ const fs = __importStar(require("fs"));
37
37
  const childProcess = __importStar(require("child_process"));
38
38
  const runtime_1 = require("@esgettext/runtime");
39
39
  const package_1 = require("../package");
40
+ const optspec_1 = require("../optspec");
40
41
  const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
41
42
  class MsgfmtAll {
42
43
  constructor(configuration) {
@@ -57,8 +58,7 @@ class MsgfmtAll {
57
58
  var _a, _b, _c, _d, _e, _f, _g, _h;
58
59
  const options = {
59
60
  locales: {
60
- alias: 'l',
61
- type: 'array',
61
+ multi: true,
62
62
  describe: gtx._('List of locale identifiers'),
63
63
  demandOption: true,
64
64
  default: (_a = this.configuration.po) === null || _a === void 0 ? void 0 : _a.locales,
@@ -84,8 +84,8 @@ class MsgfmtAll {
84
84
  group: gtx._('Mode of operation:'),
85
85
  },
86
86
  options: {
87
+ multi: true,
87
88
  type: 'string',
88
- array: true,
89
89
  describe: gtx._x("Options to pass to '{program}' program (without hyphens)", { program: 'msgfmt' }),
90
90
  default: ((_h = (_g = this.configuration.programs) === null || _g === void 0 ? void 0 : _g.msgfmt) === null || _h === void 0 ? void 0 : _h.options) || [
91
91
  'check',
@@ -129,8 +129,11 @@ class MsgfmtAll {
129
129
  }
130
130
  }
131
131
  run(argv) {
132
- this.init(argv);
133
132
  return new Promise(resolve => {
133
+ if (!(0, optspec_1.coerceOptions)(argv, this.args())) {
134
+ return resolve(1);
135
+ }
136
+ this.init(argv);
134
137
  const promises = this.locales.map(locale => this.msgfmtLocale(locale));
135
138
  Promise.all(promises)
136
139
  .then(results => {
@@ -38,6 +38,7 @@ const fs = __importStar(require("fs"));
38
38
  const childProcess = __importStar(require("child_process"));
39
39
  const runtime_1 = require("@esgettext/runtime");
40
40
  const package_1 = require("../package");
41
+ const optspec_1 = require("../optspec");
41
42
  const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
42
43
  class MsgmergeAll {
43
44
  constructor(configuration) {
@@ -72,8 +73,8 @@ class MsgmergeAll {
72
73
  var _a, _b, _c, _d, _e, _f, _g, _h;
73
74
  const options = {
74
75
  locales: {
76
+ multi: true,
75
77
  alias: 'l',
76
- type: 'array',
77
78
  describe: gtx._('List of locale identifiers'),
78
79
  demandOption: true,
79
80
  default: (_a = this.configuration.po) === null || _a === void 0 ? void 0 : _a.locales,
@@ -93,10 +94,10 @@ class MsgmergeAll {
93
94
  group: gtx._('Mode of operation:'),
94
95
  },
95
96
  options: {
97
+ multi: true,
96
98
  type: 'string',
97
- array: true,
98
99
  describe: gtx._x("Options to pass to '{program}' program (without hyphens)", { program: 'msgmerge' }),
99
- default: (_h = (_g = this.configuration.programs) === null || _g === void 0 ? void 0 : _g.msgfmt) === null || _h === void 0 ? void 0 : _h.options,
100
+ default: (_h = (_g = this.configuration.programs) === null || _g === void 0 ? void 0 : _g.msgmerge) === null || _h === void 0 ? void 0 : _h.options,
100
101
  group: gtx._('Mode of operation:'),
101
102
  },
102
103
  verbose: {
@@ -140,8 +141,11 @@ class MsgmergeAll {
140
141
  }
141
142
  }
142
143
  run(argv) {
143
- this.init(argv);
144
144
  return new Promise(resolve => {
145
+ if (!(0, optspec_1.coerceOptions)(argv, this.args())) {
146
+ return resolve(1);
147
+ }
148
+ this.init(argv);
145
149
  const promises = this.locales.map(locale => this.msgmergeLocale(locale));
146
150
  Promise.all(promises)
147
151
  .then(results => {
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Potfiles = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const child_process_1 = require("child_process");
7
+ const glob_1 = require("glob");
8
+ const runtime_1 = require("@esgettext/runtime");
9
+ const package_1 = require("../package");
10
+ const optspec_1 = require("../optspec");
11
+ const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
12
+ class Potfiles {
13
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+ constructor(configuration) {
15
+ this.GIT_DIRECTORY_NAME = '.git';
16
+ this.options = undefined;
17
+ this.configuration = configuration;
18
+ }
19
+ synopsis() {
20
+ return `[${gtx._('PATTERN')}...]`;
21
+ }
22
+ description() {
23
+ return gtx._('Write a list of filenames with translatable strings to standard output.');
24
+ }
25
+ aliases() {
26
+ return [];
27
+ }
28
+ args() {
29
+ var _a;
30
+ return {
31
+ exclude: {
32
+ multi: true,
33
+ alias: 'x',
34
+ type: 'string',
35
+ describe: gtx._('Pattern for files to ignore.'),
36
+ },
37
+ git: {
38
+ type: 'boolean',
39
+ describe: gtx._('Only list files under (git) version control.'),
40
+ default: this.isGitRepo(),
41
+ },
42
+ include: {
43
+ multi: true,
44
+ type: 'string',
45
+ describe: gtx._('Pattern for additional files to include (even when not under version control).'),
46
+ },
47
+ directory: {
48
+ type: 'string',
49
+ describe: gtx._('Make paths relative to this directory.'),
50
+ default: (_a = this.configuration.po) === null || _a === void 0 ? void 0 : _a.directory,
51
+ },
52
+ };
53
+ }
54
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
55
+ additional(argv) {
56
+ argv.positional(gtx._('PATTERN'), {
57
+ type: 'string',
58
+ describe: gtx._('Filename patterns for source files'),
59
+ });
60
+ }
61
+ isDirectory(path) {
62
+ const stats = (0, fs_1.lstatSync)(path);
63
+ if (stats.isDirectory()) {
64
+ return true;
65
+ }
66
+ else if (stats.isSymbolicLink()) {
67
+ const realPath = (0, fs_1.realpathSync)(path);
68
+ const realStats = (0, fs_1.statSync)(realPath);
69
+ if (realStats.isDirectory()) {
70
+ return true;
71
+ }
72
+ else {
73
+ return false;
74
+ }
75
+ }
76
+ else {
77
+ return false;
78
+ }
79
+ }
80
+ isGitDirectory(path) {
81
+ const fullPath = (0, path_1.join)(path, this.GIT_DIRECTORY_NAME);
82
+ return (0, fs_1.existsSync)(fullPath) && this.isDirectory(fullPath);
83
+ }
84
+ isGitRepo() {
85
+ if (this.isGitDirectory(process.cwd())) {
86
+ return true;
87
+ }
88
+ let currentPath = process.cwd();
89
+ while (true) {
90
+ const parentPath = (0, path_1.join)(currentPath, '..');
91
+ if (parentPath === currentPath) {
92
+ break;
93
+ }
94
+ if (this.isGitDirectory(parentPath)) {
95
+ return true;
96
+ }
97
+ currentPath = parentPath;
98
+ }
99
+ return false;
100
+ }
101
+ init(argv) {
102
+ const options = argv;
103
+ this.options = options;
104
+ }
105
+ filterGit(allFiles) {
106
+ const stdout = (0, child_process_1.execSync)('git ls-files').toString('utf-8');
107
+ const repoFiles = stdout
108
+ .trim()
109
+ .split('\n')
110
+ .map(filename => (0, path_1.resolve)(filename));
111
+ const filtered = [];
112
+ for (const filename of allFiles) {
113
+ const resolved = (0, path_1.resolve)(filename);
114
+ if (repoFiles.includes(resolved)) {
115
+ filtered.push(filename);
116
+ }
117
+ }
118
+ return filtered;
119
+ }
120
+ makeRelative(filename, base) {
121
+ const absoluteFilename = (0, path_1.resolve)(filename);
122
+ const absoluteBase = (0, path_1.resolve)(base);
123
+ return (0, path_1.relative)(absoluteBase, absoluteFilename);
124
+ }
125
+ run(argv) {
126
+ return new Promise(resolve => {
127
+ if (!(0, optspec_1.coerceOptions)(argv, this.args())) {
128
+ return resolve(1);
129
+ }
130
+ this.init(argv);
131
+ const patterns = this.options[gtx._('PATTERN')];
132
+ if (!patterns.length) {
133
+ console.error(gtx._x('{programName}: Error: No filename patterns specified!', {
134
+ programName: package_1.Package.getName(),
135
+ }));
136
+ return resolve(1);
137
+ }
138
+ const candidates = (0, glob_1.globSync)(patterns, { ignore: this.options.exclude });
139
+ let filtered;
140
+ if (this.options.git) {
141
+ filtered = this.filterGit(candidates);
142
+ }
143
+ else {
144
+ filtered = candidates.filter(filename => !this.isDirectory(filename));
145
+ }
146
+ if (typeof this.options.include !== 'undefined') {
147
+ const included = (0, glob_1.globSync)(this.options.include).filter(filename => !this.isDirectory(filename));
148
+ filtered.push(...included);
149
+ }
150
+ // sort | uniq for JavaScript.
151
+ filtered = filtered.sort().filter((item, index) => {
152
+ return index === 0 || item !== filtered[index - 1];
153
+ });
154
+ if (typeof this.options.directory !== 'undefined' &&
155
+ this.options.directory.length) {
156
+ filtered = filtered.map(filename => this.makeRelative(filename, this.options.directory));
157
+ }
158
+ for (const filename of filtered) {
159
+ console.log(filename);
160
+ }
161
+ resolve(0);
162
+ });
163
+ }
164
+ }
165
+ exports.Potfiles = Potfiles;
@@ -33,6 +33,7 @@ const files_collector_1 = require("./xgettext/files-collector");
33
33
  const typescript_1 = require("../parser/typescript");
34
34
  const javascript_1 = require("../parser/javascript");
35
35
  const keyword_1 = require("../pot/keyword");
36
+ const optspec_1 = require("../optspec");
36
37
  const gtx = runtime_1.Textdomain.getInstance('com.cantanea.esgettext-tools');
37
38
  class XGettext {
38
39
  // The date is only passed for testing.
@@ -59,16 +60,16 @@ class XGettext {
59
60
  : undefined;
60
61
  return {
61
62
  'files-from': {
63
+ multi: true,
62
64
  group: gtx._('Input file location:'),
63
65
  type: 'string',
64
- array: true,
65
66
  describe: gtx._('get list of input files from FILE'),
66
67
  default: (_b = this.configuration.package) === null || _b === void 0 ? void 0 : _b['files-from'],
67
68
  },
68
69
  directory: {
70
+ multi: true,
69
71
  group: gtx._('Input file location:'),
70
72
  type: 'string',
71
- array: true,
72
73
  describe: gtx._('add directory to list for input files search\nIf input file is -, standard input is read.'),
73
74
  },
74
75
  'default-domain': {
@@ -112,18 +113,18 @@ class XGettext {
112
113
  describe: gtx._('join messages with existing file'),
113
114
  },
114
115
  'exclude-file': {
116
+ multi: true,
115
117
  group: gtx._('Operation mode:'),
116
118
  alias: 'x',
117
119
  type: 'string',
118
120
  describe: gtx._('entries from FILE.po are not extracted'),
119
- array: true,
120
121
  },
121
122
  'add-comments': {
123
+ multi: true,
122
124
  group: gtx._('Operation mode:'),
123
125
  alias: 'c',
124
126
  type: 'string',
125
127
  describe: gtx._('place comment blocks starting with TAG and preceding keyword lines in output file'),
126
- array: true,
127
128
  },
128
129
  'add-all-comments': {
129
130
  group: gtx._('Operation mode:'),
@@ -137,22 +138,22 @@ class XGettext {
137
138
  describe: gtx._('extract all strings'),
138
139
  },
139
140
  keyword: {
141
+ multi: true,
140
142
  group: gtx._('Language specific options:'),
141
143
  type: 'string',
142
144
  describe: gtx._('look for WORD as an additional keyword'),
143
- array: true,
144
145
  },
145
146
  flag: {
147
+ multi: true,
146
148
  group: gtx._('Language specific options:'),
147
149
  type: 'string',
148
150
  describe: gtx._('argument: WORD:ARG:FLAG, additional flag for strings inside the argument number ARG of keyword WORD'),
149
- array: true,
150
151
  },
151
152
  instance: {
153
+ multi: true,
152
154
  group: gtx._('Language specific options:'),
153
155
  type: 'string',
154
156
  describe: gtx._('only accept method calls of specified instance names'),
155
- array: true,
156
157
  },
157
158
  'force-po': {
158
159
  group: gtx._('Output details:'),
@@ -238,7 +239,12 @@ class XGettext {
238
239
  };
239
240
  }
240
241
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
241
- additional(_) { }
242
+ additional(argv) {
243
+ argv.positional(gtx._('INPUTFILE'), {
244
+ type: 'string',
245
+ describe: gtx._('input files'),
246
+ });
247
+ }
242
248
  init(argv) {
243
249
  var _a, _b, _c, _d, _e;
244
250
  const options = argv;
@@ -318,7 +324,7 @@ class XGettext {
318
324
  }
319
325
  let fileCollector;
320
326
  try {
321
- fileCollector = new files_collector_1.FilesCollector(this.options.filesFrom, this.options._);
327
+ fileCollector = new files_collector_1.FilesCollector(this.options.filesFrom, this.options[gtx._('INPUTFILE')]);
322
328
  }
323
329
  catch (e) {
324
330
  console.error(`${this.options.$0}: ${e}`);
@@ -355,8 +361,11 @@ class XGettext {
355
361
  return exitCode;
356
362
  }
357
363
  run(argv) {
358
- this.init(argv);
359
364
  return new Promise(resolve => {
365
+ if (!(0, optspec_1.coerceOptions)(argv, this.args())) {
366
+ return resolve(1);
367
+ }
368
+ this.init(argv);
360
369
  try {
361
370
  resolve(this.doRun());
362
371
  }
@@ -412,6 +421,8 @@ class XGettext {
412
421
  break;
413
422
  case '.js':
414
423
  case '.jsx':
424
+ case '.mjs':
425
+ case '.cjs':
415
426
  parser = new javascript_1.JavaScriptParser(this.catalog, parserOptions);
416
427
  break;
417
428
  case '.po':