imdone-core 1.54.9 → 2.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.
Files changed (71) hide show
  1. package/README.md +2 -2
  2. package/lib/cli.js +114 -0
  3. package/lib/index.js +23 -0
  4. package/package.json +48 -66
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -37
  6. package/.github/workflows/ci.yml +0 -24
  7. package/.imdoneignore +0 -12
  8. package/.mocharc.json +0 -10
  9. package/.prettierrc +0 -6
  10. package/CHANGELOG.md +0 -160
  11. package/_navbar.md +0 -1
  12. package/cli.js +0 -74
  13. package/index-markdown.js +0 -55
  14. package/index.html +0 -184
  15. package/index.js +0 -1
  16. package/lib/ProjectContext.js +0 -42
  17. package/lib/adapters/date-time.js +0 -20
  18. package/lib/adapters/file-gateway.js +0 -127
  19. package/lib/adapters/git-download.js +0 -35
  20. package/lib/adapters/markdown.js +0 -168
  21. package/lib/adapters/parsers/DateLanguageParser.js +0 -10
  22. package/lib/adapters/parsers/content-transformer.js +0 -111
  23. package/lib/adapters/parsers/file/LocalFileParserFactory.js +0 -37
  24. package/lib/adapters/parsers/file/ReadStreamCodeParser.js +0 -126
  25. package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +0 -17
  26. package/lib/adapters/parsers/file/ReadStreamTaskParser.js +0 -104
  27. package/lib/adapters/parsers/function-parser.js +0 -29
  28. package/lib/adapters/parsers/task/CardContentParser.js +0 -376
  29. package/lib/adapters/parsers/task/CheckStyleTaskParser.js +0 -28
  30. package/lib/adapters/parsers/task/CodeStyleTaskParser.js +0 -24
  31. package/lib/adapters/parsers/task/HashStyleTaskParser.js +0 -27
  32. package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +0 -24
  33. package/lib/adapters/parsers/task/TaskParser.js +0 -38
  34. package/lib/adapters/readers/FileSystemProjectReader.js +0 -45
  35. package/lib/adapters/storage/config.js +0 -49
  36. package/lib/adapters/storage/tags.js +0 -30
  37. package/lib/adapters/yaml.js +0 -6
  38. package/lib/card.js +0 -300
  39. package/lib/config.js +0 -214
  40. package/lib/constants.js +0 -97
  41. package/lib/context/ApplicationContext.js +0 -32
  42. package/lib/context/StreamingApplicationContext.js +0 -31
  43. package/lib/controlers/SaveViewController.js +0 -10
  44. package/lib/default-settings.js +0 -37
  45. package/lib/domain/entities/FileProjectContext.js +0 -10
  46. package/lib/domain/entities/View.js +0 -30
  47. package/lib/domain/usecases/GetViewsUsecase.js +0 -50
  48. package/lib/domain/usecases/OpenProjectUsecase.js +0 -13
  49. package/lib/domain/usecases/SaveViewUsecase.js +0 -57
  50. package/lib/file.js +0 -1395
  51. package/lib/languages.js +0 -114
  52. package/lib/list.js +0 -105
  53. package/lib/migrate-config.js +0 -165
  54. package/lib/mixins/repo-fs-store.js +0 -424
  55. package/lib/mixins/repo-watched-fs-store.js +0 -195
  56. package/lib/plugins/archive-plugin.js +0 -70
  57. package/lib/plugins/default-board-actions-plugin.js +0 -56
  58. package/lib/plugins/default-board-properties-plugin.js +0 -101
  59. package/lib/plugins/epic-plugin.js +0 -176
  60. package/lib/plugins/extension-plugin.js +0 -87
  61. package/lib/plugins/persist-tags-plugin.js +0 -13
  62. package/lib/plugins/plugin-manager.js +0 -421
  63. package/lib/plugins/plugin-registry.js +0 -61
  64. package/lib/project-factory.js +0 -45
  65. package/lib/project.js +0 -911
  66. package/lib/repository.js +0 -1746
  67. package/lib/task.js +0 -798
  68. package/lib/tools.js +0 -250
  69. package/lib/usecases/get-imdone-url.js +0 -6
  70. package/lib/usecases/get-project-tags.js +0 -16
  71. package/lib/usecases/get-tasks-in-file.js +0 -29
@@ -1,424 +0,0 @@
1
- 'use strict'
2
-
3
- var _path = require('path'),
4
- _cloneDeep = require('lodash.clonedeep'),
5
- _isFunction = require('lodash.isfunction'),
6
- _isUndefined = require('lodash.isundefined'),
7
- _assign = require('lodash.assign'),
8
- _remove = require('lodash.remove'),
9
- _union = require('lodash.union'),
10
- async = require('async'),
11
- checksum = require('checksum'),
12
- tools = require('../tools'),
13
- constants = require('../constants'),
14
- log = require('debug')('imdone-mixins:repo-fs-store'),
15
- File = require('../file'),
16
- Config = require('../config'),
17
- languages = require('../languages'),
18
- isBinaryFile = require('isbinaryfile'),
19
- eol = require('eol'),
20
- _eol = String(eol.auto),
21
- readdirp = require('readdirp'),
22
- _ignore = require('ignore'),
23
- fastSort = require('fast-sort/dist/sort.js'),
24
- Repository = require('../repository'),
25
- buildMigrateConfig = require('../migrate-config'),
26
- { loadYAML, dumpYAML } = require('../adapters/yaml')
27
-
28
-
29
- module.exports = mixin
30
-
31
- const {
32
- CONFIG_DIR,
33
- CONFIG_FILE,
34
- CONFIG_FILE_YML,
35
- DEFAULT_CONFIG,
36
- ASYNC_LIMIT,
37
- DEFAULT_IGNORE_DIRS,
38
- DEFAULT_IGNORE_EXTS,
39
- IGNORE_FILE,
40
- SORT_FILE,
41
- ERRORS,
42
- } = constants
43
-
44
- function mixin(repo, fs = require('fs')) {
45
- repo.checksum = checksum
46
- repo.allFiles = []
47
-
48
- function getIgnorePatterns() {
49
- var ignoreFile = _path.join(repo.path, IGNORE_FILE)
50
- let patterns = DEFAULT_IGNORE_DIRS
51
- if (fs.existsSync(ignoreFile))
52
- patterns = patterns + _eol + fs.readFileSync(ignoreFile).toString()
53
-
54
- return patterns
55
- }
56
-
57
- const IG = _ignore().add(getIgnorePatterns())
58
-
59
- function shouldIncludeFile(entry) {
60
- const { path, dirent } = entry
61
- return !dirent.isSymbolicLink() && !IG.ignores(path)
62
- }
63
-
64
- function getAllFilePaths(root, cb) {
65
- readdirp
66
- .promise(root, {
67
- lstat: true,
68
- fileFilter: shouldIncludeFile,
69
- })
70
- .then((entries) => cb(null, entries))
71
- .catch((error) => cb(error, []))
72
- }
73
-
74
- function ls(root, cb) {
75
- getAllFilePaths(root, function (error, files) {
76
- if (error) {
77
- console.error(`Error reading dir: ${root} `, error)
78
- }
79
- cb(
80
- null,
81
- files
82
- .filter((res) => repo.shouldInclude(res.path))
83
- .map((res) => res.fullPath)
84
- )
85
- })
86
- }
87
-
88
- repo.addFilePath = async function (path) {
89
- var relPath = repo.getRelativePath(path)
90
- var fullPath = repo.getFullPath(path)
91
-
92
- const stat = await fs.promises.lstat(fullPath)
93
- if (stat.isDirectory()) relPath += _path.sep
94
- if (!repo.allFiles.includes(relPath)) {
95
- repo.allFiles.push(relPath)
96
- }
97
- }
98
-
99
- repo.removeFilePath = function (path) {
100
- _remove(repo.allFiles, (item) => item === path)
101
- }
102
-
103
- repo.getFilePaths = function () {
104
- return repo.allFiles
105
- }
106
-
107
- const _init = repo.init
108
- repo.migrateConfig = buildMigrateConfig(repo)
109
- repo.init = function (cb) {
110
- _init.call(repo, (err) => {
111
- if (err && repo.destroyed) return cb(err)
112
- cb = tools.cb(cb)
113
- fs.stat(repo.path, function (err, stat) {
114
- if (err || !stat.isDirectory()) {
115
- var error = new Error(
116
- `Path must be an existing directory on the file system: ${repo.path}`
117
- )
118
- repo.emit('error', error)
119
- return cb(error)
120
- }
121
-
122
- repo.loadConfig((err) => {
123
- if (err) {
124
- repo.emit('error', err)
125
- return cb(err)
126
- }
127
- repo.migrateConfig()
128
- repo.saveConfig()
129
- repo.emit('config.loaded')
130
- repo.createListeners()
131
- repo.readFiles((err, files) => {
132
- if (err && repo.destroyed) return cb(err)
133
- repo.emit('initialized', { ok: true, lists: repo.getTasksByList() })
134
- cb(err, files)
135
- })
136
- })
137
- })
138
- })
139
- }
140
-
141
- repo.loadIgnore = function () {
142
- const patterns = getIgnorePatterns() + _eol + DEFAULT_IGNORE_EXTS
143
- repo.setIgnores(patterns)
144
- }
145
-
146
- repo.fileOK = function (file, includeDirs, cb) {
147
- if (File.isFile(file)) file = file.path
148
- if (_isFunction(includeDirs)) {
149
- cb = includeDirs
150
- includeDirs = false
151
- }
152
- cb = tools.cb(cb)
153
- try {
154
- if (!file || !this.shouldInclude(file)) return cb(null, false)
155
- } catch (e) {
156
- cb(e)
157
- }
158
- var fullPath = repo.getFullPath(file)
159
- fs.lstat(fullPath, function (err, stat) {
160
- if (err) {
161
- console.log(err)
162
- return cb(null, false)
163
- }
164
- if (/\.\.(\/|\\)/.test(file) || (!includeDirs && stat.isDirectory()))
165
- return cb(null, false)
166
- if (stat.isFile()) {
167
- isBinaryFile(fullPath, function (err, result) {
168
- if (err || result) return cb(null, false)
169
- cb(null, stat)
170
- })
171
- } else if (includeDirs && stat.isDirectory()) {
172
- cb(null, stat)
173
- } else cb(null, false)
174
- })
175
- }
176
-
177
- repo.saveSort = function (sort, cb) {
178
- cb = tools.cb(cb)
179
- fs.writeFile(repo.getFullPath(SORT_FILE), JSON.stringify(sort), cb)
180
- }
181
-
182
- repo.readSort = function (cb) {
183
- fs.readFile(repo.getFullPath(SORT_FILE), (err, data) => {
184
- if (err) return cb(err)
185
- repo.sort = JSON.parse(data)
186
- cb(null, repo.sort)
187
- })
188
- }
189
-
190
- repo.saveConfig = function (cb) {
191
- repo.savingConfig = true
192
- cb = tools.cb(cb)
193
- var _cb = function (err, resp) {
194
- repo.savingConfig = false
195
- cb(err, resp)
196
- }
197
- var dir = repo.getFullPath(CONFIG_DIR)
198
- var file = repo.getFullPath(CONFIG_FILE_YML)
199
- fs.exists(dir, function (exists) {
200
- const data = { ...repo.getConfig() }
201
- delete data.cardActionsFunction
202
- delete data.boardActionsFunction
203
- delete data.cardPropertiesFunction
204
- delete data.path
205
- if (data.lists) data.lists.forEach((list) => delete list.tasks)
206
- var yaml = dumpYAML(data)
207
- if (exists) {
208
- fs.writeFile(file, yaml, _cb)
209
- } else {
210
- fs.mkdir(dir, function (err) {
211
- if (err) return _cb(err)
212
- fs.writeFile(file, yaml, _cb)
213
- })
214
- }
215
- })
216
- }
217
-
218
- repo.updateConfig = function (loadedConfig, cb) {
219
- var baseConfig = _cloneDeep(DEFAULT_CONFIG)
220
- var include_lists = baseConfig.code.include_lists
221
- const currentConfig = repo.config
222
- if (currentConfig && currentConfig.code)
223
- include_lists = _union(include_lists, currentConfig.code.include_lists)
224
-
225
- if (currentConfig && currentConfig.settings)
226
- loadedConfig.settings = {...currentConfig.settings, ...loadedConfig.settings}
227
-
228
- if (loadedConfig && loadedConfig.code)
229
- include_lists = _union(include_lists, loadedConfig.code.include_lists)
230
-
231
- const newConfig = new Config(
232
- _assign({}, baseConfig, repo.config, loadedConfig, { path: repo.path })
233
- )
234
-
235
- repo.migrateTasksByConfig(currentConfig, newConfig, (err) => {
236
- if (err) return cb(err)
237
- repo.config = newConfig
238
- repo.config.code.include_lists = include_lists
239
- var _languages = _cloneDeep(languages)
240
- repo.languages = repo.config.languages
241
- ? _assign(_languages, repo.config.languages)
242
- : _languages
243
- cb(null, repo.config)
244
- })
245
- }
246
-
247
- repo.loadConfig = function (cb) {
248
- // BACKLOG If a config is bad move it to config.json.bak and save a new one with defaults gh:2 id:9 +enhancement +standup +chore
249
- // <!--
250
- // order:-670
251
- // -->
252
- cb = tools.cb(cb)
253
- repo.loadIgnore()
254
- // new
255
- const configData = (!repo.config || repo.config.dirty) ? this.getYamlConfig() : repo.config || {}
256
- repo.updateConfig(configData, cb)
257
- }
258
-
259
- repo.getConfigFile = function () {
260
- return repo.getFullPath(CONFIG_FILE)
261
- }
262
-
263
- repo.getYamlConfig = function () {
264
- const filePath = repo.getFullPath(CONFIG_FILE_YML)
265
- if (!fs.existsSync(filePath)) return
266
- const configData = fs.readFileSync(filePath, 'utf-8')
267
- let configLike = {}
268
- try {
269
- configLike = loadYAML(configData.toString())
270
- } catch (e) {
271
- /* noop */
272
- }
273
- return configLike
274
- }
275
-
276
- var _deleteTasks = repo.deleteTasks
277
- repo.deleteTasks = function (tasks, cb) {
278
- _deleteTasks.call(repo, tasks, function (err) {
279
- if (err) return cb(err)
280
- repo.emit('tasks.updated', tasks)
281
- cb()
282
- })
283
- }
284
-
285
- repo.writeFile = function (file, emitFileUpdate, cb) {
286
- if (_isFunction(emitFileUpdate)) {
287
- cb = emitFileUpdate
288
- emitFileUpdate = false
289
- }
290
- cb = tools.cb(cb)
291
-
292
- if (!File.isFile(file)) return cb(new Error(ERRORS.NOT_A_FILE))
293
- if (file.deleted) return cb(null, file)
294
-
295
- var filePath = repo.getFullPath(file)
296
-
297
- if (!/\.\.(\/|\\)/.test(file.path)) {
298
- var write = function () {
299
- var oldChecksum = file.checksum
300
- file.checksum = checksum(file.getContentForFile())
301
- fs.writeFile(
302
- filePath,
303
- file.getContentForFile(),
304
- 'utf8',
305
- function (err) {
306
- if (err) {
307
- file.checksum = oldChecksum
308
- return cb([new Error('Unable to write file:' + filePath), err])
309
- }
310
-
311
- fs.stat(filePath, function (err, stats) {
312
- if (err)
313
- return cb([new Error('Unable to stat file:' + filePath), err])
314
-
315
- file.setModifiedTime(stats.mtime)
316
- file.modified = false
317
- repo.addFilePath(filePath)
318
- if (emitFileUpdate) repo.emit('file.saved', file)
319
- cb(null, file)
320
- })
321
- }
322
- )
323
- }
324
-
325
- var dirName = _path.dirname(filePath)
326
- if (fs.existsSync(dirName)) {
327
- return write()
328
- }
329
-
330
- tools.mkdirp(fs, dirName, function (err) {
331
- if (err) return cb(err)
332
- write()
333
- })
334
- } else return cb(new Error('Unable to write file:' + file.path), file)
335
- }
336
-
337
- repo.getFilesInPath = function (includeDirs, cb) {
338
- cb = tools.cb(cb)
339
- ls(repo.path, function (err, allPaths) {
340
- if (err) return cb(err)
341
- var files = [],
342
- processed = 0
343
- log('allPaths=', allPaths)
344
- if (allPaths.length === 0) return cb(null, [])
345
- async.eachLimit(
346
- allPaths,
347
- ASYNC_LIMIT,
348
- function (path, _cb) {
349
- if (!path) return _cb()
350
- path = repo.getRelativePath(path)
351
- repo.fileOK(path, includeDirs, function (err, stat) {
352
- // stack-3 repo-fs-store.js:250:14
353
- processed++
354
- if (err) return _cb(err)
355
- repo.emit('file.processed', {
356
- file: path,
357
- ok: stat !== false,
358
- total: allPaths.length,
359
- processed: processed + 1,
360
- repoId: repo.getId(),
361
- })
362
-
363
- if (stat) {
364
- log('%s is ok %j', path, stat)
365
- var file = new File({
366
- repoId: repo.getId(),
367
- filePath: path,
368
- modifiedTime: stat.mtime,
369
- createdTime: stat.birthtime,
370
- languages: repo.languages,
371
- project: repo.project,
372
- })
373
- file.isDir = stat.isDirectory()
374
- files.push(file)
375
- }
376
- log('err=%j', err, null)
377
- log('stat=%j', stat, null)
378
- log('processed=%d allPaths.length=%d', processed, allPaths.length)
379
- _cb() // stack-1 repo-fs-store.js:270:11
380
- })
381
- },
382
- function (err) {
383
- cb(err, fastSort(files).asc(u => u.path))
384
- }
385
- )
386
- })
387
- }
388
-
389
- repo.readFileContent = function (file, cb) {
390
- cb = tools.cb(cb)
391
- if (!File.isFile(file)) return cb(new Error(ERRORS.NOT_A_FILE))
392
- var filePath = repo.getFullPath(file)
393
-
394
- fs.lstat(filePath, function (err, stats) {
395
- if (err) return cb([new Error('Unable to stat file:' + filePath), err])
396
- if (!stats.isFile()) return cb(null, file)
397
- fs.readFile(filePath, 'utf8', function (err, data) {
398
- if (err) return cb([new Error('Unable to read file:' + filePath), err])
399
-
400
- file
401
- .setContentFromFile(data)
402
- .setModifiedTime(stats.mtime)
403
- .setCreatedTime(stats.birthtime)
404
-
405
- file.lineCount = eol.split(data).length
406
- cb(null, file)
407
- })
408
- })
409
- }
410
-
411
- repo.deleteFile = function (path, cb) {
412
- cb = tools.cb(cb)
413
- var file = File.isFile(path) ? path : repo.getFile(path)
414
- if (!_isUndefined(file)) {
415
- fs.unlink(repo.getFullPath(file), function (err) {
416
- if (err) return cb('Unable to delete:' + path + ' : ' + err.toString())
417
- repo.removeFile(file)
418
- cb(null, file)
419
- })
420
- } else cb('Unable to delete:' + path)
421
- }
422
-
423
- return repo
424
- }
@@ -1,195 +0,0 @@
1
- 'use strict'
2
-
3
- var fsStore = require('./repo-fs-store'),
4
- log = require('debug')('imdone-mixins:repo-watched-fs-store'),
5
- File = require('../file'),
6
- constants = require('../constants'),
7
- sane = require('sane')
8
-
9
- module.exports = mixin
10
-
11
- // BACKLOG Only emit file.update if the file checksum has changed
12
- // <!--
13
- // order:-650
14
- // -->
15
- function mixin(repo, fs = require('fs')) {
16
- repo = fsStore(repo, fs)
17
- var _refresh = repo.refresh
18
- var _destroy = repo.destroy
19
- var _init = repo.init
20
- var initializing = false
21
-
22
- repo.init = function (cb) {
23
- if (initializing) {
24
- const err = new Error("Can't initialize repo while it's initializing.")
25
- console.error(err.message)
26
- return cb ? cb(err) : null
27
- }
28
- log('Initializing repo:', repo.path)
29
- initializing = true
30
- _init.call(repo, function (err, files) {
31
- if (err) {
32
- console.error(`Error initializing repo: ${err.message}`)
33
- initializing = false
34
- return cb ? cb(err) : null
35
- }
36
- repo.initWatcher(() => {
37
- initializing = false
38
- if (cb) cb(err, files)
39
- })
40
- })
41
- }
42
-
43
- repo.destroy = function () {
44
- if (repo.watcher) repo.watcher.close()
45
- _destroy.apply(repo)
46
- }
47
-
48
- repo.refresh = function (cb) {
49
- if (initializing) {
50
- return cb ? cb('already initializing') : null
51
- }
52
- console.info('Initializing repo:', repo.path)
53
- initializing = true
54
- if (repo.watcher) repo.watcher.close()
55
- _refresh.call(repo, function (err, files) {
56
- if (err) {
57
- initializing = false
58
- return cb ? cb(err) : null
59
- }
60
- repo.initWatcher(() => {
61
- initializing = false
62
- return cb ? cb(err, files) : null
63
- })
64
- })
65
- }
66
-
67
- var _isImdoneConfig = function (path) {
68
- return path === constants.CONFIG_FILE_YML
69
- }
70
-
71
- var _isImdoneIgnore = function (path) {
72
- return path === constants.IGNORE_FILE
73
- }
74
-
75
- const onConfigChange = function (file) {
76
- console.info('Loading config. Observed a change to:', file)
77
- const label = `Refresh repo: ${repo.path}`
78
- console.time(label)
79
- repo.refresh((err, files) => {
80
- if (err) console.error('Error refreshing repo', err)
81
- console.timeEnd(label)
82
- repo.emitConfigUpdate(file, repo.config)
83
- })
84
- }
85
-
86
- const onIgnoreChange = onConfigChange
87
-
88
- repo.initWatcher = function (cb) {
89
- console.log('initializing watcher for:', repo.path)
90
- repo.watcher = sane(repo.path, {
91
- dot: true,
92
- ignored(file) {
93
- if (!initializing && _isImdoneConfig(file)) {
94
- onConfigChange(file)
95
- }
96
-
97
- if (!initializing && _isImdoneIgnore(file)) {
98
- onIgnoreChange(file)
99
- }
100
-
101
- const ignore = !repo.shouldInclude(file)
102
- if (!ignore || /^.*\.(jpg|gif|pdf|png)$/i.test(file)) {
103
- repo.addFilePath(file)
104
- }
105
- return ignore
106
- },
107
- })
108
-
109
- repo.watcher
110
- .on('error', (err) => {
111
- console.error('Error in watcher')
112
- console.error(err)
113
- cb(err)
114
- })
115
- .on('ready', () => {
116
- console.log('watcher ready for:', repo.path)
117
- initializing = false
118
- cb()
119
- })
120
- .on('add', function (path, root, stat) {
121
- console.log('Watcher received add event for file: ' + path)
122
- if (stat.isDirectory()) return
123
- var file = repo.getFile(path)
124
- if (file === undefined) {
125
- log('Creating file: ' + path)
126
- file = new File({
127
- repoId: repo.getId(),
128
- filePath: path,
129
- languages: repo.languages,
130
- project: repo.project,
131
- })
132
- }
133
-
134
- repo.fileOK(file, function (err, stat) {
135
- log('fileOK returned: ' + JSON.stringify(stat))
136
- if (err || !stat) return
137
- if (stat.mtime <= file.getModifiedTime()) {
138
- return log('File update already applied. Change ignored for file: ' + path)
139
- }
140
- log('Reading file: ' + path)
141
- repo.readFile(file, function (err, file) {
142
- repo.emitFileUpdate(file)
143
- })
144
- })
145
- })
146
- .on('change', function (path, root, stat) {
147
- console.log(
148
- `Watcher received change event for file: ${path} repoPath: ${repo.path}`,
149
- stat.mtime
150
- )
151
- if (!path || stat.isDirectory()) return
152
- var file = repo.getFile(path) || path
153
- const isFile = File.isFile(file)
154
- // BACKLOG ## Handle the case where the file is not in the repo
155
- // #urgent #1.12.0
156
- // <!--
157
- // order:-660
158
- // -->
159
- if (isFile && stat.mtime <= file.getModifiedTime()) {
160
- // console.log("File update already applied. Change ignored.")
161
- return
162
- }
163
- if (_isImdoneConfig(path)) return onConfigChange(path)
164
- if (_isImdoneIgnore(path)) return onIgnoreChange(path)
165
-
166
- repo.fileOK((file && file.path) || path, function (err, ok) {
167
- if (err) {
168
- console.error('Error processing ignore on path: ', path, err)
169
- return
170
- }
171
- if (!ok) return
172
- log('Reading file: ' + path)
173
- if (!isFile) file = repo.getFile(path)
174
- repo.readFile(file, function (err, file) {
175
- repo.emitFileUpdate(file)
176
- })
177
- })
178
- })
179
- .on('delete', function (path) {
180
- log('Watcher received unlink event for file: ' + path)
181
- repo.removeFilePath(path)
182
- var file = new File({
183
- repoId: repo.getId(),
184
- filePath: path,
185
- languages: repo.languages,
186
- project: repo.project,
187
- })
188
- log('Removing file: ' + path)
189
- repo.removeFile(file)
190
- repo.emitFileUpdate(file, true)
191
- })
192
- }
193
-
194
- return repo
195
- }
@@ -1,70 +0,0 @@
1
- const Plugin = require('imdone-api')
2
- const path = require('path')
3
- const { getRawTask } = require('../adapters/parsers/task/CardContentParser')
4
-
5
- module.exports = class ArchivePlugin extends Plugin {
6
- constructor(project) {
7
- super(project)
8
- }
9
-
10
- get config() {
11
- return this.project.config
12
- }
13
-
14
- get fileGateway() {
15
- return this.project.fileGateway
16
- }
17
-
18
- async onBeforeBoardUpdate() {
19
- const config = this.config
20
- if (!config || !config.archiveCompleted || this.archivingTasks) return
21
- this.archivingTasks = true
22
- const cards = this.project.getAllCards(`meta.archived != "true" and list = ${config.doneList}`)
23
- const messageUser = cards.length > 1
24
-
25
- if (!cards.length) {
26
- this.archivingTasks = false
27
- return
28
- } else {
29
- if (messageUser) this.project.snackBar({message: `Archiving ${cards.length} card(s)...`})
30
- }
31
-
32
- cards.forEach(card => this.archiveTask(card))
33
-
34
- if (messageUser) this.project.snackBar({message: ` Done archiving ${cards.length} card(s). Deleting original(s)...`})
35
- await this.project.deleteTasks(cards)
36
-
37
- this.archivingTasks = false
38
- if (messageUser) this.project.snackBar({message: `Done deleting original card(s).`})
39
-
40
- }
41
-
42
- archiveTask (task, config = this.config) {
43
- const archiveFolder = config.archiveFolder
44
- const fileDir = path.dirname(task.relPath)
45
-
46
- if (fileDir.startsWith(archiveFolder)) return
47
-
48
- const fileName = this.fileGateway.sanitizeFileName(`${task.text}.md`, config.replaceSpacesWith)
49
- const newPath = path.join(this.project.path, archiveFolder, fileDir, fileName)
50
-
51
- const content = this.project.addMetaToContent(
52
- [
53
- { key: 'archived', value: 'true'},
54
- { key: 'archivedAt', value: this.project.isoDateWithOffset },
55
- { key: 'originalPath', value: task.relPath },
56
- { key: 'originalLine', value: task.line }
57
- ],
58
- task.content
59
- )
60
-
61
- const { tokenPrefix } = config
62
- const { beforeText, list } = task
63
- const taskStart = getRawTask({tokenPrefix, beforeText, list, text: ''})
64
- const taskContent = `${taskStart} ${content}\n\n\n`
65
-
66
- this.fileGateway.preparePathForWriting(newPath)
67
- this.fileGateway.appendFileSync(newPath, taskContent)
68
- }
69
-
70
- }