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.
- package/README.md +2 -2
- package/lib/cli.js +114 -0
- package/lib/index.js +23 -0
- package/package.json +48 -66
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -37
- package/.github/workflows/ci.yml +0 -24
- package/.imdoneignore +0 -12
- package/.mocharc.json +0 -10
- package/.prettierrc +0 -6
- package/CHANGELOG.md +0 -160
- package/_navbar.md +0 -1
- package/cli.js +0 -74
- package/index-markdown.js +0 -55
- package/index.html +0 -184
- package/index.js +0 -1
- package/lib/ProjectContext.js +0 -42
- package/lib/adapters/date-time.js +0 -20
- package/lib/adapters/file-gateway.js +0 -127
- package/lib/adapters/git-download.js +0 -35
- package/lib/adapters/markdown.js +0 -168
- package/lib/adapters/parsers/DateLanguageParser.js +0 -10
- package/lib/adapters/parsers/content-transformer.js +0 -111
- package/lib/adapters/parsers/file/LocalFileParserFactory.js +0 -37
- package/lib/adapters/parsers/file/ReadStreamCodeParser.js +0 -126
- package/lib/adapters/parsers/file/ReadStreamMarkdownParser.js +0 -17
- package/lib/adapters/parsers/file/ReadStreamTaskParser.js +0 -104
- package/lib/adapters/parsers/function-parser.js +0 -29
- package/lib/adapters/parsers/task/CardContentParser.js +0 -376
- package/lib/adapters/parsers/task/CheckStyleTaskParser.js +0 -28
- package/lib/adapters/parsers/task/CodeStyleTaskParser.js +0 -24
- package/lib/adapters/parsers/task/HashStyleTaskParser.js +0 -27
- package/lib/adapters/parsers/task/MarkdownStyleTaskParser.js +0 -24
- package/lib/adapters/parsers/task/TaskParser.js +0 -38
- package/lib/adapters/readers/FileSystemProjectReader.js +0 -45
- package/lib/adapters/storage/config.js +0 -49
- package/lib/adapters/storage/tags.js +0 -30
- package/lib/adapters/yaml.js +0 -6
- package/lib/card.js +0 -300
- package/lib/config.js +0 -214
- package/lib/constants.js +0 -97
- package/lib/context/ApplicationContext.js +0 -32
- package/lib/context/StreamingApplicationContext.js +0 -31
- package/lib/controlers/SaveViewController.js +0 -10
- package/lib/default-settings.js +0 -37
- package/lib/domain/entities/FileProjectContext.js +0 -10
- package/lib/domain/entities/View.js +0 -30
- package/lib/domain/usecases/GetViewsUsecase.js +0 -50
- package/lib/domain/usecases/OpenProjectUsecase.js +0 -13
- package/lib/domain/usecases/SaveViewUsecase.js +0 -57
- package/lib/file.js +0 -1395
- package/lib/languages.js +0 -114
- package/lib/list.js +0 -105
- package/lib/migrate-config.js +0 -165
- package/lib/mixins/repo-fs-store.js +0 -424
- package/lib/mixins/repo-watched-fs-store.js +0 -195
- package/lib/plugins/archive-plugin.js +0 -70
- package/lib/plugins/default-board-actions-plugin.js +0 -56
- package/lib/plugins/default-board-properties-plugin.js +0 -101
- package/lib/plugins/epic-plugin.js +0 -176
- package/lib/plugins/extension-plugin.js +0 -87
- package/lib/plugins/persist-tags-plugin.js +0 -13
- package/lib/plugins/plugin-manager.js +0 -421
- package/lib/plugins/plugin-registry.js +0 -61
- package/lib/project-factory.js +0 -45
- package/lib/project.js +0 -911
- package/lib/repository.js +0 -1746
- package/lib/task.js +0 -798
- package/lib/tools.js +0 -250
- package/lib/usecases/get-imdone-url.js +0 -6
- package/lib/usecases/get-project-tags.js +0 -16
- package/lib/usecases/get-tasks-in-file.js +0 -29
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
const eol = require('eol')
|
|
2
|
-
const XRegExp = require('xregexp')
|
|
3
|
-
|
|
4
|
-
const FILE_TYPES = {
|
|
5
|
-
MARKDOWN: 'markdown',
|
|
6
|
-
CODE: 'code',
|
|
7
|
-
}
|
|
8
|
-
const TASK_TYPES = {
|
|
9
|
-
CODE: 'CODE',
|
|
10
|
-
HASHTAG: 'HASHTAG',
|
|
11
|
-
MARKDOWN: 'MARKDOWN',
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const DEFAULT_TOKEN_PREFIX = '#'
|
|
15
|
-
const START_TAG = '<card>'
|
|
16
|
-
const END_TAG = '</card>'
|
|
17
|
-
const CODE_STYLE_PATTERN = '([A-Z]+[A-Z-_]+?)((:)(-?[\\d.]+(?:e-?\\d+)?)?)?[ \\t]+(.+)$'
|
|
18
|
-
const LIST_NAME_PATTERN = '[\\p{L}0-9-_]{2,}' // [a-zA-Z-_]+?
|
|
19
|
-
const LINK_STYLE_REGEX = new XRegExp(
|
|
20
|
-
`(\\[.*\\]\\s?)?(\\[(.+)\\]\\(#(${LIST_NAME_PATTERN})(:)(-?[\\d.]+(?:e-?\\d+)?)?\\))`,
|
|
21
|
-
'gm'
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
const CHECK_REGEX = /^(\s*- )\[([x ])\]/
|
|
25
|
-
|
|
26
|
-
function getHashStyleRegex(tokenPrefix = DEFAULT_TOKEN_PREFIX, orderMeta = false) {
|
|
27
|
-
return orderMeta ?
|
|
28
|
-
new XRegExp(
|
|
29
|
-
`${tokenPrefix}(${LIST_NAME_PATTERN})[ \\t]+(.+)$`, 'gm'
|
|
30
|
-
) :
|
|
31
|
-
new XRegExp(
|
|
32
|
-
`${tokenPrefix}(${LIST_NAME_PATTERN})(:(-?[\\d.]+(?:e-?\\d+)?)?)?[ \\t]+(.+)$`,
|
|
33
|
-
'gm'
|
|
34
|
-
)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function getCheckedData(content) {
|
|
38
|
-
const taskRegex = new RegExp(CHECK_REGEX)
|
|
39
|
-
const result = taskRegex.exec(content)
|
|
40
|
-
return result
|
|
41
|
-
? {
|
|
42
|
-
pad: result[1].length,
|
|
43
|
-
checked: result[2].trim() !== '',
|
|
44
|
-
}
|
|
45
|
-
: null
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getContentLines(content) {
|
|
49
|
-
let foundContent = false
|
|
50
|
-
return eol.split(content).filter((line) => {
|
|
51
|
-
const hasContent = line.trim()
|
|
52
|
-
if (!foundContent && hasContent) foundContent = true
|
|
53
|
-
return foundContent || hasContent
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function isCustomCardTerminator(config, line) {
|
|
58
|
-
return config.customCardTerminator
|
|
59
|
-
&& config.customCardTerminator.trim()
|
|
60
|
-
&& line
|
|
61
|
-
&& line.trim() === config.customCardTerminator
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function isCheckBoxTask (config, line, beforeText) {
|
|
65
|
-
if (!config.isAddCheckBoxTasks()) return
|
|
66
|
-
|
|
67
|
-
const beforeTextCheckData = getCheckedData(beforeText)
|
|
68
|
-
if (!beforeTextCheckData) return
|
|
69
|
-
|
|
70
|
-
const lineCheckData = getCheckedData(line)
|
|
71
|
-
if (!lineCheckData) return
|
|
72
|
-
|
|
73
|
-
return lineCheckData.pad <= beforeTextCheckData.pad
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function hasTaskInText(config, text, isCodeFile) {
|
|
77
|
-
const hashStyleRegex = new XRegExp(getHashStyleRegex(config.tokenPrefix));
|
|
78
|
-
const linkStyleRegex = new XRegExp(LINK_STYLE_REGEX);
|
|
79
|
-
|
|
80
|
-
const inlineCodeRe = /`[^`]*`/g;
|
|
81
|
-
|
|
82
|
-
// Function to check if a match is within inline code
|
|
83
|
-
function isWithinInlineCode(index) {
|
|
84
|
-
let match;
|
|
85
|
-
while ((match = inlineCodeRe.exec(text)) !== null) {
|
|
86
|
-
const isInCode = index >= match.index && index < match.index + match[0].length
|
|
87
|
-
if (isInCode) return true;
|
|
88
|
-
}
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Check for code style tasks
|
|
93
|
-
if (isCodeFile && hasCodeStyleTask(config, text)) {
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Check for hash style tasks
|
|
98
|
-
let result;
|
|
99
|
-
if ((result = hashStyleRegex.exec(text)) !== null && !isWithinInlineCode(result.index)) {
|
|
100
|
-
return config.lists.find((list) => text.includes(`${config.tokenPrefix}${list.name}`));
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Check for link style tasks
|
|
104
|
-
if ((result = linkStyleRegex.exec(text)) !== null && !isWithinInlineCode(result.index)) {
|
|
105
|
-
return config.lists.find((list) => text.includes(`${config.tokenPrefix}${list.name}`));
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function isBeforeTextMarkdownList(beforeText) {
|
|
112
|
-
return /^\s*(\*|-|- \[[x| ]\]|\d+\.|[a-zA-Z]\.)\s$/.test(beforeText)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function isMarkdownListItem(line) {
|
|
116
|
-
return /^\s*(\*|-|- \[[x| ]\]|\d+\.|[a-zA-Z]\.)\s/.test(line)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function padDescription(description = [], beforeText = '') {
|
|
120
|
-
if (!isBeforeTextMarkdownList(beforeText)) return description
|
|
121
|
-
return description.map((line) => {
|
|
122
|
-
return line.padStart(line.length + beforeText.length)
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function isLineOutsideMarkdownList(line, beforeText) {
|
|
127
|
-
return isBeforeTextMarkdownList(beforeText) &&
|
|
128
|
-
isMarkdownListItem(line) &&
|
|
129
|
-
line.search(/\S/) <= beforeText.search(/\S/)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function hasCodeStyleTask(config, text) {
|
|
133
|
-
const codeStylePatternRe = new RegExp(CODE_STYLE_PATTERN);
|
|
134
|
-
let result = codeStylePatternRe.exec(text);
|
|
135
|
-
|
|
136
|
-
if (!result) return false;
|
|
137
|
-
|
|
138
|
-
// Check if the match is within inline code
|
|
139
|
-
const inlineCodeRe = /`[^`]*`/g;
|
|
140
|
-
let match;
|
|
141
|
-
while ((match = inlineCodeRe.exec(text)) !== null) {
|
|
142
|
-
if (result.index >= match.index && result.index < match.index + match[0].length) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return config.includeList(result[1]);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
function getCardTagsTaskContent ({
|
|
151
|
-
content,
|
|
152
|
-
fileType
|
|
153
|
-
}) {
|
|
154
|
-
const isCodeFile = fileType === FILE_TYPES.CODE
|
|
155
|
-
if (isCodeFile) return
|
|
156
|
-
|
|
157
|
-
const isMarkDownFile = fileType === FILE_TYPES.MARKDOWN
|
|
158
|
-
let lines = getContentLines(content)
|
|
159
|
-
const hasCardStartTag =
|
|
160
|
-
isMarkDownFile && lines.length > 1 && lines[1].trim() === START_TAG
|
|
161
|
-
if (!hasCardStartTag) return
|
|
162
|
-
|
|
163
|
-
let openBlockCommentTokens = 0
|
|
164
|
-
let closeBlockCommentTokens = 0
|
|
165
|
-
let hasCardEndTag = false
|
|
166
|
-
const rawTaskContentLines = []
|
|
167
|
-
const taskContentLines = []
|
|
168
|
-
for (let i = 1; i < lines.length; i++) {
|
|
169
|
-
let line = lines[i]
|
|
170
|
-
// Check for matching block comments in markdown files
|
|
171
|
-
if (isMarkDownFile && line.trim().indexOf('<!--') > -1)
|
|
172
|
-
openBlockCommentTokens++
|
|
173
|
-
if (isMarkDownFile && line.trim().indexOf('-->') > -1)
|
|
174
|
-
closeBlockCommentTokens++
|
|
175
|
-
|
|
176
|
-
rawTaskContentLines.push(line)
|
|
177
|
-
|
|
178
|
-
if (line.trim() === START_TAG) continue
|
|
179
|
-
if (line.trim() === END_TAG) {
|
|
180
|
-
hasCardEndTag = true
|
|
181
|
-
break
|
|
182
|
-
}
|
|
183
|
-
taskContentLines.push(line)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Remove extra block comment tokens
|
|
187
|
-
if (
|
|
188
|
-
isMarkDownFile &&
|
|
189
|
-
rawTaskContentLines.length &&
|
|
190
|
-
rawTaskContentLines[rawTaskContentLines.length - 1].trim() === '-->' &&
|
|
191
|
-
openBlockCommentTokens !== closeBlockCommentTokens
|
|
192
|
-
)
|
|
193
|
-
rawTaskContentLines.pop()
|
|
194
|
-
|
|
195
|
-
const isWrappedWithCardTag = hasCardStartTag && hasCardEndTag
|
|
196
|
-
|
|
197
|
-
return {
|
|
198
|
-
rawTaskContentLines,
|
|
199
|
-
taskContentLines,
|
|
200
|
-
isWrappedWithCardTag,
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// This finds the end of task
|
|
205
|
-
function getCodeFileTaskContent ({
|
|
206
|
-
config,
|
|
207
|
-
content,
|
|
208
|
-
inBlockComment,
|
|
209
|
-
fileType,
|
|
210
|
-
lang
|
|
211
|
-
}) {
|
|
212
|
-
const isCodeFile = fileType === FILE_TYPES.CODE
|
|
213
|
-
if (!isCodeFile) return
|
|
214
|
-
|
|
215
|
-
const rawTaskContentLines = []
|
|
216
|
-
let lines = getContentLines(content)
|
|
217
|
-
for (let i = 1; i < lines.length; i++) {
|
|
218
|
-
let line = lines[i]
|
|
219
|
-
// Another task ends a task
|
|
220
|
-
if (hasTaskInText(config, line, isCodeFile)) break
|
|
221
|
-
if (
|
|
222
|
-
!inBlockComment &&
|
|
223
|
-
(line.indexOf(lang.symbol) < 0 ||
|
|
224
|
-
line.trim().indexOf(lang.symbol) > 0 ||
|
|
225
|
-
line.trim() === lang.symbol)
|
|
226
|
-
)
|
|
227
|
-
break
|
|
228
|
-
if (lang.block && line.trim() === lang.block.end)
|
|
229
|
-
break
|
|
230
|
-
if (lang.block && line.trim() === lang.block.ignore)
|
|
231
|
-
break
|
|
232
|
-
if (line && lang && lang.block) line = line.replace(lang.block.end, '')
|
|
233
|
-
|
|
234
|
-
rawTaskContentLines.push(line)
|
|
235
|
-
}
|
|
236
|
-
return {
|
|
237
|
-
rawTaskContentLines,
|
|
238
|
-
taskContentLines: rawTaskContentLines,
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function getTextFileTaskContent ({
|
|
243
|
-
config,
|
|
244
|
-
content,
|
|
245
|
-
beforeText,
|
|
246
|
-
fileType,
|
|
247
|
-
}) {
|
|
248
|
-
const isCodeFile = fileType === FILE_TYPES.CODE
|
|
249
|
-
if (isCodeFile) return
|
|
250
|
-
|
|
251
|
-
let lines = getContentLines(content)
|
|
252
|
-
const hasCardStartTag = lines.length > 1 && lines[1].trim() === START_TAG
|
|
253
|
-
if (hasCardStartTag) return
|
|
254
|
-
|
|
255
|
-
const isMarkDownFile = fileType === FILE_TYPES.MARKDOWN
|
|
256
|
-
const isTaskInList = isMarkDownFile && isBeforeTextMarkdownList(beforeText)
|
|
257
|
-
let openBlockCommentTokens = 0
|
|
258
|
-
let closeBlockCommentTokens = 0
|
|
259
|
-
let lastLineBlank = false
|
|
260
|
-
let endsWithDoubleBlank = false
|
|
261
|
-
let trailingBlankLines = 0
|
|
262
|
-
const rawTaskContentLines = []
|
|
263
|
-
const taskContentLines = []
|
|
264
|
-
|
|
265
|
-
let inCodeBlock = false
|
|
266
|
-
|
|
267
|
-
for (let i = 1; i < lines.length; i++) {
|
|
268
|
-
let line = lines[i]
|
|
269
|
-
|
|
270
|
-
// Check for markdown code blocks
|
|
271
|
-
if (isMarkDownFile && line.trim().startsWith('```')) {
|
|
272
|
-
inCodeBlock = !inCodeBlock
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Only break if the task is not in a markdown code block or code span
|
|
276
|
-
if (!inCodeBlock && hasTaskInText(config, line)) break
|
|
277
|
-
if (isCheckBoxTask(config, line, beforeText)) break
|
|
278
|
-
if (isTaskInList && isLineOutsideMarkdownList(line, beforeText)) break
|
|
279
|
-
if (isCustomCardTerminator(config, line)) break
|
|
280
|
-
|
|
281
|
-
rawTaskContentLines.push(line)
|
|
282
|
-
taskContentLines.push(`${line}`)
|
|
283
|
-
|
|
284
|
-
// Check for matching block comments in markdown files
|
|
285
|
-
if (isMarkDownFile && line.trim().indexOf('<!--') > -1)
|
|
286
|
-
openBlockCommentTokens++
|
|
287
|
-
if (isMarkDownFile && line.trim().indexOf('-->') > -1)
|
|
288
|
-
closeBlockCommentTokens++
|
|
289
|
-
|
|
290
|
-
const thisLineBlank = line.trim() === ''
|
|
291
|
-
|
|
292
|
-
if (thisLineBlank && lastLineBlank) {
|
|
293
|
-
endsWithDoubleBlank = true
|
|
294
|
-
break
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
lastLineBlank = thisLineBlank
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
if (endsWithDoubleBlank) trailingBlankLines = 2
|
|
301
|
-
else if (lastLineBlank) trailingBlankLines = 1
|
|
302
|
-
|
|
303
|
-
// Remove extra block comment tokens
|
|
304
|
-
if (
|
|
305
|
-
isMarkDownFile &&
|
|
306
|
-
rawTaskContentLines.length &&
|
|
307
|
-
rawTaskContentLines[rawTaskContentLines.length - 1].trim() === '-->' &&
|
|
308
|
-
openBlockCommentTokens !== closeBlockCommentTokens
|
|
309
|
-
) {
|
|
310
|
-
rawTaskContentLines.pop()
|
|
311
|
-
taskContentLines.pop()
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
return {
|
|
315
|
-
rawTaskContentLines,
|
|
316
|
-
taskContentLines: trailingBlankLines
|
|
317
|
-
? taskContentLines.slice(0, -trailingBlankLines)
|
|
318
|
-
: taskContentLines,
|
|
319
|
-
trailingBlankLines,
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
function getTaskContent ({
|
|
324
|
-
config,
|
|
325
|
-
content,
|
|
326
|
-
inBlockComment,
|
|
327
|
-
beforeText,
|
|
328
|
-
fileType,
|
|
329
|
-
lang
|
|
330
|
-
}) {
|
|
331
|
-
return getCardTagsTaskContent({ content, fileType }) ||
|
|
332
|
-
getCodeFileTaskContent({ config, content, inBlockComment, fileType, lang }) ||
|
|
333
|
-
getTextFileTaskContent({ config, content, beforeText, fileType })
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function getRawTask ({
|
|
337
|
-
tokenPrefix = DEFAULT_TOKEN_PREFIX,
|
|
338
|
-
orderMeta = true,
|
|
339
|
-
beforeText = '',
|
|
340
|
-
hasColon = false,
|
|
341
|
-
list,
|
|
342
|
-
order = '',
|
|
343
|
-
text,
|
|
344
|
-
type = TASK_TYPES.HASHTAG
|
|
345
|
-
}) {
|
|
346
|
-
if (type === TASK_TYPES.MARKDOWN) {
|
|
347
|
-
return `${beforeText || ''}[${text}](${tokenPrefix}${list}:${
|
|
348
|
-
orderMeta ? '' : order
|
|
349
|
-
})`
|
|
350
|
-
} else {
|
|
351
|
-
const colon = hasColon || (isNumber(order) && !orderMeta) ? ':' : '';
|
|
352
|
-
return `${beforeText || ''}${tokenPrefix}${list}${colon}${
|
|
353
|
-
orderMeta ? '' : order
|
|
354
|
-
} ${text}`
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
function isNumber (value) {
|
|
359
|
-
return !isNaN(parseFloat(value)) && isFinite(value)
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
module.exports = {
|
|
363
|
-
FILE_TYPES,
|
|
364
|
-
TASK_TYPES,
|
|
365
|
-
getTaskContent,
|
|
366
|
-
getRawTask,
|
|
367
|
-
isBeforeTextMarkdownList,
|
|
368
|
-
padDescription,
|
|
369
|
-
getCheckedData,
|
|
370
|
-
hasTaskInText,
|
|
371
|
-
isNumber,
|
|
372
|
-
getHashStyleRegex,
|
|
373
|
-
CHECK_REGEX,
|
|
374
|
-
LIST_NAME_PATTERN,
|
|
375
|
-
LINK_STYLE_REGEX
|
|
376
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
const TaskParser = require('./TaskParser')
|
|
2
|
-
|
|
3
|
-
module.exports = class CheckStyleTaskParser extends TaskParser {
|
|
4
|
-
constructor() {
|
|
5
|
-
super()
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
get pattern() {
|
|
9
|
-
return /^(\s*- \[([x ])\]\s)(.+$)/gm
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
parse(lineContent, line, matchResult, task) {
|
|
13
|
-
let [match, beforeText, checked, text] = matchResult
|
|
14
|
-
if (
|
|
15
|
-
(task && !task.beforeText) ||
|
|
16
|
-
(task && task.beforeText.length !== beforeText.length)
|
|
17
|
-
)
|
|
18
|
-
return
|
|
19
|
-
checked = checked.trim() === 'x'
|
|
20
|
-
return {
|
|
21
|
-
beforeText,
|
|
22
|
-
text,
|
|
23
|
-
line,
|
|
24
|
-
checked,
|
|
25
|
-
type: this.config.getNewCardSyntax(),
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const TaskParser = require('./TaskParser')
|
|
2
|
-
|
|
3
|
-
module.exports = class CodeStyleTaskParser extends TaskParser {
|
|
4
|
-
constructor(config) {
|
|
5
|
-
super('CODE', config)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
get pattern() {
|
|
9
|
-
return /^(.*?[ #]?)([a-zA-Z-_]+?)(:)(-?[\d.]+(?:e-?\d+)?)?[ \t]+(.+)$/gm
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
parse(lineContent, line, matchResult) {
|
|
13
|
-
const [match, beforeText, list, colon, order, text] = matchResult
|
|
14
|
-
return {
|
|
15
|
-
beforeText,
|
|
16
|
-
text,
|
|
17
|
-
order,
|
|
18
|
-
list,
|
|
19
|
-
line,
|
|
20
|
-
colon,
|
|
21
|
-
type: this.type,
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const TaskParser = require('./TaskParser')
|
|
2
|
-
const { getHashStyleRegex } = require('./CardContentParser')
|
|
3
|
-
|
|
4
|
-
module.exports = class HashStyleTaskParser extends TaskParser {
|
|
5
|
-
constructor(config) {
|
|
6
|
-
super('HASHTAG', config)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
get pattern() {
|
|
10
|
-
const config = this.config
|
|
11
|
-
return getHashStyleRegex(config.tokenPrefix, config.orderMeta)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
parse(lineContent, line, matchResult) {
|
|
15
|
-
const [rawTask, list, orderGroup, order, text] = matchResult
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
// beforeText,
|
|
19
|
-
text,
|
|
20
|
-
order,
|
|
21
|
-
list,
|
|
22
|
-
line,
|
|
23
|
-
colon: orderGroup && orderGroup.startsWith(':'),
|
|
24
|
-
type: this.type,
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const TaskParser = require('./TaskParser')
|
|
2
|
-
|
|
3
|
-
module.exports = class MarkdownStyleTaskParser extends TaskParser {
|
|
4
|
-
constructor(config) {
|
|
5
|
-
super('MARKDOWN', config)
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
get pattern() {
|
|
9
|
-
return /^(.*)(\[(.+?)\]\(#([a-zA-Z-_]+?)(:)(-?[\d.]+(?:e-?\d+)?)?\))/gm
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
parse(lineContent, line, matchResult) {
|
|
13
|
-
const [match, beforeText, rawTask, text, list, colon, order] = matchResult
|
|
14
|
-
return {
|
|
15
|
-
beforeText,
|
|
16
|
-
text,
|
|
17
|
-
order,
|
|
18
|
-
list,
|
|
19
|
-
line,
|
|
20
|
-
colon,
|
|
21
|
-
type: this.type,
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
class Task {
|
|
3
|
-
constructor({ beforeText, text, list, line, order, checked, colon, type }) {
|
|
4
|
-
this.contentLength = 0
|
|
5
|
-
this.description = []
|
|
6
|
-
this.beforeText = beforeText
|
|
7
|
-
this.text = text
|
|
8
|
-
this.list = list
|
|
9
|
-
this.line = line
|
|
10
|
-
this.order = order
|
|
11
|
-
this.checked = checked
|
|
12
|
-
this.colon = colon
|
|
13
|
-
this.type = type
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
module.exports = class TaskParser {
|
|
18
|
-
constructor(type, config) {
|
|
19
|
-
this.config = config
|
|
20
|
-
this.type = type
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
get pattern() {
|
|
24
|
-
throw new Error('Unimplemented')
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
parseLine(lineContent, line, task) {
|
|
28
|
-
const re = new RegExp(this.pattern)
|
|
29
|
-
const result = re.exec(lineContent)
|
|
30
|
-
const parseResult = result && this.parse(lineContent, line, result, task)
|
|
31
|
-
|
|
32
|
-
if (parseResult && this.config.lists && !this.config.listExists(parseResult.list)) {
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return parseResult && new Task(parseResult)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const fs = require('fs/promises')
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const LocalFileParserFactory = require('../parsers/file/LocalFileParserFactory')
|
|
4
|
-
|
|
5
|
-
module.exports = class FileSystemProjectReader {
|
|
6
|
-
async read (projectPath) {
|
|
7
|
-
// BACKLOG ## Load the config file
|
|
8
|
-
// #adapter
|
|
9
|
-
// [lib/adapters/readers/FileSystemProjectReader.js](lib/adapters/readers/FileSystemProjectReader.js)
|
|
10
|
-
// <!-- epic:"Release 2.0"
|
|
11
|
-
// order:-590
|
|
12
|
-
// -->
|
|
13
|
-
const files = await this.getFilesFromDirectory(projectPath)
|
|
14
|
-
|
|
15
|
-
// BACKLOG ## Parse project files
|
|
16
|
-
// - Loop over the files in the filesystem
|
|
17
|
-
// - Give each one a file parser and parse the file
|
|
18
|
-
// - `const parser = LocalFileParserFactory.getFileParser(filePath, config)`
|
|
19
|
-
// - Use worker_threads
|
|
20
|
-
// - After tasks are parsed trim the description appropriately and look for Check style tasks in what's left of the description
|
|
21
|
-
// #adapter
|
|
22
|
-
// [lib/adapters/readers/FileSystemProjectReader.js](lib/adapters/readers/FileSystemProjectReader.js)
|
|
23
|
-
// <!-- epic:"Release 2.0"
|
|
24
|
-
// order:-600
|
|
25
|
-
// -->
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async getFilesFromDirectory (directoryPath) {
|
|
30
|
-
const filesInDirectory = await fs.readdir(directoryPath)
|
|
31
|
-
const files = await Promise.all(
|
|
32
|
-
filesInDirectory.map(async (file) => {
|
|
33
|
-
const filePath = path.join(directoryPath, file)
|
|
34
|
-
const stats = await fs.stat(filePath)
|
|
35
|
-
|
|
36
|
-
if (stats.isDirectory()) {
|
|
37
|
-
return this.getFilesFromDirectory(filePath)
|
|
38
|
-
} else {
|
|
39
|
-
return filePath
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
)
|
|
43
|
-
return files.filter((file) => file.length)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
const { readFile, writeFile, exists } = require('../file-gateway')
|
|
2
|
-
const { CONFIG_DIR, CONFIG_FILE_YML } = require('../../constants')
|
|
3
|
-
const { loadYAML, dumpYAML } = require('../yaml')
|
|
4
|
-
const findUp = require('find-up')
|
|
5
|
-
const _path = require('path')
|
|
6
|
-
const Config = require('../../config')
|
|
7
|
-
|
|
8
|
-
module.exports = {
|
|
9
|
-
load,
|
|
10
|
-
save,
|
|
11
|
-
loadForFilePath,
|
|
12
|
-
findImdonePath
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async function load(projectPath, configPath = _path.join(projectPath, CONFIG_FILE_YML)) {
|
|
16
|
-
const configLike = await loadYamlConfig(configPath)
|
|
17
|
-
return configLike && new Config(configLike)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function save(config, projectPath) {
|
|
21
|
-
const configPath = _path.join(projectPath, CONFIG_FILE_YML)
|
|
22
|
-
await writeFile(configPath, dumpYAML(config))
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function loadForFilePath(filePath) {
|
|
26
|
-
const projectPath = await findImdonePath(filePath)
|
|
27
|
-
return load(projectPath)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async function loadYamlConfig(filePath) {
|
|
31
|
-
if (!(await exists(filePath))) return
|
|
32
|
-
const configData = await readFile(filePath, 'utf-8')
|
|
33
|
-
let configLike = {}
|
|
34
|
-
try {
|
|
35
|
-
configLike = loadYAML(configData.toString())
|
|
36
|
-
if (configLike.exclude) delete configLike.exclude
|
|
37
|
-
if (configLike.watcher) delete configLike.watcher
|
|
38
|
-
|
|
39
|
-
} catch (e) {
|
|
40
|
-
console.error(`Error parsing config file: ${filePath}`)
|
|
41
|
-
}
|
|
42
|
-
return configLike
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function findImdonePath(cwd) {
|
|
46
|
-
const configDir = await findUp(CONFIG_DIR, { cwd, type: 'directory' })
|
|
47
|
-
return _path.dirname(configDir)
|
|
48
|
-
}
|
|
49
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const { readFile, writeFile, exists } = require('../file-gateway')
|
|
2
|
-
const { CONFIG_DIR } = require('../../constants')
|
|
3
|
-
const { loadYAML, dumpYAML } = require('../yaml')
|
|
4
|
-
const _path = require('path')
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
load,
|
|
8
|
-
save
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async function load(projectPath) {
|
|
12
|
-
const tagsPath = getTagsPath(projectPath)
|
|
13
|
-
if (!(await exists(tagsPath))) return
|
|
14
|
-
const tagsData = await readFile(tagsPath, 'utf-8')
|
|
15
|
-
try {
|
|
16
|
-
const { tags } = loadYAML(tagsData)
|
|
17
|
-
return tags
|
|
18
|
-
} catch (e) {
|
|
19
|
-
console.error(e)
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
async function save(tags, projectPath) {
|
|
25
|
-
await writeFile(getTagsPath(projectPath), dumpYAML({ tags }))
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function getTagsPath(projectPath) {
|
|
29
|
-
return _path.join(projectPath, CONFIG_DIR, 'tags.yml')
|
|
30
|
-
}
|