@forgehive/forge-cli 0.2.13 → 0.3.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/dist/runner.js +15 -7
- package/dist/tasks/auth/add.js +23 -19
- package/dist/tasks/auth/list.js +20 -16
- package/dist/tasks/auth/load.js +19 -15
- package/dist/tasks/auth/loadCurrent.js +13 -9
- package/dist/tasks/auth/remove.js +30 -26
- package/dist/tasks/auth/switch.js +19 -15
- package/dist/tasks/bundle/create.js +16 -12
- package/dist/tasks/bundle/fingerprint.d.ts +36 -0
- package/dist/tasks/bundle/fingerprint.js +164 -0
- package/dist/tasks/bundle/load.js +9 -5
- package/dist/tasks/bundle/zip.js +49 -45
- package/dist/tasks/conf/info.js +23 -19
- package/dist/tasks/conf/load.js +8 -4
- package/dist/tasks/fixture/download.js +40 -36
- package/dist/tasks/init.js +35 -31
- package/dist/tasks/runner/bundle.js +34 -30
- package/dist/tasks/runner/create.js +28 -24
- package/dist/tasks/runner/remove.js +22 -18
- package/dist/tasks/task/createTask.js +35 -28
- package/dist/tasks/task/describe.d.ts +35 -0
- package/dist/tasks/task/describe.js +130 -0
- package/dist/tasks/task/download.js +63 -59
- package/dist/tasks/task/fingerprint.d.ts +26 -0
- package/dist/tasks/task/fingerprint.js +87 -0
- package/dist/tasks/task/list.d.ts +12 -0
- package/dist/tasks/task/list.js +46 -0
- package/dist/tasks/task/publish.js +72 -68
- package/dist/tasks/task/remove.js +24 -20
- package/dist/tasks/task/replay.js +94 -90
- package/dist/tasks/task/run.js +84 -79
- package/dist/test/setup.d.ts +0 -0
- package/dist/test/setup.js +14 -0
- package/dist/test/tasks/create.test.js +6 -5
- package/dist/utils/taskAnalysis.d.ts +21 -0
- package/dist/utils/taskAnalysis.js +380 -0
- package/forge.json +20 -0
- package/jest.config.js +2 -1
- package/logs/task:fingerprint.log +10 -0
- package/package.json +8 -8
- package/specs/fingerprint.md +380 -0
- package/src/runner.ts +14 -5
- package/src/tasks/README.md +13 -13
- package/src/tasks/auth/add.ts +3 -3
- package/src/tasks/auth/list.ts +3 -3
- package/src/tasks/auth/load.ts +3 -3
- package/src/tasks/auth/loadCurrent.ts +3 -3
- package/src/tasks/auth/remove.ts +3 -3
- package/src/tasks/auth/switch.ts +3 -3
- package/src/tasks/bundle/README.md +7 -7
- package/src/tasks/bundle/create.ts +4 -4
- package/src/tasks/bundle/fingerprint.ts +218 -0
- package/src/tasks/bundle/load.ts +4 -4
- package/src/tasks/bundle/zip.ts +3 -3
- package/src/tasks/conf/info.ts +3 -3
- package/src/tasks/conf/load.ts +3 -3
- package/src/tasks/fixture/download.ts +3 -3
- package/src/tasks/init.ts +3 -3
- package/src/tasks/runner/bundle.ts +3 -3
- package/src/tasks/runner/create.ts +3 -3
- package/src/tasks/runner/remove.ts +3 -3
- package/src/tasks/task/createTask.ts +10 -7
- package/src/tasks/task/describe.ts +148 -0
- package/src/tasks/task/download.ts +3 -3
- package/src/tasks/task/fingerprint.ts +107 -0
- package/src/tasks/task/list.ts +58 -0
- package/src/tasks/task/publish.ts +3 -3
- package/src/tasks/task/remove.ts +3 -3
- package/src/tasks/task/replay.ts +3 -3
- package/src/tasks/task/run.ts +5 -4
- package/src/test/setup.ts +14 -0
- package/src/test/tasks/create.test.ts +9 -9
- package/src/utils/taskAnalysis.ts +419 -0
- package/dist/taskAdapter.d.ts +0 -34
- package/dist/taskAdapter.js +0 -85
- package/dist/templates/README.md +0 -23
- package/dist/templates/task.hbs +0 -27
- package/dist/test/utils.d.ts +0 -2
- package/dist/test/utils.js +0 -17
- package/logs/auth:list.log +0 -4
- package/logs/auth:load.log +0 -2
- package/logs/auth:loadCurrent.log +0 -1
- package/logs/conf:info.log +0 -2
- package/logs/runner:create.log +0 -4
|
@@ -69,10 +69,10 @@ const boundaries = {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
export const create = createTask(
|
|
72
|
+
export const create = createTask({
|
|
73
73
|
schema,
|
|
74
74
|
boundaries,
|
|
75
|
-
async function ({ runnerName }, {
|
|
75
|
+
fn: async function ({ runnerName }, {
|
|
76
76
|
persistRunner,
|
|
77
77
|
loadConf,
|
|
78
78
|
persistConf,
|
|
@@ -118,4 +118,4 @@ export const create = createTask(
|
|
|
118
118
|
runnerName: formattedName
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
-
)
|
|
121
|
+
})
|
|
@@ -32,10 +32,10 @@ const boundaries = {
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export const remove = createTask(
|
|
35
|
+
export const remove = createTask({
|
|
36
36
|
schema,
|
|
37
37
|
boundaries,
|
|
38
|
-
async function ({ runnerName }, {
|
|
38
|
+
fn: async function ({ runnerName }, {
|
|
39
39
|
loadConf,
|
|
40
40
|
getCwd,
|
|
41
41
|
removeRunner,
|
|
@@ -71,4 +71,4 @@ export const remove = createTask(
|
|
|
71
71
|
runnerName: formattedName
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
)
|
|
74
|
+
})
|
|
@@ -18,6 +18,7 @@ const TASK_TEMPLATE = `// TASK: {{ taskName }}
|
|
|
18
18
|
import { createTask } from '@forgehive/task'
|
|
19
19
|
import { Schema } from '@forgehive/schema'
|
|
20
20
|
|
|
21
|
+
const name = '{{ taskDescriptor }}'
|
|
21
22
|
const description = 'Add task description here'
|
|
22
23
|
|
|
23
24
|
const schema = new Schema({
|
|
@@ -30,10 +31,12 @@ const boundaries = {
|
|
|
30
31
|
// example: readFile: async (path: string) => fs.readFile(path, 'utf-8')
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
export const {{ taskName }} = createTask(
|
|
34
|
+
export const {{ taskName }} = createTask({
|
|
35
|
+
name,
|
|
36
|
+
description,
|
|
34
37
|
schema,
|
|
35
38
|
boundaries,
|
|
36
|
-
async function (argv, boundaries) {
|
|
39
|
+
fn: async function (argv, boundaries) {
|
|
37
40
|
console.log('input:', argv)
|
|
38
41
|
console.log('boundaries:', boundaries)
|
|
39
42
|
// Your task implementation goes here
|
|
@@ -41,9 +44,8 @@ export const {{ taskName }} = createTask(
|
|
|
41
44
|
|
|
42
45
|
return status
|
|
43
46
|
}
|
|
44
|
-
)
|
|
47
|
+
})
|
|
45
48
|
|
|
46
|
-
{{ taskName }}.setDescription(description)
|
|
47
49
|
`
|
|
48
50
|
|
|
49
51
|
const schema = new Schema({
|
|
@@ -107,10 +109,10 @@ const boundaries = {
|
|
|
107
109
|
}
|
|
108
110
|
}
|
|
109
111
|
|
|
110
|
-
export const createTaskCommand = createTask(
|
|
112
|
+
export const createTaskCommand = createTask({
|
|
111
113
|
schema,
|
|
112
114
|
boundaries,
|
|
113
|
-
async function ({ descriptorName }, {
|
|
115
|
+
fn: async function ({ descriptorName }, {
|
|
114
116
|
loadTemplate,
|
|
115
117
|
persistTask,
|
|
116
118
|
loadConf,
|
|
@@ -132,6 +134,7 @@ export const createTaskCommand = createTask(
|
|
|
132
134
|
==================================================
|
|
133
135
|
Starting task creation!
|
|
134
136
|
Creating: ${taskName}
|
|
137
|
+
Descriptor: ${descriptor}
|
|
135
138
|
Dir: ${dir ?? ''}
|
|
136
139
|
Into: ${taskPath}
|
|
137
140
|
==================================================
|
|
@@ -159,4 +162,4 @@ export const createTaskCommand = createTask(
|
|
|
159
162
|
|
|
160
163
|
return { taskPath, fileName }
|
|
161
164
|
}
|
|
162
|
-
)
|
|
165
|
+
})
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
// TASK: describe
|
|
2
|
+
// Run this task with:
|
|
3
|
+
// forge task:run task:describe
|
|
4
|
+
|
|
5
|
+
import path from 'path'
|
|
6
|
+
import os from 'os'
|
|
7
|
+
import fs from 'fs/promises'
|
|
8
|
+
|
|
9
|
+
import { createTask } from '@forgehive/task'
|
|
10
|
+
import { Schema } from '@forgehive/schema'
|
|
11
|
+
|
|
12
|
+
import { create as bundleCreate } from '../bundle/create'
|
|
13
|
+
import { load as bundleLoad } from '../bundle/load'
|
|
14
|
+
import { load as loadConf } from '../conf/load'
|
|
15
|
+
import { type ForgeConf } from '../types'
|
|
16
|
+
|
|
17
|
+
const description = 'Describe a task with detailed information about its schema, boundaries and configuration'
|
|
18
|
+
|
|
19
|
+
const schema = new Schema({
|
|
20
|
+
descriptorName: Schema.string()
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const boundaries = {
|
|
24
|
+
loadConf: loadConf.asBoundary(),
|
|
25
|
+
bundleCreate: bundleCreate.asBoundary(),
|
|
26
|
+
bundleLoad: bundleLoad.asBoundary(),
|
|
27
|
+
ensureBuildsFolder: async (): Promise<string> => {
|
|
28
|
+
const buildsPath = path.join(os.homedir(), '.forge', 'builds')
|
|
29
|
+
try {
|
|
30
|
+
await fs.access(buildsPath)
|
|
31
|
+
} catch {
|
|
32
|
+
await fs.mkdir(buildsPath, { recursive: true })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return buildsPath
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const describe = createTask({
|
|
40
|
+
schema,
|
|
41
|
+
boundaries,
|
|
42
|
+
fn: async function ({ descriptorName }, {
|
|
43
|
+
loadConf,
|
|
44
|
+
bundleCreate,
|
|
45
|
+
bundleLoad,
|
|
46
|
+
ensureBuildsFolder
|
|
47
|
+
}) {
|
|
48
|
+
// Load forge configuration
|
|
49
|
+
const forge: ForgeConf = await loadConf({})
|
|
50
|
+
const taskDescriptor = forge.tasks[descriptorName as keyof typeof forge.tasks]
|
|
51
|
+
|
|
52
|
+
if (taskDescriptor === undefined) {
|
|
53
|
+
throw new Error(`Task "${descriptorName}" is not defined in forge.json`)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Prepare paths
|
|
57
|
+
const entryPoint = path.join(process.cwd(), taskDescriptor.path)
|
|
58
|
+
const buildsPath = await ensureBuildsFolder()
|
|
59
|
+
const outputFile = path.join(buildsPath, `${descriptorName}.js`)
|
|
60
|
+
|
|
61
|
+
// Bundle the task
|
|
62
|
+
await bundleCreate({
|
|
63
|
+
entryPoint,
|
|
64
|
+
outputFile
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
// Load the bundled task
|
|
68
|
+
const bundle = await bundleLoad({
|
|
69
|
+
bundlePath: outputFile
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// Get the task handler
|
|
73
|
+
const task = bundle[taskDescriptor.handler]
|
|
74
|
+
|
|
75
|
+
if (!task) {
|
|
76
|
+
throw new Error(`Handler "${taskDescriptor.handler}" not found in bundle`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log('===============================================')
|
|
80
|
+
console.log(`Task: ${descriptorName}`)
|
|
81
|
+
console.log('===============================================')
|
|
82
|
+
console.log(`Path: ${taskDescriptor.path}`)
|
|
83
|
+
console.log(`Handler: ${taskDescriptor.handler}`)
|
|
84
|
+
|
|
85
|
+
// Get task description
|
|
86
|
+
const taskDescription = task.getDescription?.() || 'No description available'
|
|
87
|
+
console.log(`Description: ${taskDescription}`)
|
|
88
|
+
|
|
89
|
+
console.log('')
|
|
90
|
+
console.log('Schema:')
|
|
91
|
+
console.log('-------')
|
|
92
|
+
|
|
93
|
+
// Get schema information
|
|
94
|
+
const taskSchema = task.getSchema?.()
|
|
95
|
+
if (taskSchema && taskSchema.shape) {
|
|
96
|
+
const schemaKeys = Object.keys(taskSchema.shape)
|
|
97
|
+
if (schemaKeys.length === 0) {
|
|
98
|
+
console.log(' No schema parameters defined')
|
|
99
|
+
} else {
|
|
100
|
+
schemaKeys.forEach(key => {
|
|
101
|
+
const field = taskSchema.shape[key]
|
|
102
|
+
const fieldType = field.type || 'unknown'
|
|
103
|
+
const fieldDescription = field.description || ''
|
|
104
|
+
|
|
105
|
+
if (fieldDescription) {
|
|
106
|
+
console.log(` • ${key} (${fieldType}): ${fieldDescription}`)
|
|
107
|
+
} else {
|
|
108
|
+
console.log(` • ${key} (${fieldType})`)
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
console.log(' No schema information available')
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
console.log('')
|
|
117
|
+
console.log('Boundaries:')
|
|
118
|
+
console.log('-----------')
|
|
119
|
+
|
|
120
|
+
// Get boundaries information
|
|
121
|
+
const taskBoundaries = task.getBoundaries?.()
|
|
122
|
+
if (taskBoundaries) {
|
|
123
|
+
const boundaryKeys = Object.keys(taskBoundaries)
|
|
124
|
+
if (boundaryKeys.length === 0) {
|
|
125
|
+
console.log(' No boundaries defined')
|
|
126
|
+
} else {
|
|
127
|
+
boundaryKeys.forEach(boundaryName => {
|
|
128
|
+
console.log(` • ${boundaryName}`)
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
console.log(' No boundary information available')
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
console.log('===============================================')
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
name: descriptorName,
|
|
139
|
+
path: taskDescriptor.path,
|
|
140
|
+
handler: taskDescriptor.handler,
|
|
141
|
+
description: taskDescription,
|
|
142
|
+
schema: taskSchema?.shape || {},
|
|
143
|
+
boundaries: taskBoundaries ? Object.keys(taskBoundaries) : []
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
describe.setDescription(description)
|
|
@@ -90,10 +90,10 @@ const boundaries = {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
export const download = createTask(
|
|
93
|
+
export const download = createTask({
|
|
94
94
|
schema,
|
|
95
95
|
boundaries,
|
|
96
|
-
async function ({ descriptorName, uuid }, {
|
|
96
|
+
fn: async function ({ descriptorName, uuid }, {
|
|
97
97
|
downloadTask,
|
|
98
98
|
getCwd,
|
|
99
99
|
parseTaskName,
|
|
@@ -189,4 +189,4 @@ export const download = createTask(
|
|
|
189
189
|
handler: response.handler
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
)
|
|
192
|
+
})
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// TASK: fingerprint
|
|
2
|
+
// Run this task with:
|
|
3
|
+
// forge task:run task:fingerprint --descriptorName task-name
|
|
4
|
+
|
|
5
|
+
import { createTask } from '@forgehive/task'
|
|
6
|
+
import { Schema } from '@forgehive/schema'
|
|
7
|
+
import fs from 'fs/promises'
|
|
8
|
+
import path from 'path'
|
|
9
|
+
import os from 'os'
|
|
10
|
+
|
|
11
|
+
import { load as loadConf } from '../conf/load'
|
|
12
|
+
import { analyzeTaskFile, TaskFingerprintOutput } from '../../utils/taskAnalysis'
|
|
13
|
+
|
|
14
|
+
interface FingerprintAnalysis {
|
|
15
|
+
taskFingerprint: TaskFingerprintOutput
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const description = 'Analyze a specific task and generate detailed fingerprint without bundling'
|
|
19
|
+
|
|
20
|
+
const schema = new Schema({
|
|
21
|
+
descriptorName: Schema.string()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
const boundaries = {
|
|
25
|
+
getCwd: async (): Promise<string> => {
|
|
26
|
+
return process.cwd()
|
|
27
|
+
},
|
|
28
|
+
loadConf: loadConf.asBoundary(),
|
|
29
|
+
readFile: async (filePath: string): Promise<string> => {
|
|
30
|
+
return fs.readFile(filePath, 'utf-8')
|
|
31
|
+
},
|
|
32
|
+
writeFile: async (filePath: string, content: string): Promise<void> => {
|
|
33
|
+
return fs.writeFile(filePath, content)
|
|
34
|
+
},
|
|
35
|
+
ensureForgeFolder: async (): Promise<string> => {
|
|
36
|
+
const forgePath = path.join(os.homedir(), '.forge')
|
|
37
|
+
try {
|
|
38
|
+
await fs.access(forgePath)
|
|
39
|
+
} catch {
|
|
40
|
+
await fs.mkdir(forgePath, { recursive: true })
|
|
41
|
+
}
|
|
42
|
+
return forgePath
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const fingerprint = createTask({
|
|
47
|
+
schema,
|
|
48
|
+
boundaries,
|
|
49
|
+
fn: async function ({ descriptorName }, {
|
|
50
|
+
getCwd,
|
|
51
|
+
loadConf,
|
|
52
|
+
readFile,
|
|
53
|
+
writeFile,
|
|
54
|
+
ensureForgeFolder
|
|
55
|
+
}) {
|
|
56
|
+
const cwd = await getCwd()
|
|
57
|
+
const forgeJson = await loadConf({})
|
|
58
|
+
|
|
59
|
+
const taskDescriptor = forgeJson.tasks[descriptorName as keyof typeof forgeJson.tasks]
|
|
60
|
+
|
|
61
|
+
if (taskDescriptor === undefined) {
|
|
62
|
+
throw new Error(`Task "${descriptorName}" is not defined in forge.json`)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const filePath = path.join(cwd, taskDescriptor.path)
|
|
66
|
+
const forgePath = await ensureForgeFolder()
|
|
67
|
+
const fingerprintFile = path.join(forgePath, `${descriptorName}.task-fingerprint.json`)
|
|
68
|
+
|
|
69
|
+
console.log(`Analyzing task: ${descriptorName}`)
|
|
70
|
+
console.log(`Task file: ${filePath}`)
|
|
71
|
+
|
|
72
|
+
// Read and analyze the task file using the utility function
|
|
73
|
+
const sourceCode = await readFile(filePath)
|
|
74
|
+
const taskFingerprint = analyzeTaskFile(sourceCode, filePath)
|
|
75
|
+
|
|
76
|
+
if (!taskFingerprint) {
|
|
77
|
+
throw new Error('Could not extract fingerprint from task file: ' + filePath)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Create analysis result - clean output without extra fields
|
|
81
|
+
const analysis: FingerprintAnalysis = {
|
|
82
|
+
taskFingerprint
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Write fingerprint to file
|
|
86
|
+
await writeFile(fingerprintFile, JSON.stringify(analysis, null, 2))
|
|
87
|
+
|
|
88
|
+
console.log('Task fingerprint generated successfully')
|
|
89
|
+
console.log(`Input properties: ${Object.keys(taskFingerprint.inputSchema.properties).join(', ')}`)
|
|
90
|
+
console.log(`Boundaries: ${taskFingerprint.boundaries.join(', ')}`)
|
|
91
|
+
console.log(`Fingerprint saved to: ${fingerprintFile}`)
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
taskName: descriptorName,
|
|
95
|
+
fingerprint: taskFingerprint,
|
|
96
|
+
fingerprintFile,
|
|
97
|
+
analysis: {
|
|
98
|
+
inputSchemaProps: Object.keys(taskFingerprint.inputSchema.properties),
|
|
99
|
+
boundaryCount: taskFingerprint.boundaries.length,
|
|
100
|
+
hasDescription: !!taskFingerprint.description,
|
|
101
|
+
outputType: taskFingerprint.outputType.type
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
fingerprint.setDescription(description)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// TASK: list
|
|
2
|
+
// Run this task with:
|
|
3
|
+
// forge task:run task:list
|
|
4
|
+
|
|
5
|
+
import { createTask } from '@forgehive/task'
|
|
6
|
+
import { Schema } from '@forgehive/schema'
|
|
7
|
+
|
|
8
|
+
import { load as loadConf } from '../conf/load'
|
|
9
|
+
import { type ForgeConf } from '../types'
|
|
10
|
+
|
|
11
|
+
const description = 'List all available tasks in the current project'
|
|
12
|
+
|
|
13
|
+
const schema = new Schema({
|
|
14
|
+
// No arguments needed
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const boundaries = {
|
|
18
|
+
loadConf: loadConf.asBoundary()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const list = createTask({
|
|
22
|
+
schema,
|
|
23
|
+
boundaries,
|
|
24
|
+
fn: async function (argv, { loadConf }) {
|
|
25
|
+
// Load forge configuration
|
|
26
|
+
const forge: ForgeConf = await loadConf({})
|
|
27
|
+
|
|
28
|
+
console.log('Available tasks:')
|
|
29
|
+
console.log('===============================================')
|
|
30
|
+
|
|
31
|
+
const tasks = forge.tasks
|
|
32
|
+
const taskNames = Object.keys(tasks).sort()
|
|
33
|
+
|
|
34
|
+
if (taskNames.length === 0) {
|
|
35
|
+
console.log('No tasks found in forge.json')
|
|
36
|
+
return { taskCount: 0, tasks: [] }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Find the longest task name for alignment
|
|
40
|
+
const maxNameLength = Math.max(...taskNames.map(name => name.length))
|
|
41
|
+
|
|
42
|
+
taskNames.forEach((taskName) => {
|
|
43
|
+
const task = tasks[taskName]
|
|
44
|
+
const paddedName = taskName.padEnd(maxNameLength + 1)
|
|
45
|
+
console.log(`• ${paddedName} - ${task.path}`)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
console.log('===============================================')
|
|
49
|
+
console.log('Total tasks: ', taskNames.length)
|
|
50
|
+
console.log('===============================================')
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
taskCount: taskNames.length
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
list.setDescription(description)
|
|
@@ -81,10 +81,10 @@ const boundaries = {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
export const publish = createTask(
|
|
84
|
+
export const publish = createTask({
|
|
85
85
|
schema,
|
|
86
86
|
boundaries,
|
|
87
|
-
async function ({ descriptorName }, {
|
|
87
|
+
fn: async function ({ descriptorName }, {
|
|
88
88
|
getCwd,
|
|
89
89
|
ensureBuildsFolder,
|
|
90
90
|
loadConf,
|
|
@@ -184,4 +184,4 @@ export const publish = createTask(
|
|
|
184
184
|
throw new Error('Bundle upload failed')
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
|
-
)
|
|
187
|
+
})
|
package/src/tasks/task/remove.ts
CHANGED
|
@@ -25,10 +25,10 @@ const boundaries = {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export const remove = createTask(
|
|
28
|
+
export const remove = createTask({
|
|
29
29
|
schema,
|
|
30
30
|
boundaries,
|
|
31
|
-
async function ({ descriptorName }, { loadConf, persistConf, deleteFile }) {
|
|
31
|
+
fn: async function ({ descriptorName }, { loadConf, persistConf, deleteFile }) {
|
|
32
32
|
// Load shadow configuration
|
|
33
33
|
const forge: ForgeConf = await loadConf({})
|
|
34
34
|
|
|
@@ -61,4 +61,4 @@ export const remove = createTask(
|
|
|
61
61
|
message: `Task '${descriptorName}' has been successfully removed`
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
)
|
|
64
|
+
})
|
package/src/tasks/task/replay.ts
CHANGED
|
@@ -96,10 +96,10 @@ const boundaries = {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
export const replay = createTask(
|
|
99
|
+
export const replay = createTask({
|
|
100
100
|
schema,
|
|
101
101
|
boundaries,
|
|
102
|
-
async function ({ descriptorName, path: fixturePath, cache }, { readFixture, loadConf, loadCurrentProfile, bundleCreate, bundleLoad, ensureBuildsFolder, verifyLogFolder, sendLogToAPI }) {
|
|
102
|
+
fn: async function ({ descriptorName, path: fixturePath, cache }, { readFixture, loadConf, loadCurrentProfile, bundleCreate, bundleLoad, ensureBuildsFolder, verifyLogFolder, sendLogToAPI }) {
|
|
103
103
|
console.log('Input descriptorName:', descriptorName)
|
|
104
104
|
console.log('Input path:', fixturePath)
|
|
105
105
|
console.log('Input cache:', cache)
|
|
@@ -215,6 +215,6 @@ export const replay = createTask(
|
|
|
215
215
|
|
|
216
216
|
return result
|
|
217
217
|
}
|
|
218
|
-
)
|
|
218
|
+
})
|
|
219
219
|
|
|
220
220
|
replay.setDescription(description)
|
package/src/tasks/task/run.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// TASK: run
|
|
2
2
|
// Run this task with:
|
|
3
|
-
//
|
|
3
|
+
// most recursive call on the project
|
|
4
|
+
// forge task:run task:run
|
|
4
5
|
|
|
5
6
|
import path from 'path'
|
|
6
7
|
import fs from 'fs/promises'
|
|
@@ -78,10 +79,10 @@ const boundaries = {
|
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
export const run = createTask(
|
|
82
|
+
export const run = createTask({
|
|
82
83
|
schema,
|
|
83
84
|
boundaries,
|
|
84
|
-
async function ({ descriptorName, args }, {
|
|
85
|
+
fn: async function ({ descriptorName, args }, {
|
|
85
86
|
loadConf,
|
|
86
87
|
bundleCreate,
|
|
87
88
|
bundleLoad,
|
|
@@ -187,4 +188,4 @@ export const run = createTask(
|
|
|
187
188
|
|
|
188
189
|
return result
|
|
189
190
|
}
|
|
190
|
-
)
|
|
191
|
+
})
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Global test setup - mocks for problematic ES modules
|
|
2
|
+
|
|
3
|
+
// Mock archiver to avoid ES module issues
|
|
4
|
+
jest.mock('archiver', () => ({
|
|
5
|
+
__esModule: true,
|
|
6
|
+
default: jest.fn(() => ({
|
|
7
|
+
pipe: jest.fn(),
|
|
8
|
+
finalize: jest.fn(),
|
|
9
|
+
directory: jest.fn(),
|
|
10
|
+
file: jest.fn(),
|
|
11
|
+
on: jest.fn(),
|
|
12
|
+
pointer: jest.fn(() => 0)
|
|
13
|
+
}))
|
|
14
|
+
}))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createTaskCommand } from '../../tasks/task/createTask'
|
|
2
|
-
import { createFsFromVolume, Volume } from 'memfs'
|
|
2
|
+
import { createFsFromVolume, Volume, type IFs } from 'memfs'
|
|
3
3
|
import path from 'path'
|
|
4
4
|
import { createMockBoundary } from '../testUtils'
|
|
5
5
|
import { ForgeConf } from '../../tasks/types'
|
|
@@ -12,6 +12,7 @@ const expectedContent = `// TASK: newTask
|
|
|
12
12
|
import { createTask } from '@forgehive/task'
|
|
13
13
|
import { Schema } from '@forgehive/schema'
|
|
14
14
|
|
|
15
|
+
const name = 'sample:newTask'
|
|
15
16
|
const description = 'Add task description here'
|
|
16
17
|
|
|
17
18
|
const schema = new Schema({
|
|
@@ -24,10 +25,12 @@ const boundaries = {
|
|
|
24
25
|
// example: readFile: async (path: string) => fs.readFile(path, 'utf-8')
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
export const newTask = createTask(
|
|
28
|
+
export const newTask = createTask({
|
|
29
|
+
name,
|
|
30
|
+
description,
|
|
28
31
|
schema,
|
|
29
32
|
boundaries,
|
|
30
|
-
async function (argv, boundaries) {
|
|
33
|
+
fn: async function (argv, boundaries) {
|
|
31
34
|
console.log('input:', argv)
|
|
32
35
|
console.log('boundaries:', boundaries)
|
|
33
36
|
// Your task implementation goes here
|
|
@@ -35,15 +38,13 @@ export const newTask = createTask(
|
|
|
35
38
|
|
|
36
39
|
return status
|
|
37
40
|
}
|
|
38
|
-
)
|
|
41
|
+
})
|
|
39
42
|
|
|
40
|
-
newTask.setDescription(description)
|
|
41
43
|
`
|
|
42
44
|
|
|
43
45
|
describe('Create task', () => {
|
|
44
46
|
let volume: InstanceType<typeof Volume>
|
|
45
|
-
|
|
46
|
-
let fs: any
|
|
47
|
+
let fs: IFs
|
|
47
48
|
let rootDir: string
|
|
48
49
|
|
|
49
50
|
beforeEach(() => {
|
|
@@ -96,11 +97,10 @@ describe('Create task', () => {
|
|
|
96
97
|
|
|
97
98
|
// Read the created task file
|
|
98
99
|
const fileContent = await fs.promises.readFile(path.join(rootDir, 'src/tasks/sample', 'newTask.ts'), 'utf-8')
|
|
99
|
-
|
|
100
100
|
expect(fileContent).toBe(expectedContent)
|
|
101
101
|
|
|
102
102
|
// Read the updated forge.json
|
|
103
|
-
const forgeContent = await fs.promises.readFile(path.join(rootDir, 'forge.json'), 'utf-8')
|
|
103
|
+
const forgeContent = await fs.promises.readFile(path.join(rootDir, 'forge.json'), 'utf-8') as string
|
|
104
104
|
const forgeConf = JSON.parse(forgeContent)
|
|
105
105
|
expect(forgeConf.tasks['sample:newTask']).toBeDefined()
|
|
106
106
|
})
|