mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 03:20:12 +08:00
feat: add exceptions to stage
This commit is contained in:
1 parent
56d96cf7a0
commit
66ce015f0e
6 files changed
+86
-1
No files matched your search
@@ -28,5 +28,6 @@ module.exports = {
|
|||||||
'no-plusplus': 'off',
|
'no-plusplus': 'off',
|
||||||
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }],
|
'prettier/prettier': ['error', { endOfLine: 'auto', semi: false }],
|
||||||
'import/prefer-default-export': 'off',
|
'import/prefer-default-export': 'off',
|
||||||
|
'no-restricted-syntax': ['off', 'ForOfStatement'],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,26 @@ conditionSchema.add({
|
|||||||
not: conditionSchema,
|
not: conditionSchema,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const exceptionSchema = new Schema({
|
||||||
|
condition: {
|
||||||
|
type: conditionSchema,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
catchAll: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
responses: {
|
||||||
|
type: [responseSchema],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
hints: {
|
||||||
|
type: [String],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
const stageSchema = new Schema({
|
const stageSchema = new Schema({
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -66,6 +86,10 @@ const stageSchema = new Schema({
|
|||||||
type: [String],
|
type: [String],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
exceptions: {
|
||||||
|
type: [exceptionSchema],
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const Quest = model(
|
const Quest = model(
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
FROM linuxodyssey/quest-base
|
||||||
|
|
||||||
|
COPY home ${HOME}
|
||||||
+22
-1
@@ -1,6 +1,27 @@
|
|||||||
title: 複製檔案
|
title: 複製檔案
|
||||||
instruction: |
|
instruction: |
|
||||||
複製檔案
|
在這個關卡中,你將學習如何複製檔案。
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- create
|
- create
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- id: start
|
||||||
|
task: 輸入 `echo start` 來開始
|
||||||
|
condition:
|
||||||
|
output:
|
||||||
|
- start
|
||||||
|
exceptions:
|
||||||
|
- condition:
|
||||||
|
command:
|
||||||
|
- ^echo$
|
||||||
|
responses:
|
||||||
|
- type: narrative
|
||||||
|
content:
|
||||||
|
- 你忘記輸入 `start` 了嗎?
|
||||||
|
- 請輸入 `echo start` 來開始
|
||||||
|
- catchAll: true
|
||||||
|
responses:
|
||||||
|
- type: narrative
|
||||||
|
content:
|
||||||
|
- 請輸入 `echo start` 來開始
|
||||||
@@ -97,6 +97,19 @@ export default class CommandHandler extends SessionHandler {
|
|||||||
return matches.some((m) => m === true)
|
return matches.some((m) => m === true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async checkException(stage) {
|
||||||
|
const exceptions = stage.exceptions || []
|
||||||
|
for (const exception of exceptions) {
|
||||||
|
console.log(exception)
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
if (exception.condition && (await this.isMatch(exception.condition))) {
|
||||||
|
return exception
|
||||||
|
}
|
||||||
|
if (exception.catchAll) return exception
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
async run() {
|
async run() {
|
||||||
this.quest = await Quest.findById(this.session.quest)
|
this.quest = await Quest.findById(this.session.quest)
|
||||||
const stages = this.getStages()
|
const stages = this.getStages()
|
||||||
@@ -114,6 +127,14 @@ export default class CommandHandler extends SessionHandler {
|
|||||||
|
|
||||||
const stage = stages.find((_, i) => matches[i])
|
const stage = stages.find((_, i) => matches[i])
|
||||||
if (!stage) {
|
if (!stage) {
|
||||||
|
for (const s of stages) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const exception = await this.checkException(s)
|
||||||
|
if (exception) {
|
||||||
|
console.log('Got exception', exception)
|
||||||
|
return this.executeException(exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
const response = this.execute(stage)
|
const response = this.execute(stage)
|
||||||
|
|||||||
@@ -63,4 +63,19 @@ export default class SessionHandler {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
executeException(exception) {
|
||||||
|
const { hints, responses } = exception
|
||||||
|
if (hints && hints.length > 0) this.session.hints.push(hints)
|
||||||
|
|
||||||
|
return {
|
||||||
|
responses,
|
||||||
|
hints,
|
||||||
|
callback: () => {
|
||||||
|
if (hints && hints.length > 0)
|
||||||
|
pushToSession(this.session.id, 'hints', hints)
|
||||||
|
pushToSession(this.session.id, 'status', this.session.status)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user