imdone-core 1.53.5 → 1.53.6
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/lib/adapters/markdown.js +11 -4
- package/lib/card.js +1 -0
- package/lib/config.js +6 -0
- package/lib/default-settings.js +1 -0
- package/lib/file.js +43 -54
- package/lib/migrate-config.js +4 -0
- package/lib/plugins/default-card-properties-plugin.js +1 -0
- package/lib/task.js +56 -51
- package/package.json +1 -1
- package/devops/containers/README.md +0 -11
- package/devops/containers/remove-remote.sh +0 -6
- package/devops/containers/setup-remote.sh +0 -31
- package/devops/imdone/backlog-config.yml +0 -102
- package/devops/imdone/backlog.imdoneignore +0 -1
- package/devops/imdone/story-config.yml +0 -71
package/lib/adapters/markdown.js
CHANGED
|
@@ -29,7 +29,7 @@ function getRenderer(filePath) {
|
|
|
29
29
|
.use(imageSize)
|
|
30
30
|
.use(obsidianTopicLinks(filePath))
|
|
31
31
|
.use(replaceImagePaths(filePath))
|
|
32
|
-
.use(
|
|
32
|
+
.use(replaceLinkPathsAndTitles(filePath))
|
|
33
33
|
.validateLink = () => true
|
|
34
34
|
|
|
35
35
|
return md
|
|
@@ -50,11 +50,12 @@ function obsidianTopicLinks(filePath) {
|
|
|
50
50
|
let topic = match[1].trim();
|
|
51
51
|
const alias = match[2] ? match[2].trim() : topic;
|
|
52
52
|
if (!topic.endsWith('.md')) topic = `${topic}.md`;
|
|
53
|
-
const
|
|
53
|
+
const unencodedHref = resolveFileUrl(topic, filePath);
|
|
54
|
+
const href = encodeURI(unencodedHref);
|
|
54
55
|
|
|
55
56
|
// Create a new token
|
|
56
57
|
const token = state.push("obsidian_link", "", 0);
|
|
57
|
-
token.content = `<a href="${href}">${md.utils.escapeHtml(alias)}</a>`;
|
|
58
|
+
token.content = `<a href="${href}" title="${unencodedHref}">${md.utils.escapeHtml(alias)}</a>`;
|
|
58
59
|
|
|
59
60
|
// Move parsing position forward
|
|
60
61
|
state.pos += fullMatch.length;
|
|
@@ -92,7 +93,7 @@ function replaceImagePaths(filePath) {
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
function
|
|
96
|
+
function replaceLinkPathsAndTitles(filePath) {
|
|
96
97
|
|
|
97
98
|
return function(md) {
|
|
98
99
|
const defaultRender = md.renderer.rules.link_open || function(tokens, idx, options, env, self) {
|
|
@@ -108,6 +109,12 @@ function replaceLinkPaths(filePath) {
|
|
|
108
109
|
if (srcUrl) token.attrs[srcIndex][1] = srcUrl;
|
|
109
110
|
}
|
|
110
111
|
|
|
112
|
+
// set the title to the href if it's not already set
|
|
113
|
+
const titleIndex = token.attrIndex('title');
|
|
114
|
+
if (titleIndex < 0) {
|
|
115
|
+
const title = token.attrs[srcIndex][1];
|
|
116
|
+
token.attrPush(['title', title]);
|
|
117
|
+
}
|
|
111
118
|
return defaultRender(tokens, idx, options, env, self);
|
|
112
119
|
};
|
|
113
120
|
}
|
package/lib/card.js
CHANGED
package/lib/config.js
CHANGED
|
@@ -70,6 +70,12 @@ class Config {
|
|
|
70
70
|
return _get(this, 'settings.cards.doneList', defaultValue)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
getDoingList() {
|
|
74
|
+
const lists = _cloneDeep(this.lists).reverse().filter((list) => !list.filter)
|
|
75
|
+
const defaultValue = lists && lists.length ? lists[1].name : undefined
|
|
76
|
+
return _get(this, 'settings.cards.doingList', defaultValue)
|
|
77
|
+
}
|
|
78
|
+
|
|
73
79
|
isAddNewCardsToTop() {
|
|
74
80
|
return _get(this, 'settings.cards.addNewCardsToTop', false)
|
|
75
81
|
}
|
package/lib/default-settings.js
CHANGED
package/lib/file.js
CHANGED
|
@@ -78,10 +78,8 @@ function File(opts) {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
util.inherits(File, events.EventEmitter)
|
|
81
|
-
const CODE_BLOCK_REGEX = (File.CODE_BLOCK_REGEX = /`{3}[\s\S]*?`{3}/gm)
|
|
82
|
-
const INLINE_CODE_REGEX = (File.INLINE_CODE_REGEX = /`[\s\S]*?`/g)
|
|
83
|
-
const CODE_STYLE_END = '((:)(-?[\\d.]+(?:e-?\\d+)?)?)?[ \\t]+(.+)$'
|
|
84
81
|
|
|
82
|
+
const CODE_STYLE_END = '((:)(-?[\\d.]+(?:e-?\\d+)?)?)?[ \\t]+(.+)$'
|
|
85
83
|
const CODE_STYLE_PATTERN = (File.CODE_STYLE_PATTERN =
|
|
86
84
|
'([A-Z]+[A-Z-_]+?)' + CODE_STYLE_END)
|
|
87
85
|
|
|
@@ -103,6 +101,10 @@ function getDoneList(config) {
|
|
|
103
101
|
return config.getDoneList()
|
|
104
102
|
}
|
|
105
103
|
|
|
104
|
+
function getDoingList(config) {
|
|
105
|
+
return config.getDoingList()
|
|
106
|
+
}
|
|
107
|
+
|
|
106
108
|
function getFrontMeta(meta) {
|
|
107
109
|
const metadata = {}
|
|
108
110
|
Object.entries(meta).forEach(([prop, val]) => {
|
|
@@ -137,6 +139,37 @@ File.isMarkdown = function (relPath) {
|
|
|
137
139
|
return /\.md$/i.test(relPath) || path.extname(relPath) === ''
|
|
138
140
|
}
|
|
139
141
|
|
|
142
|
+
File.prototype.removeCompleted = function ({ task, content, config }) {
|
|
143
|
+
const doneList = getDoneList(config)
|
|
144
|
+
if (doneList === task.list) return content
|
|
145
|
+
if (
|
|
146
|
+
task.meta.completed &&
|
|
147
|
+
task.meta.completed.length > 0
|
|
148
|
+
) {
|
|
149
|
+
content = this.removeMetaData(
|
|
150
|
+
content,
|
|
151
|
+
'completed',
|
|
152
|
+
task.meta.completed[0]
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
return content
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
File.addStarted = function ({ task, content, config }) {
|
|
159
|
+
if (!task || !config || !config.settings) return content
|
|
160
|
+
if (!config.settings.cards.addStartedMeta) return content
|
|
161
|
+
if (task.meta.started) return content
|
|
162
|
+
if (task.list !== getDoingList(config)) return content
|
|
163
|
+
const now = getIsoDateWithOffset()
|
|
164
|
+
content = task.addToLastCommentInContent(
|
|
165
|
+
content,
|
|
166
|
+
`started${config.getMetaSep()}${now}`,
|
|
167
|
+
File.isMetaNewLine(config)
|
|
168
|
+
)
|
|
169
|
+
const lines = eol.split(content)
|
|
170
|
+
return lines.join(lineEnd)
|
|
171
|
+
}
|
|
172
|
+
|
|
140
173
|
File.addCompleted = function ({ task, content, config }) {
|
|
141
174
|
const doneList = getDoneList(config)
|
|
142
175
|
if (
|
|
@@ -220,7 +253,6 @@ File.prototype.trackListChanges = function ({ task, content, config, modify }) {
|
|
|
220
253
|
.filter((list) => !list.filter)
|
|
221
254
|
.map((list) => list.name)
|
|
222
255
|
|
|
223
|
-
const doneList = getDoneList(config)
|
|
224
256
|
let beforeTextModified = false
|
|
225
257
|
if (this.isMarkDownFile()) {
|
|
226
258
|
beforeTextModified = trackMarkdownChecklistChanges({task, config, modify})
|
|
@@ -239,18 +271,6 @@ File.prototype.trackListChanges = function ({ task, content, config, modify }) {
|
|
|
239
271
|
if (!task.meta[list]) task.meta[list] = []
|
|
240
272
|
task.meta[list].push(now)
|
|
241
273
|
}
|
|
242
|
-
|
|
243
|
-
if (
|
|
244
|
-
doneList !== task.list &&
|
|
245
|
-
task.meta.completed &&
|
|
246
|
-
task.meta.completed.length > 0
|
|
247
|
-
) {
|
|
248
|
-
content = this.removeMetaData(
|
|
249
|
-
content,
|
|
250
|
-
'completed',
|
|
251
|
-
task.meta.completed[0]
|
|
252
|
-
)
|
|
253
|
-
}
|
|
254
274
|
}
|
|
255
275
|
|
|
256
276
|
return { content, beforeTextModified }
|
|
@@ -278,7 +298,9 @@ File.prototype.transformTask = function ({config, modify, task}) {
|
|
|
278
298
|
content = File.parseDueDate(config, content)
|
|
279
299
|
content = File.parseRemindDate(config, content)
|
|
280
300
|
content = File.parseDeferDate(config, content)
|
|
301
|
+
content = File.addStarted({ task, content, config })
|
|
281
302
|
content = File.addCompleted({ task, content, config })
|
|
303
|
+
content = this.removeCompleted({ task, content, config })
|
|
282
304
|
content = task.format(content)
|
|
283
305
|
if (
|
|
284
306
|
content.trim() !== task.content.trim()
|
|
@@ -290,7 +312,6 @@ File.prototype.transformTask = function ({config, modify, task}) {
|
|
|
290
312
|
}
|
|
291
313
|
|
|
292
314
|
File.prototype.transformTasks = function (config, modify) {
|
|
293
|
-
// if (this.isCodeFile()) return
|
|
294
315
|
fastSort(this.getTasks())
|
|
295
316
|
.desc(u => u.line)
|
|
296
317
|
.forEach(task => this.transformTask({config, modify, task}))
|
|
@@ -360,7 +381,7 @@ File.prototype.extractHashStyleTasks = function (config, pos, content) {
|
|
|
360
381
|
if (!config.listExists(list)) continue
|
|
361
382
|
|
|
362
383
|
const posInContent = result.index + pos
|
|
363
|
-
if (this.
|
|
384
|
+
if (this.isWithinCodeSpanOrBlock(posInContent, content)) continue
|
|
364
385
|
|
|
365
386
|
const line = this.getLineNumber(posInContent)
|
|
366
387
|
if (this.hasTaskAtLine(line)) continue
|
|
@@ -395,7 +416,7 @@ File.prototype.extractLinkStyleTasks = function (config, pos, content) {
|
|
|
395
416
|
let [match, before, rawTask, text, list, colon, order] = result
|
|
396
417
|
const beforeLength = before ? before.length : 0
|
|
397
418
|
const posInContent = result.index + pos + beforeLength
|
|
398
|
-
if (this.
|
|
419
|
+
if (this.isWithinCodeSpanOrBlock(posInContent, content)) continue
|
|
399
420
|
var line = this.getLineNumber(posInContent)
|
|
400
421
|
if (self.hasTaskAtLine(line)) continue
|
|
401
422
|
if (!config.listExists(list)) continue
|
|
@@ -521,7 +542,6 @@ File.prototype.extractTasksInCodeFile = function (config) {
|
|
|
521
542
|
}
|
|
522
543
|
|
|
523
544
|
File.prototype.extractTasksInNonCodeFile = function (config) {
|
|
524
|
-
this.codeSpanAndBlockPositions = File.getCodePositions(this.getContent())
|
|
525
545
|
this.extractHashStyleTasks(config, 0, this.getContent())
|
|
526
546
|
this.extractLinkStyleTasks(config, 0, this.getContent())
|
|
527
547
|
this.extractCheckboxTasks(config, 0, this.getContent())
|
|
@@ -1105,27 +1125,6 @@ File.prototype.removeTask = function (task) {
|
|
|
1105
1125
|
}
|
|
1106
1126
|
}
|
|
1107
1127
|
|
|
1108
|
-
File.prototype.ignoreCodeBlocks = function () {
|
|
1109
|
-
// BACKLOG This is not used, but we need a way to ignore tasks in code blocks. Maybe save position ranges
|
|
1110
|
-
// ```javascript
|
|
1111
|
-
// var cleanContent = this.content
|
|
1112
|
-
// var replacer = function (block) {
|
|
1113
|
-
// block = block.replace(new XRegExp(LINK_STYLE_REGEX), '**TASK**')
|
|
1114
|
-
// block = block.replace(getHashStyleRegex(config.tokenPrefix), '**TASK**')
|
|
1115
|
-
// return block
|
|
1116
|
-
// }
|
|
1117
|
-
// if (this.isMarkDownFile()) {
|
|
1118
|
-
// cleanContent = this.content
|
|
1119
|
-
// .replace(new RegExp(CODE_BLOCK_REGEX), replacer)
|
|
1120
|
-
// .replace(new RegExp(INLINE_CODE_REGEX), replacer)
|
|
1121
|
-
// }
|
|
1122
|
-
// return cleanContent
|
|
1123
|
-
// ```
|
|
1124
|
-
// <!--
|
|
1125
|
-
// order:-640
|
|
1126
|
-
// -->
|
|
1127
|
-
}
|
|
1128
|
-
|
|
1129
1128
|
File.prototype.isMarkDownFile = function () {
|
|
1130
1129
|
return /^md|markdown$/i.test(this.getExt())
|
|
1131
1130
|
}
|
|
@@ -1345,19 +1344,9 @@ File.prototype.getSource = function () {
|
|
|
1345
1344
|
}
|
|
1346
1345
|
}
|
|
1347
1346
|
|
|
1348
|
-
File.
|
|
1349
|
-
const
|
|
1350
|
-
|
|
1351
|
-
let result
|
|
1352
|
-
while ((result = regex.exec(content)) !== null) {
|
|
1353
|
-
indicies.push([result.index, regex.lastIndex])
|
|
1354
|
-
}
|
|
1355
|
-
return indicies
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
File.prototype.hasCodeSpanOrBlockAtPos = function(pos) {
|
|
1359
|
-
const positions = this.codeSpanAndBlockPositions || File.getCodePositions(this.content)
|
|
1360
|
-
return positions.find(([start, end]) => pos > start && pos < end)
|
|
1347
|
+
File.prototype.isWithinCodeSpanOrBlock = function(pos, content) {
|
|
1348
|
+
const positions = Task.getMarkdownCodePositions(content)
|
|
1349
|
+
return Task.isResultInMarkdownCode(positions, pos)
|
|
1361
1350
|
}
|
|
1362
1351
|
|
|
1363
1352
|
module.exports = File
|
package/lib/migrate-config.js
CHANGED
|
@@ -109,6 +109,10 @@ module.exports = function (repo, defaultSettings = defaultSettingsObject) {
|
|
|
109
109
|
if (config.settings.cards.doneList === undefined) {
|
|
110
110
|
config.settings.cards.doneList = lists ? lists[lists.length - 1] : ''
|
|
111
111
|
}
|
|
112
|
+
// Set up default doingList
|
|
113
|
+
if (config.settings.cards.doingList === undefined) {
|
|
114
|
+
config.settings.cards.doingList = lists ? lists[lists.length - 1] : ''
|
|
115
|
+
}
|
|
112
116
|
// Add name
|
|
113
117
|
if (config.settings.name === undefined) {
|
|
114
118
|
config.settings.name = _path.basename(path)
|
|
@@ -12,6 +12,7 @@ module.exports = class DefaultCardPropertiesPlugin extends Plugin {
|
|
|
12
12
|
return {
|
|
13
13
|
date: `${getIsoDateWithOffset(new Date()).substring(0, 10)}`,
|
|
14
14
|
timestamp: getIsoDateWithOffset(new Date()),
|
|
15
|
+
clearFilterURL: self.getFilterURL(''),
|
|
15
16
|
getFilterURL: (filter) => self.getFilterURL(filter),
|
|
16
17
|
getFilterLink: (filter) => `[Filter By: ${filter}](${self.getFilterURL(filter)})`
|
|
17
18
|
}
|
package/lib/task.js
CHANGED
|
@@ -136,26 +136,17 @@ class Task {
|
|
|
136
136
|
|
|
137
137
|
getTextAndDescription() {
|
|
138
138
|
const description = _clone(this.description)
|
|
139
|
-
const
|
|
140
|
-
stripMeta: true,
|
|
141
|
-
sanitize: true,
|
|
142
|
-
stripTags: true,
|
|
143
|
-
stripContext: true,
|
|
144
|
-
})
|
|
145
|
-
const descriptionMD = description.map((line) => {
|
|
146
|
-
return this.getText(
|
|
147
|
-
{
|
|
148
|
-
stripMeta: true,
|
|
149
|
-
sanitize: true,
|
|
150
|
-
stripTags: true,
|
|
151
|
-
stripContext: true,
|
|
152
|
-
},
|
|
153
|
-
line
|
|
154
|
-
)
|
|
155
|
-
})
|
|
156
|
-
return `${this.markdownBeforeText}${text}${lineEnd}${descriptionMD.join(
|
|
139
|
+
const taskContent = `${this.markdownBeforeText}${this.text}${lineEnd}${description.join(
|
|
157
140
|
lineEnd
|
|
158
141
|
)}`.replace(/<!--\s*\[\s*([\s\S]*?)\s*\]\s*-->/gm, '$1')
|
|
142
|
+
return this.getText(
|
|
143
|
+
{
|
|
144
|
+
stripMeta: true,
|
|
145
|
+
sanitize: true,
|
|
146
|
+
stripTags: true,
|
|
147
|
+
stripContext: true,
|
|
148
|
+
},
|
|
149
|
+
taskContent);
|
|
159
150
|
}
|
|
160
151
|
|
|
161
152
|
getRawTextAndDescription() {
|
|
@@ -206,7 +197,7 @@ class Task {
|
|
|
206
197
|
})
|
|
207
198
|
}
|
|
208
199
|
}
|
|
209
|
-
const DATE_META_KEYS = Task.DATE_META_KEYS = ['due', 'defer', 'created', 'remind', 'completed', 'archivedAt']
|
|
200
|
+
const DATE_META_KEYS = Task.DATE_META_KEYS = ['due', 'defer', 'created', 'started', 'remind', 'completed', 'archivedAt']
|
|
210
201
|
|
|
211
202
|
Task.hasCheckPrefix = function (content) {
|
|
212
203
|
return new RegExp(CHECK_REGEX).test(content)
|
|
@@ -252,25 +243,44 @@ Task.getTagRegexp = function (prefix = '+') {
|
|
|
252
243
|
)
|
|
253
244
|
}
|
|
254
245
|
Task.getTags = function (text, prefix = '+') {
|
|
255
|
-
const tags = []
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
246
|
+
const tags = [];
|
|
247
|
+
const codePositions = Task.getMarkdownCodePositions(text);
|
|
248
|
+
const linkLabelPositions = Task.getMarkdownLinkLabelPositions(text);
|
|
249
|
+
let result;
|
|
250
|
+
const re = Task.getTagRegexp(prefix);
|
|
259
251
|
|
|
260
252
|
while ((result = re.exec(text)) !== null) {
|
|
261
|
-
if (Task.isResultInMarkdownCode(codePositions, result.index)) continue
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
tags.
|
|
253
|
+
if (Task.isResultInMarkdownCode(codePositions, result.index)) continue;
|
|
254
|
+
if (Task.isResultInMarkdownLinkLabel(linkLabelPositions, result.index)) continue;
|
|
255
|
+
const tag = result[2];
|
|
256
|
+
if (tags.includes(tag) || /^[#]+$/.test(tag)) continue;
|
|
257
|
+
tags.push(tag);
|
|
265
258
|
}
|
|
266
259
|
|
|
267
|
-
return tags
|
|
268
|
-
}
|
|
260
|
+
return tags;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
Task.getMarkdownLinkLabelPositions = function (text) {
|
|
264
|
+
const positions = [];
|
|
265
|
+
const re = /\[([^\]]+)\]\([^\)]+\)/g;
|
|
266
|
+
let match;
|
|
267
|
+
|
|
268
|
+
while ((match = re.exec(text)) !== null) {
|
|
269
|
+
positions.push({ start: match.index, end: re.lastIndex });
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return positions;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
Task.isResultInMarkdownLinkLabel = function (linkLabelPositions, index) {
|
|
276
|
+
return linkLabelPositions.some(pos => index >= pos.start && index < pos.end);
|
|
277
|
+
};
|
|
269
278
|
|
|
270
279
|
Task.ContextRegExp = new RegExp(
|
|
271
280
|
`(^|\\s)@([${Task.AnyLanguageGroup}${Task.EmojiGroup}]+)`,
|
|
272
281
|
'gmiu'
|
|
273
282
|
)
|
|
283
|
+
|
|
274
284
|
Task.getContext = function (text) {
|
|
275
285
|
const context = []
|
|
276
286
|
var codePositions = Task.getMarkdownCodePositions(text)
|
|
@@ -484,16 +494,16 @@ Task.isTask = function (task) {
|
|
|
484
494
|
}
|
|
485
495
|
|
|
486
496
|
Task.getMarkdownCodePositions = function (text) {
|
|
487
|
-
const re =
|
|
488
|
-
let result
|
|
489
|
-
let positions = []
|
|
497
|
+
const re = /(```[\s\S]*?```|`[^`]+`)/g;
|
|
498
|
+
let result;
|
|
499
|
+
let positions = [];
|
|
490
500
|
while ((result = re.exec(text)) !== null) {
|
|
491
|
-
const start = result.index
|
|
492
|
-
const end = start + result[0].length
|
|
493
|
-
positions.push({ start, end })
|
|
501
|
+
const start = result.index;
|
|
502
|
+
const end = start + result[0].length;
|
|
503
|
+
positions.push({ start, end });
|
|
494
504
|
}
|
|
495
|
-
return positions
|
|
496
|
-
}
|
|
505
|
+
return positions;
|
|
506
|
+
};
|
|
497
507
|
|
|
498
508
|
Task.isResultInMarkdownCode = function (positions, index) {
|
|
499
509
|
for (let i = 0; i < positions.length; i++) {
|
|
@@ -510,12 +520,15 @@ Task.prototype.parseTodoTxt = function () {
|
|
|
510
520
|
}
|
|
511
521
|
|
|
512
522
|
Task.removeTags = function (text, prefix = '+') {
|
|
513
|
-
const
|
|
523
|
+
const codePositions = Task.getMarkdownCodePositions(text);
|
|
524
|
+
const linkLabelPositions = Task.getMarkdownLinkLabelPositions(text);
|
|
514
525
|
return text.replace(Task.getTagRegexp(prefix), (match, p1, p2, offset) => {
|
|
515
|
-
if (Task.isResultInMarkdownCode(
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
526
|
+
if (Task.isResultInMarkdownCode(codePositions, offset) || Task.isResultInMarkdownLinkLabel(linkLabelPositions, offset) || match.includes('##')) {
|
|
527
|
+
return match;
|
|
528
|
+
}
|
|
529
|
+
return '';
|
|
530
|
+
});
|
|
531
|
+
};
|
|
519
532
|
|
|
520
533
|
Task.removeContext = function (text) {
|
|
521
534
|
const positions = Task.getMarkdownCodePositions(text)
|
|
@@ -714,7 +727,7 @@ Task.prototype.getList = function () {
|
|
|
714
727
|
// order:-700
|
|
715
728
|
// -->
|
|
716
729
|
Task.prototype.getText = function (opts, text) {
|
|
717
|
-
if (text === undefined)
|
|
730
|
+
if (text === undefined) return
|
|
718
731
|
if (opts) {
|
|
719
732
|
if (opts.stripMeta) {
|
|
720
733
|
text = Task.removeMetaDataFromText(this.config || {}, text)
|
|
@@ -733,14 +746,6 @@ Task.prototype.getText = function (opts, text) {
|
|
|
733
746
|
return text
|
|
734
747
|
}
|
|
735
748
|
|
|
736
|
-
Task.prototype.getDescription = function (opts) {
|
|
737
|
-
return this.description
|
|
738
|
-
.map((line) => {
|
|
739
|
-
return this.getText(opts, line)
|
|
740
|
-
})
|
|
741
|
-
.join(lineEnd)
|
|
742
|
-
}
|
|
743
|
-
|
|
744
749
|
Task.prototype.getChecksFromHtml = function (html) {
|
|
745
750
|
let $ = cheerio.load(html)
|
|
746
751
|
let checks = $('.task-description').find("input[type='checkbox']")
|
package/package.json
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Running a git remote in docker
|
|
2
|
-
|
|
3
|
-
[GitHub - 1nfiniteloop/git-remote: Docker image for a minimal git remote](https://github.com/1nfiniteloop/git-remote)
|
|
4
|
-
|
|
5
|
-
## setup the container before each test
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
./setup-remote.sh
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
The remote will remain running after the testing has completed
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
|
4
|
-
|
|
5
|
-
$SCRIPT_DIR/remove-remote.sh
|
|
6
|
-
|
|
7
|
-
docker run \
|
|
8
|
-
--name=git-remote \
|
|
9
|
-
--detach \
|
|
10
|
-
--publish 0.0.0.0:8022:22 \
|
|
11
|
-
--volume git-remote.home:/home/git \
|
|
12
|
-
--volume git-remote.host-keys:/etc/ssh/host_keys \
|
|
13
|
-
1nfiniteloop/git-remote:latest
|
|
14
|
-
|
|
15
|
-
docker exec git-remote mkdir /home/git/authorized_keys
|
|
16
|
-
|
|
17
|
-
# TODO Generate a key in the container and use that instead of copying the key from the host
|
|
18
|
-
# Update to use `GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example`
|
|
19
|
-
# <!--
|
|
20
|
-
# order:0
|
|
21
|
-
# -->
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
docker cp ~/.ssh/id_rsa.pub git-remote:/home/git/authorized_keys
|
|
25
|
-
|
|
26
|
-
echo "make authorized_keys owned by git"
|
|
27
|
-
docker exec git-remote chown -R git:git /home/git/authorized_keys/id_rsa.pub
|
|
28
|
-
docker exec git-remote chmod 777 /home/git/authorized_keys/id_rsa.pub
|
|
29
|
-
|
|
30
|
-
echo "create the test project"
|
|
31
|
-
docker exec git-remote su - git -s /bin/bash -c "mkdir /home/git/test-project.git; cd /home/git/test-project.git; git init --bare;"
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
keepEmptyPriority: true
|
|
2
|
-
code:
|
|
3
|
-
include_lists:
|
|
4
|
-
- TODO
|
|
5
|
-
- DOING
|
|
6
|
-
- DONE
|
|
7
|
-
- PLANNING
|
|
8
|
-
- FIXME
|
|
9
|
-
- ARCHIVE
|
|
10
|
-
- HACK
|
|
11
|
-
- CHANGED
|
|
12
|
-
- XXX
|
|
13
|
-
- IDEA
|
|
14
|
-
- NOTE
|
|
15
|
-
- REVIEW
|
|
16
|
-
- CURRENT
|
|
17
|
-
- BACKLOG
|
|
18
|
-
lists:
|
|
19
|
-
- name: BACKLOG
|
|
20
|
-
hidden: true
|
|
21
|
-
ignore: false
|
|
22
|
-
id: jea67colm3nm22s
|
|
23
|
-
- name: TODO
|
|
24
|
-
hidden: false
|
|
25
|
-
ignore: false
|
|
26
|
-
id: jea6phpllxpsj7j
|
|
27
|
-
- name: DOING
|
|
28
|
-
hidden: false
|
|
29
|
-
ignore: false
|
|
30
|
-
id: jea6phpllxpsj7k
|
|
31
|
-
- name: DONE
|
|
32
|
-
hidden: false
|
|
33
|
-
ignore: false
|
|
34
|
-
id: jea6phpllxpsj7l
|
|
35
|
-
settings:
|
|
36
|
-
openIn: default
|
|
37
|
-
customOpenIn: ''
|
|
38
|
-
editorTheme: blackboard
|
|
39
|
-
journalType: New File
|
|
40
|
-
journalPath: stories
|
|
41
|
-
appendNewCardsTo: imdone-tasks.md
|
|
42
|
-
newCardSyntax: HASHTAG
|
|
43
|
-
replaceSpacesWith: '-'
|
|
44
|
-
plugins:
|
|
45
|
-
devMode: false
|
|
46
|
-
CliBacklogPlugin:
|
|
47
|
-
projectType: BACKLOG_PROJECT
|
|
48
|
-
storyTemplate: |
|
|
49
|
-
# Story id
|
|
50
|
-
|
|
51
|
-
As a <role>, I want <feature>, so that <benefit>.
|
|
52
|
-
|
|
53
|
-
## Acceptance Criteria
|
|
54
|
-
|
|
55
|
-
- [ ] Criteria 1
|
|
56
|
-
- [ ] Criteria 2
|
|
57
|
-
|
|
58
|
-
## Tasks
|
|
59
|
-
|
|
60
|
-
### Phase One Tasks
|
|
61
|
-
|
|
62
|
-
- [ ] Task 1
|
|
63
|
-
|
|
64
|
-
### DoD
|
|
65
|
-
|
|
66
|
-
- [ ] Acceptance criteria are met
|
|
67
|
-
- [ ] Refactoring is complete
|
|
68
|
-
- [ ] Code builds with no error
|
|
69
|
-
- [ ] Unit tests are written and pass
|
|
70
|
-
- [ ] Existing Unit Tests pass
|
|
71
|
-
- [ ] Sufficient diagnostics/telemetry are logged
|
|
72
|
-
- [ ] Code review is complete
|
|
73
|
-
- [ ] UX review is complete (if applicable)
|
|
74
|
-
- [ ] Documentation is updated
|
|
75
|
-
- [ ] The feature is merged into the develop branch
|
|
76
|
-
- [ ] The feature is signed off by the product owner
|
|
77
|
-
journalTemplate: ''
|
|
78
|
-
theme: dark
|
|
79
|
-
views: []
|
|
80
|
-
name: backlog
|
|
81
|
-
cards:
|
|
82
|
-
colors: []
|
|
83
|
-
template: |
|
|
84
|
-
|
|
85
|
-
<!--
|
|
86
|
-
#story
|
|
87
|
-
created:${(new Date()).toISOString()}
|
|
88
|
-
task-id:${sid}
|
|
89
|
-
-->
|
|
90
|
-
trackChanges: false
|
|
91
|
-
metaNewLine: true
|
|
92
|
-
addCompletedMeta: true
|
|
93
|
-
addCheckBoxTasks: false
|
|
94
|
-
doneList: DONE
|
|
95
|
-
taskPrefix: '##'
|
|
96
|
-
tagPrefix: '#'
|
|
97
|
-
metaSep: ':'
|
|
98
|
-
orderMeta: true
|
|
99
|
-
maxLines: 6
|
|
100
|
-
addNewCardsToTop: true
|
|
101
|
-
defaultList: TODO
|
|
102
|
-
defaultFilter: allTags = "story"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# stories/**/tasks
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
keepEmptyPriority: true
|
|
2
|
-
code:
|
|
3
|
-
include_lists:
|
|
4
|
-
- TODO
|
|
5
|
-
- DOING
|
|
6
|
-
- DONE
|
|
7
|
-
- PLANNING
|
|
8
|
-
- FIXME
|
|
9
|
-
- ARCHIVE
|
|
10
|
-
- HACK
|
|
11
|
-
- CHANGED
|
|
12
|
-
- XXX
|
|
13
|
-
- IDEA
|
|
14
|
-
- NOTE
|
|
15
|
-
- REVIEW
|
|
16
|
-
- CURRENT
|
|
17
|
-
- BACKLOG
|
|
18
|
-
lists:
|
|
19
|
-
- name: TODO
|
|
20
|
-
hidden: false
|
|
21
|
-
ignore: false
|
|
22
|
-
id: jea6phpllxpsj7j
|
|
23
|
-
- name: DOING
|
|
24
|
-
hidden: false
|
|
25
|
-
ignore: false
|
|
26
|
-
id: jea6phpllxpsj7k
|
|
27
|
-
- name: DONE
|
|
28
|
-
hidden: false
|
|
29
|
-
ignore: false
|
|
30
|
-
id: jea6phpllxpsj7l
|
|
31
|
-
settings:
|
|
32
|
-
openIn: default
|
|
33
|
-
customOpenIn: ''
|
|
34
|
-
editorTheme: blackboard
|
|
35
|
-
journalType: New File
|
|
36
|
-
journalPath: tasks
|
|
37
|
-
appendNewCardsTo: imdone-tasks.md
|
|
38
|
-
newCardSyntax: HASHTAG
|
|
39
|
-
replaceSpacesWith: '-'
|
|
40
|
-
plugins:
|
|
41
|
-
devMode: false
|
|
42
|
-
CliBacklogPlugin:
|
|
43
|
-
projectType: STORY_PROJECT
|
|
44
|
-
journalTemplate: null
|
|
45
|
-
theme: dark
|
|
46
|
-
views: []
|
|
47
|
-
name: Add-a-command-to-show-defaults
|
|
48
|
-
defaultFilter: allTags = "task"
|
|
49
|
-
cards:
|
|
50
|
-
colors: []
|
|
51
|
-
template: |
|
|
52
|
-
|
|
53
|
-
<!--
|
|
54
|
-
#task
|
|
55
|
-
created:${(new Date()).toISOString()}
|
|
56
|
-
group:"${ungroupedTasks}"
|
|
57
|
-
story-id:${projectName}
|
|
58
|
-
task-id:${sid}
|
|
59
|
-
-->
|
|
60
|
-
trackChanges: false
|
|
61
|
-
metaNewLine: true
|
|
62
|
-
addCompletedMeta: true
|
|
63
|
-
addCheckBoxTasks: false
|
|
64
|
-
doneList: DONE
|
|
65
|
-
taskPrefix: '##'
|
|
66
|
-
tagPrefix: '#'
|
|
67
|
-
metaSep: ':'
|
|
68
|
-
orderMeta: true
|
|
69
|
-
maxLines: 6
|
|
70
|
-
addNewCardsToTop: true
|
|
71
|
-
defaultList: TODO
|