imdone-core 1.54.10 → 2.0.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.
Files changed (163) hide show
  1. package/.dependency-cruiser.cjs +412 -0
  2. package/.github/workflows/ci.yml +2 -2
  3. package/.imdoneignore +2 -1
  4. package/README.md +2 -2
  5. package/_index.md +7 -0
  6. package/build.js +57 -0
  7. package/esm-migration.md +446 -0
  8. package/lib/FileProjectContext.js +13 -0
  9. package/lib/ProjectContext.js +19 -18
  10. package/lib/adapters/date-time.js +3 -8
  11. package/lib/adapters/environment.js +3 -0
  12. package/lib/adapters/file-gateway.js +133 -106
  13. package/lib/adapters/git-download.js +36 -16
  14. package/lib/adapters/index.js +9 -0
  15. package/lib/adapters/logger.js +136 -0
  16. package/lib/adapters/markdown.js +31 -19
  17. package/lib/adapters/parsers/DateLanguageParser.js +11 -9
  18. package/lib/adapters/parsers/content-transformer.js +35 -30
  19. package/lib/adapters/parsers/file/LocalFileParserFactory.js +8 -9
  20. package/lib/adapters/parsers/file/ReadStreamCodeParser.js +8 -8
  21. package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +4 -4
  22. package/lib/adapters/parsers/file/ReadStreamTaskParser.js +5 -3
  23. package/lib/adapters/parsers/file/index.js +4 -0
  24. package/lib/adapters/parsers/function-parser.js +1 -5
  25. package/lib/adapters/parsers/index.js +5 -0
  26. package/lib/adapters/parsers/task/CardContentParser.js +23 -32
  27. package/lib/adapters/parsers/task/CheckStyleTaskParser.js +2 -2
  28. package/lib/adapters/parsers/task/CodeStyleTaskParser.js +2 -2
  29. package/lib/adapters/parsers/task/HashStyleTaskParser.js +3 -3
  30. package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +2 -2
  31. package/lib/adapters/parsers/task/TaskParser.js +1 -1
  32. package/lib/adapters/parsers/task/index.js +6 -0
  33. package/lib/adapters/storage/config.js +15 -20
  34. package/lib/adapters/storage/index.js +2 -0
  35. package/lib/adapters/storage/tags.js +11 -12
  36. package/lib/adapters/yaml.js +8 -5
  37. package/lib/card.js +25 -26
  38. package/lib/checksum.js +22 -0
  39. package/lib/cli.js +114 -0
  40. package/lib/config.js +106 -71
  41. package/lib/constants.js +21 -50
  42. package/lib/context/ApplicationContext.js +7 -4
  43. package/lib/context/index.js +1 -0
  44. package/lib/default-settings.js +3 -3
  45. package/lib/domain/entities/View.js +4 -11
  46. package/lib/domain/entities/index.js +1 -0
  47. package/lib/domain/index.js +2 -0
  48. package/lib/domain/usecases/GetViewsUsecase.js +6 -12
  49. package/lib/domain/usecases/SaveViewUsecase.js +8 -14
  50. package/lib/domain/usecases/index.js +2 -0
  51. package/lib/file.js +1158 -1162
  52. package/lib/get-tasks-to-modify.js +117 -0
  53. package/lib/index.js +23 -0
  54. package/lib/languages.js +4 -5
  55. package/lib/list.js +46 -95
  56. package/lib/migrate-config.js +5 -5
  57. package/lib/mixins/index.js +2 -0
  58. package/lib/mixins/repo-fs-store.js +224 -289
  59. package/lib/mixins/repo-watched-fs-store.js +158 -147
  60. package/lib/plugins/archive-plugin.js +10 -8
  61. package/lib/plugins/default-board-actions-plugin.js +2 -2
  62. package/lib/plugins/default-board-properties-plugin.js +7 -7
  63. package/lib/plugins/default-plugins.js +7 -0
  64. package/lib/plugins/epic-plugin.js +6 -5
  65. package/lib/plugins/extension-plugin.js +24 -17
  66. package/lib/plugins/index.js +9 -0
  67. package/lib/plugins/persist-tags-plugin.js +4 -3
  68. package/lib/plugins/plugin-manager.js +89 -52
  69. package/lib/plugins/plugin-registry.js +12 -16
  70. package/lib/project-factory.js +21 -24
  71. package/lib/project.js +97 -144
  72. package/lib/repository.js +1323 -1555
  73. package/lib/task.js +562 -580
  74. package/lib/tools.js +39 -113
  75. package/lib/usecases/actions.js +32 -0
  76. package/lib/usecases/get-project-tags.js +3 -12
  77. package/lib/usecases/get-tasks-in-file.js +4 -7
  78. package/lib/usecases/index.js +4 -0
  79. package/package.json +44 -66
  80. package/scripts/delete-markdown-indexes.js +87 -0
  81. package/scripts/generate-index.js +35 -0
  82. package/{index-markdown.js → scripts/index-markdown.js} +7 -7
  83. package/tsconfig.json +15 -0
  84. package/types/FileProjectContext.d.ts +4 -0
  85. package/types/ProjectContext.d.ts +9 -0
  86. package/types/adapters/date-time.d.ts +2 -0
  87. package/types/adapters/environment.d.ts +1 -0
  88. package/types/adapters/file-gateway.d.ts +51 -0
  89. package/types/adapters/git-download.d.ts +1 -0
  90. package/types/adapters/index.d.ts +9 -0
  91. package/types/adapters/logger.d.ts +24 -0
  92. package/types/adapters/markdown.d.ts +13 -0
  93. package/types/adapters/parsers/DateLanguageParser.d.ts +1 -0
  94. package/types/adapters/parsers/content-transformer.d.ts +10 -0
  95. package/types/adapters/parsers/file/LocalFileParserFactory.d.ts +5 -0
  96. package/types/adapters/parsers/file/ReadStreamCodeParser.d.ts +13 -0
  97. package/types/adapters/parsers/file/ReadStreamMarkdownParser.d.ts +7 -0
  98. package/types/adapters/parsers/file/ReadStreamTaskParser.d.ts +19 -0
  99. package/types/adapters/parsers/file/index.d.ts +4 -0
  100. package/types/adapters/parsers/function-parser.d.ts +1 -0
  101. package/types/adapters/parsers/index.d.ts +5 -0
  102. package/types/adapters/parsers/task/CardContentParser.d.ts +45 -0
  103. package/types/adapters/parsers/task/CheckStyleTaskParser.d.ts +12 -0
  104. package/types/adapters/parsers/task/CodeStyleTaskParser.d.ts +14 -0
  105. package/types/adapters/parsers/task/HashStyleTaskParser.d.ts +13 -0
  106. package/types/adapters/parsers/task/MarkdownStyleTaskParser.d.ts +14 -0
  107. package/types/adapters/parsers/task/TaskParser.d.ts +7 -0
  108. package/types/adapters/parsers/task/index.d.ts +6 -0
  109. package/types/adapters/storage/config.d.ts +6 -0
  110. package/types/adapters/storage/index.d.ts +2 -0
  111. package/types/adapters/storage/tags.d.ts +3 -0
  112. package/types/adapters/yaml.d.ts +2 -0
  113. package/types/card.d.ts +166 -0
  114. package/types/checksum.d.ts +8 -0
  115. package/types/config.d.ts +61 -0
  116. package/types/constants.d.ts +46 -0
  117. package/types/context/ApplicationContext.d.ts +24 -0
  118. package/types/context/index.d.ts +1 -0
  119. package/types/default-settings.d.ts +2 -0
  120. package/types/domain/entities/FileProjectContext.d.ts +5 -0
  121. package/types/domain/entities/View.d.ts +17 -0
  122. package/types/domain/entities/index.d.ts +1 -0
  123. package/types/domain/index.d.ts +2 -0
  124. package/types/domain/usecases/GetViewsUsecase.d.ts +4 -0
  125. package/types/domain/usecases/SaveViewUsecase.d.ts +8 -0
  126. package/types/domain/usecases/index.d.ts +2 -0
  127. package/types/file.d.ts +344 -0
  128. package/types/get-tasks-to-modify.d.ts +3 -0
  129. package/types/index.d.ts +23 -0
  130. package/types/languages.d.ts +649 -0
  131. package/types/list.d.ts +30 -0
  132. package/types/migrate-config.d.ts +1 -0
  133. package/types/mixins/index.d.ts +2 -0
  134. package/types/mixins/repo-fs-store.d.ts +2 -0
  135. package/types/mixins/repo-watched-fs-store.d.ts +2 -0
  136. package/types/plugins/archive-plugin.d.ts +8 -0
  137. package/types/plugins/default-board-actions-plugin.d.ts +9 -0
  138. package/types/plugins/default-board-properties-plugin.d.ts +16 -0
  139. package/types/plugins/default-plugins.d.ts +6 -0
  140. package/types/plugins/epic-plugin.d.ts +19 -0
  141. package/types/plugins/extension-plugin.d.ts +15 -0
  142. package/types/plugins/index.d.ts +9 -0
  143. package/types/plugins/persist-tags-plugin.d.ts +4 -0
  144. package/types/plugins/plugin-manager.d.ts +68 -0
  145. package/types/plugins/plugin-registry.d.ts +1 -0
  146. package/types/project-factory.d.ts +14 -0
  147. package/types/project.d.ts +158 -0
  148. package/types/repository.d.ts +996 -0
  149. package/types/task.d.ts +202 -0
  150. package/types/tools.d.ts +29 -0
  151. package/types/usecases/actions.d.ts +7 -0
  152. package/types/usecases/get-imdone-url.d.ts +1 -0
  153. package/types/usecases/get-project-tags.d.ts +1 -0
  154. package/types/usecases/get-tasks-in-file.d.ts +4 -0
  155. package/types/usecases/index.d.ts +4 -0
  156. package/vitest.config.js +13 -0
  157. package/cli.js +0 -74
  158. package/index.js +0 -1
  159. package/lib/adapters/readers/FileSystemProjectReader.js +0 -45
  160. package/lib/context/StreamingApplicationContext.js +0 -31
  161. package/lib/controlers/SaveViewController.js +0 -10
  162. package/lib/domain/entities/FileProjectContext.js +0 -10
  163. package/lib/domain/usecases/OpenProjectUsecase.js +0 -13
@@ -1,53 +1,48 @@
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
1
+ import _path from 'path'
2
+ import _cloneDeep from 'lodash.clonedeep'
3
+ import _isFunction from 'lodash.isfunction'
4
+ import _isUndefined from 'lodash.isundefined'
5
+ import _assign from 'lodash.assign'
6
+ import _remove from 'lodash.remove'
7
+ import _union from 'lodash.union'
8
+ import { eachLimit } from 'async'
9
+ import { computeChecksum } from '../checksum.js'
10
+ import { constants } from '../constants.js'
11
+ import debug from 'debug'
12
+ const log = debug('imdone-mixins:repo-fs-store.js')
13
+ import { File } from '../file.js'
14
+ import { Config } from '../config.js'
15
+ import { languages } from '../languages.js'
16
+ import { isBinaryFile } from 'isbinaryfile'
17
+ import eol from 'eol'
18
+ const _eol = String(eol.auto)
19
+ import readdirp from 'readdirp'
20
+ import _ignore from 'ignore'
21
+ import { sort } from 'fast-sort'
22
+ import { buildMigrateConfig } from '../migrate-config.js'
23
+ import { loadYAML, dumpYAML } from '../adapters/yaml.js';
24
+ import realFs, { readFileSync } from 'fs'
25
+ import { preparePathForWriting, readFile, writeFile, stat, lstat, unlink } from '../adapters/file-gateway.js'
30
26
 
31
27
  const {
32
- CONFIG_DIR,
33
28
  CONFIG_FILE,
34
29
  CONFIG_FILE_YML,
35
- DEFAULT_CONFIG,
36
30
  ASYNC_LIMIT,
37
- DEFAULT_IGNORE_DIRS,
31
+ DEFAULT_IGNORE_PATHS,
38
32
  DEFAULT_IGNORE_EXTS,
39
33
  IGNORE_FILE,
40
34
  SORT_FILE,
41
35
  ERRORS,
42
36
  } = constants
43
37
 
44
- function mixin(repo, fs = require('fs')) {
45
- repo.checksum = checksum
38
+ const { DEFAULT_CONFIG } = Config
39
+
40
+ export function fileSystemStoreMixin(repo, fs = realFs) {
46
41
  repo.allFiles = []
47
42
 
48
43
  function getIgnorePatterns() {
49
44
  var ignoreFile = _path.join(repo.path, IGNORE_FILE)
50
- let patterns = DEFAULT_IGNORE_DIRS
45
+ let patterns = DEFAULT_IGNORE_PATHS
51
46
  if (fs.existsSync(ignoreFile))
52
47
  patterns = patterns + _eol + fs.readFileSync(ignoreFile).toString()
53
48
 
@@ -61,28 +56,13 @@ function mixin(repo, fs = require('fs')) {
61
56
  return !dirent.isSymbolicLink() && !IG.ignores(path)
62
57
  }
63
58
 
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
- })
59
+ repo.getAllFilePaths = async function (root) {
60
+ const entries = []
61
+ for await (const entry of readdirp(root, { lstat: true, fileFilter: shouldIncludeFile })) {
62
+ entries.push(entry)
63
+ }
64
+ return entries.filter((res) => repo.shouldInclude(res.path))
65
+ .map((res) => res.fullPath)
86
66
  }
87
67
 
88
68
  repo.addFilePath = async function (path) {
@@ -104,38 +84,32 @@ function mixin(repo, fs = require('fs')) {
104
84
  return repo.allFiles
105
85
  }
106
86
 
107
- const _init = repo.init
108
87
  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
- }
88
+ // READY Refactor init to use async/await
89
+ // #esm-migration #important #urgent
90
+ // <!--
91
+ // order:-270
92
+ // -->
93
+ repo.init = async function () {
94
+ const stats = await stat(repo.path)
95
+ if (!stats.isDirectory()) {
96
+ var error = new Error(
97
+ `Path must be an existing directory on the file system: ${repo.path}`
98
+ )
99
+ repo.emit('error', error)
100
+ throw error
101
+ }
121
102
 
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
- })
103
+ await repo.loadConfig()
104
+ repo.migrateConfig()
105
+ await repo.saveConfig()
106
+ repo.emit('config.loaded')
107
+ repo.createListeners()
108
+
109
+ const files = await repo.readFiles()
110
+ const lists = repo.getTasksByList()
111
+ repo.emit('fs-store-initialized', { ok: true, lists })
112
+ return files
139
113
  }
140
114
 
141
115
  repo.loadIgnore = function () {
@@ -143,79 +117,62 @@ function mixin(repo, fs = require('fs')) {
143
117
  repo.setIgnores(patterns)
144
118
  }
145
119
 
146
- repo.fileOK = function (file, includeDirs, cb) {
120
+ repo.fileOK = async function (file, includeDirs = false) {
147
121
  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
- }
122
+ if (!file || !this.shouldInclude(file)) return false
123
+
158
124
  var fullPath = repo.getFullPath(file)
159
- fs.lstat(fullPath, function (err, stat) {
160
- if (err) {
161
- console.log(err)
162
- return cb(null, false)
125
+ try {
126
+ const stats = await lstat(fullPath)
127
+
128
+ if (!stats) return false
129
+
130
+ if (/\.\.(\/|\\)/.test(file) || (!includeDirs && stats.isDirectory()))
131
+ return false
132
+
133
+ const content = await readFile(fullPath)
134
+
135
+ if (await isBinaryFile(content, stats.size) ) {
136
+ return false
163
137
  }
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
- })
138
+
139
+ return stats
140
+ } catch (err) {
141
+ return false
142
+ }
175
143
  }
176
144
 
177
- repo.saveSort = function (sort, cb) {
178
- cb = tools.cb(cb)
179
- fs.writeFile(repo.getFullPath(SORT_FILE), JSON.stringify(sort), cb)
145
+ // READY Refactor saveSort to use async/await
146
+ // #esm-migration #important
147
+ // TODO readSort and saveSort are no longer used
148
+ repo.saveSort = async function (sort) {
149
+ writeFile(repo.getFullPath(SORT_FILE), JSON.stringify(sort), 'utf8')
180
150
  }
181
151
 
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
- })
152
+ repo.readSort = async function () {
153
+ const data = readFile(repo.getFullPath(SORT_FILE))
154
+ repo.sort = JSON.parse(data)
188
155
  }
189
156
 
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) {
157
+ repo.saveConfig = async function () {
158
+ try {
159
+ repo.savingConfig = true
160
+ const file = repo.getFullPath(CONFIG_FILE_YML)
200
161
  const data = { ...repo.getConfig() }
201
162
  delete data.cardActionsFunction
202
163
  delete data.boardActionsFunction
203
164
  delete data.cardPropertiesFunction
204
165
  delete data.path
205
166
  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
- })
167
+ const yaml = dumpYAML(data)
168
+ await preparePathForWriting(file)
169
+ await writeFile(file, yaml)
170
+ } finally {
171
+ repo.savingConfig = false
172
+ }
216
173
  }
217
174
 
218
- repo.updateConfig = function (loadedConfig, cb) {
175
+ repo.updateConfig = async function (loadedConfig) {
219
176
  var baseConfig = _cloneDeep(DEFAULT_CONFIG)
220
177
  var include_lists = baseConfig.code.include_lists
221
178
  const currentConfig = repo.config
@@ -232,38 +189,42 @@ function mixin(repo, fs = require('fs')) {
232
189
  _assign({}, baseConfig, repo.config, loadedConfig, { path: repo.path })
233
190
  )
234
191
 
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
- })
192
+ await repo.migrateTasksByConfig(currentConfig, newConfig)
193
+ repo.config = newConfig
194
+ repo.config.code.include_lists = include_lists
195
+ var _languages = _cloneDeep(languages)
196
+ repo.languages = repo.config.languages
197
+ ? _assign(_languages, repo.config.languages)
198
+ : _languages
199
+ return repo.config
245
200
  }
246
201
 
247
- repo.loadConfig = function (cb) {
202
+ // READY Refactor loadConfig to use async/await
203
+ // #esm-migration
204
+ // <!--
205
+ // order:-255
206
+ // -->
207
+ repo.loadConfig = async function (cb) {
248
208
  // 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
209
  // <!--
250
210
  // order:-670
251
211
  // -->
252
- cb = tools.cb(cb)
253
212
  repo.loadIgnore()
254
- // new
255
- const configData = (!repo.config || repo.config.dirty) ? this.getYamlConfig() : repo.config || {}
256
- repo.updateConfig(configData, cb)
213
+ const configData = (!repo.config || repo.config.dirty)
214
+ ? await this.getYamlConfig()
215
+ : repo.config || {}
216
+
217
+ return await repo.updateConfig(configData)
257
218
  }
258
219
 
259
220
  repo.getConfigFile = function () {
260
221
  return repo.getFullPath(CONFIG_FILE)
261
222
  }
262
223
 
263
- repo.getYamlConfig = function () {
224
+ repo.getYamlConfig = async function () {
264
225
  const filePath = repo.getFullPath(CONFIG_FILE_YML)
265
226
  if (!fs.existsSync(filePath)) return
266
- const configData = fs.readFileSync(filePath, 'utf-8')
227
+ const configData = await readFile(filePath, 'utf-8')
267
228
  let configLike = {}
268
229
  try {
269
230
  configLike = loadYAML(configData.toString())
@@ -273,151 +234,125 @@ function mixin(repo, fs = require('fs')) {
273
234
  return configLike
274
235
  }
275
236
 
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)
237
+ // READY Refactor writeFile to use async/await
238
+ // #esm-migration #important
239
+ // <!--
240
+ // order:-280
241
+ // -->
242
+ repo.writeFile = async (file, emitFileUpdate) => {
243
+ if (!File.isFile(file)) throw new Error(ERRORS.NOT_A_FILE)
244
+ if (file.deleted) return file
294
245
 
295
- var filePath = repo.getFullPath(file)
246
+ if (/\.\.(\/|\\)/.test(file.path)) throw new Error('Unable to write file:' + file.path)
296
247
 
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
- }
248
+ const filePath = repo.getFullPath(file)
249
+
250
+ await preparePathForWriting(filePath)
324
251
 
325
- var dirName = _path.dirname(filePath)
326
- if (fs.existsSync(dirName)) {
327
- return write()
328
- }
252
+ const oldChecksum = file.checksum
253
+ file.checksum = computeChecksum(file.getContentForFile())
254
+
255
+ try {
256
+ await writeFile(filePath, file.getContentForFile(), 'utf8')
257
+ } catch (err) {
258
+ file.checksum = oldChecksum
259
+ throw new Error('Unable to write file:' + filePath, {cause: err})
260
+ }
329
261
 
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)
262
+ try {
263
+ const stats = await stat(filePath)
264
+ file.setModifiedTime(stats.mtime)
265
+ file.modified = false
266
+ repo.addFilePath(filePath)
267
+ if (emitFileUpdate) repo.emit('file.saved', file)
268
+ } catch (err) {
269
+ throw new Error('Unable to stat file:' + filePath, {cause: err})
270
+ }
271
+
272
+ return file
335
273
  }
336
274
 
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
275
+ // READY Refactor getFilesInPath to use async/await
276
+ // #esm-migration #important #urgent
277
+ // <!--
278
+ // order:-20
279
+ // -->
280
+ repo.getFilesInPath = async function (includeDirs) {
281
+ const allPaths = await repo.getAllFilePaths(repo.path)
282
+ const files = []
283
+ let processed = 0
284
+ log('allPaths=', allPaths)
285
+ if (allPaths.length === 0) return files
286
+ await eachLimit(
287
+ allPaths,
288
+ ASYNC_LIMIT,
289
+ async (path) => {
290
+ if (!path) return
291
+ path = repo.getRelativePath(path)
292
+ const stat = await repo.fileOK(path, includeDirs)
293
+ processed++
294
+ repo.emit('file.processed', {
295
+ file: path,
296
+ ok: stat !== false,
297
+ total: allPaths.length,
298
+ processed: processed + 1,
299
+ repoId: repo.getId(),
300
+ })
301
+
302
+ if (stat) {
303
+ log('%s is ok %j', path, stat)
304
+ var file = new File({
305
+ repoId: repo.getId(),
306
+ filePath: path,
307
+ modifiedTime: stat.mtime,
308
+ createdTime: stat.birthtime,
309
+ languages: repo.languages,
310
+ project: repo.project,
380
311
  })
381
- },
382
- function (err) {
383
- cb(err, fastSort(files).asc(u => u.path))
312
+ file.isDir = stat.isDirectory()
313
+ files.push(file)
384
314
  }
385
- )
386
- })
315
+ log('stat=%j', stat, null)
316
+ log('processed=%d allPaths.length=%d', processed, allPaths.length)
317
+ })
318
+ return sort(files).asc(u => u.path)
387
319
  }
388
320
 
389
- repo.readFileContent = function (file, cb) {
390
- cb = tools.cb(cb)
391
- if (!File.isFile(file)) return cb(new Error(ERRORS.NOT_A_FILE))
321
+ // READY Refactor readFileContent to use async/await
322
+ // #esm-migration #important #urgent
323
+ // <!--
324
+ // order:-40
325
+ // -->
326
+ repo.readFileContent = async function (file) {
327
+ if (!File.isFile(file)) throw new Error(ERRORS.NOT_A_FILE)
392
328
  var filePath = repo.getFullPath(file)
393
329
 
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])
330
+ const stats = await stat(filePath)
331
+ if (!stats.isFile()) return file
332
+ const data = await readFile(filePath, 'utf8')
399
333
 
400
- file
401
- .setContentFromFile(data)
402
- .setModifiedTime(stats.mtime)
403
- .setCreatedTime(stats.birthtime)
334
+ file
335
+ .setContentFromFile(data)
336
+ .setModifiedTime(stats.mtime)
337
+ .setCreatedTime(stats.birthtime)
404
338
 
405
- file.lineCount = eol.split(data).length
406
- cb(null, file)
407
- })
408
- })
339
+ file.lineCount = eol.split(data).length
340
+ return file
409
341
  }
410
342
 
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)
343
+ // READY Refactor deleteFile to use async/await
344
+ // #esm-migration #important
345
+ repo.deleteFile = async function (path) {
346
+ const file = File.isFile(path) ? path : repo.getFile(path)
347
+ if (!file) throw new Error('Unable to delete:' + path)
348
+
349
+ try {
350
+ await unlink(repo.getFullPath(file))
351
+ repo.removeFile(file)
352
+ } catch (err) {
353
+ throw new Error('Unable to delete file:' + path, {cause: err})
354
+ }
355
+
421
356
  }
422
357
 
423
358
  return repo