adapt-migrations 1.0.0 → 1.2.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/.eslintignore +1 -1
- package/.eslintrc.json +14 -14
- package/README.md +106 -43
- package/api/commands.js +33 -33
- package/api/data.js +26 -26
- package/api/describe.js +12 -12
- package/api/errors.js +28 -28
- package/api/helpers.js +17 -0
- package/api/plugins.js +47 -44
- package/api/tests.js +57 -57
- package/api/where.js +46 -46
- package/examples/migrations.js +159 -159
- package/examples/script.js +78 -78
- package/index.js +70 -62
- package/lib/CacheManager.js +95 -95
- package/lib/Journal.js +303 -303
- package/lib/Logger.js +91 -91
- package/lib/Task.js +381 -381
- package/lib/TaskContext.js +27 -27
- package/lib/TaskTest.js +19 -19
- package/lib/lifecycle.js +50 -50
- package/package.json +18 -18
package/index.js
CHANGED
|
@@ -1,62 +1,70 @@
|
|
|
1
|
-
import {
|
|
2
|
-
load,
|
|
3
|
-
capture,
|
|
4
|
-
migrate,
|
|
5
|
-
test
|
|
6
|
-
} from './api/commands.js'
|
|
7
|
-
import {
|
|
8
|
-
describe
|
|
9
|
-
} from './api/describe.js'
|
|
10
|
-
import {
|
|
11
|
-
whereContent,
|
|
12
|
-
whereFromPlugin,
|
|
13
|
-
whereToPlugin
|
|
14
|
-
} from './api/where.js'
|
|
15
|
-
import {
|
|
16
|
-
checkContent,
|
|
17
|
-
mutateContent
|
|
18
|
-
} from './api/data.js'
|
|
19
|
-
import {
|
|
20
|
-
ifErroredAsk,
|
|
21
|
-
throwError
|
|
22
|
-
} from './api/errors.js'
|
|
23
|
-
import {
|
|
24
|
-
testErrorWhere,
|
|
25
|
-
testStopWhere,
|
|
26
|
-
testSuccessWhere
|
|
27
|
-
} from './api/tests.js'
|
|
28
|
-
import {
|
|
29
|
-
updatePlugin,
|
|
30
|
-
removePlugin,
|
|
31
|
-
addPlugin
|
|
32
|
-
} from './api/plugins.js'
|
|
33
|
-
import
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
import {
|
|
2
|
+
load,
|
|
3
|
+
capture,
|
|
4
|
+
migrate,
|
|
5
|
+
test
|
|
6
|
+
} from './api/commands.js'
|
|
7
|
+
import {
|
|
8
|
+
describe
|
|
9
|
+
} from './api/describe.js'
|
|
10
|
+
import {
|
|
11
|
+
whereContent,
|
|
12
|
+
whereFromPlugin,
|
|
13
|
+
whereToPlugin
|
|
14
|
+
} from './api/where.js'
|
|
15
|
+
import {
|
|
16
|
+
checkContent,
|
|
17
|
+
mutateContent
|
|
18
|
+
} from './api/data.js'
|
|
19
|
+
import {
|
|
20
|
+
ifErroredAsk,
|
|
21
|
+
throwError
|
|
22
|
+
} from './api/errors.js'
|
|
23
|
+
import {
|
|
24
|
+
testErrorWhere,
|
|
25
|
+
testStopWhere,
|
|
26
|
+
testSuccessWhere
|
|
27
|
+
} from './api/tests.js'
|
|
28
|
+
import {
|
|
29
|
+
updatePlugin,
|
|
30
|
+
removePlugin,
|
|
31
|
+
addPlugin
|
|
32
|
+
} from './api/plugins.js'
|
|
33
|
+
import {
|
|
34
|
+
getConfig,
|
|
35
|
+
getCourse,
|
|
36
|
+
getComponents
|
|
37
|
+
} from './api/helpers.js'
|
|
38
|
+
import Journal from './lib/Journal.js'
|
|
39
|
+
import CacheManager from './lib/CacheManager.js'
|
|
40
|
+
import Logger from './lib/Logger.js'
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
// commands
|
|
44
|
+
load,
|
|
45
|
+
capture,
|
|
46
|
+
migrate,
|
|
47
|
+
test,
|
|
48
|
+
// migration script api
|
|
49
|
+
describe,
|
|
50
|
+
whereContent,
|
|
51
|
+
whereFromPlugin,
|
|
52
|
+
whereToPlugin,
|
|
53
|
+
checkContent,
|
|
54
|
+
mutateContent,
|
|
55
|
+
ifErroredAsk,
|
|
56
|
+
throwError,
|
|
57
|
+
testErrorWhere,
|
|
58
|
+
testStopWhere,
|
|
59
|
+
testSuccessWhere,
|
|
60
|
+
updatePlugin,
|
|
61
|
+
removePlugin,
|
|
62
|
+
addPlugin,
|
|
63
|
+
getConfig,
|
|
64
|
+
getCourse,
|
|
65
|
+
getComponents,
|
|
66
|
+
// environment objects
|
|
67
|
+
Journal,
|
|
68
|
+
CacheManager,
|
|
69
|
+
Logger
|
|
70
|
+
}
|
package/lib/CacheManager.js
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import crypto from 'crypto'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
import globs from 'globs'
|
|
4
|
-
import fs from 'fs-extra'
|
|
5
|
-
import os from 'os'
|
|
6
|
-
import Logger from './Logger.js'
|
|
7
|
-
|
|
8
|
-
export const ONE_MINUTE = 60 * 1000
|
|
9
|
-
export const ONE_HOUR = 60 * ONE_MINUTE
|
|
10
|
-
export const ONE_WEEK = 7 * 24 * ONE_HOUR
|
|
11
|
-
|
|
12
|
-
const logger = Logger.getInstance();
|
|
13
|
-
|
|
14
|
-
export default class CacheManager {
|
|
15
|
-
constructor (maxAge = ONE_WEEK) {
|
|
16
|
-
this.maxAge = maxAge
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static hash (path) {
|
|
20
|
-
return crypto
|
|
21
|
-
.createHash('sha1')
|
|
22
|
-
.update(path, 'utf8')
|
|
23
|
-
.digest('hex')
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async getTempPath () {
|
|
27
|
-
const osTempPath = await fs.promises.realpath(path.resolve(os.tmpdir()))
|
|
28
|
-
const tempPath = path.posix.join(osTempPath, 'migrations')
|
|
29
|
-
await fs.ensureDir(tempPath)
|
|
30
|
-
return tempPath
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async getCachePath ({ basePath = process.cwd(), outputPath, tempPath }) {
|
|
34
|
-
const projectHash = CacheManager.hash(path.join(basePath, outputPath))
|
|
35
|
-
if (tempPath) await fs.ensureDir(tempPath)
|
|
36
|
-
const cachePath = path.join(tempPath ?? await this.getTempPath(), `${projectHash}.cache`)
|
|
37
|
-
return cachePath
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async getCheckFilePath () {
|
|
41
|
-
const checkFilePath = path.join(await this.getTempPath(), 'last.touch')
|
|
42
|
-
return checkFilePath
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async isCleaningTime () {
|
|
46
|
-
// By default, clean once a day, or with a floor of one hourly intervals
|
|
47
|
-
const checkInterval = Math.max(this.maxAge / 7, ONE_HOUR)
|
|
48
|
-
const checkFilePath = await this.getCheckFilePath()
|
|
49
|
-
// Check if checkFile is older than the cleaning interval
|
|
50
|
-
return (!fs.existsSync(checkFilePath) || Date.now() - (await fs.stat(checkFilePath)).mtime >= checkInterval)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async clean () {
|
|
54
|
-
if (!await this.isCleaningTime()) return
|
|
55
|
-
logger.debug('CacheManager -- Clean running')
|
|
56
|
-
const checkFilePath = await this.getCheckFilePath()
|
|
57
|
-
// Touch checkFile
|
|
58
|
-
await fs.writeFile(checkFilePath, String(Date.now()))
|
|
59
|
-
logger.debug('CacheManager -- Clearing compilation caches')
|
|
60
|
-
const tempPath = await this.getTempPath()
|
|
61
|
-
// Fetch all cache files except checkFile
|
|
62
|
-
const files = await new Promise((resolve, reject) => globs([
|
|
63
|
-
`${tempPath}/**`,
|
|
64
|
-
`!${checkFilePath}`
|
|
65
|
-
], {
|
|
66
|
-
nodir: true
|
|
67
|
-
}, (err, files) => err ? reject(err) : resolve(files)))
|
|
68
|
-
// Fetch file ages
|
|
69
|
-
const fileAges = []
|
|
70
|
-
const now = Date.now()
|
|
71
|
-
for (const index in files) {
|
|
72
|
-
const file = files[index]
|
|
73
|
-
let age = this.maxAge
|
|
74
|
-
try {
|
|
75
|
-
const stat = await fs.stat(file)
|
|
76
|
-
age = (now - stat.mtime)
|
|
77
|
-
} catch (err) {
|
|
78
|
-
logger.error(`CacheManager -- ${err}`)
|
|
79
|
-
}
|
|
80
|
-
fileAges[index] = { file, age }
|
|
81
|
-
}
|
|
82
|
-
// Sort by oldest
|
|
83
|
-
fileAges.sort((a, b) => b.age - a.age)
|
|
84
|
-
// Filter by expired
|
|
85
|
-
const toRemove = fileAges.filter(fileAge => fileAge.age >= this.maxAge)
|
|
86
|
-
// Delete expired cache files
|
|
87
|
-
for (const fileAge of toRemove) {
|
|
88
|
-
try {
|
|
89
|
-
await fs.unlink(fileAge.file)
|
|
90
|
-
} catch (err) {
|
|
91
|
-
logger.error(`CacheManager -- Could not clear cache file ${fileAge.file}`)
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
};
|
|
1
|
+
import crypto from 'crypto'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import globs from 'globs'
|
|
4
|
+
import fs from 'fs-extra'
|
|
5
|
+
import os from 'os'
|
|
6
|
+
import Logger from './Logger.js'
|
|
7
|
+
|
|
8
|
+
export const ONE_MINUTE = 60 * 1000
|
|
9
|
+
export const ONE_HOUR = 60 * ONE_MINUTE
|
|
10
|
+
export const ONE_WEEK = 7 * 24 * ONE_HOUR
|
|
11
|
+
|
|
12
|
+
const logger = Logger.getInstance();
|
|
13
|
+
|
|
14
|
+
export default class CacheManager {
|
|
15
|
+
constructor (maxAge = ONE_WEEK) {
|
|
16
|
+
this.maxAge = maxAge
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static hash (path) {
|
|
20
|
+
return crypto
|
|
21
|
+
.createHash('sha1')
|
|
22
|
+
.update(path, 'utf8')
|
|
23
|
+
.digest('hex')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async getTempPath () {
|
|
27
|
+
const osTempPath = await fs.promises.realpath(path.resolve(os.tmpdir()))
|
|
28
|
+
const tempPath = path.posix.join(osTempPath, 'migrations')
|
|
29
|
+
await fs.ensureDir(tempPath)
|
|
30
|
+
return tempPath
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async getCachePath ({ basePath = process.cwd(), outputPath, tempPath }) {
|
|
34
|
+
const projectHash = CacheManager.hash(path.join(basePath, outputPath))
|
|
35
|
+
if (tempPath) await fs.ensureDir(tempPath)
|
|
36
|
+
const cachePath = path.join(tempPath ?? await this.getTempPath(), `${projectHash}.cache`)
|
|
37
|
+
return cachePath
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async getCheckFilePath () {
|
|
41
|
+
const checkFilePath = path.join(await this.getTempPath(), 'last.touch')
|
|
42
|
+
return checkFilePath
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async isCleaningTime () {
|
|
46
|
+
// By default, clean once a day, or with a floor of one hourly intervals
|
|
47
|
+
const checkInterval = Math.max(this.maxAge / 7, ONE_HOUR)
|
|
48
|
+
const checkFilePath = await this.getCheckFilePath()
|
|
49
|
+
// Check if checkFile is older than the cleaning interval
|
|
50
|
+
return (!fs.existsSync(checkFilePath) || Date.now() - (await fs.stat(checkFilePath)).mtime >= checkInterval)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async clean () {
|
|
54
|
+
if (!await this.isCleaningTime()) return
|
|
55
|
+
logger.debug('CacheManager -- Clean running')
|
|
56
|
+
const checkFilePath = await this.getCheckFilePath()
|
|
57
|
+
// Touch checkFile
|
|
58
|
+
await fs.writeFile(checkFilePath, String(Date.now()))
|
|
59
|
+
logger.debug('CacheManager -- Clearing compilation caches')
|
|
60
|
+
const tempPath = await this.getTempPath()
|
|
61
|
+
// Fetch all cache files except checkFile
|
|
62
|
+
const files = await new Promise((resolve, reject) => globs([
|
|
63
|
+
`${tempPath}/**`,
|
|
64
|
+
`!${checkFilePath}`
|
|
65
|
+
], {
|
|
66
|
+
nodir: true
|
|
67
|
+
}, (err, files) => err ? reject(err) : resolve(files)))
|
|
68
|
+
// Fetch file ages
|
|
69
|
+
const fileAges = []
|
|
70
|
+
const now = Date.now()
|
|
71
|
+
for (const index in files) {
|
|
72
|
+
const file = files[index]
|
|
73
|
+
let age = this.maxAge
|
|
74
|
+
try {
|
|
75
|
+
const stat = await fs.stat(file)
|
|
76
|
+
age = (now - stat.mtime)
|
|
77
|
+
} catch (err) {
|
|
78
|
+
logger.error(`CacheManager -- ${err}`)
|
|
79
|
+
}
|
|
80
|
+
fileAges[index] = { file, age }
|
|
81
|
+
}
|
|
82
|
+
// Sort by oldest
|
|
83
|
+
fileAges.sort((a, b) => b.age - a.age)
|
|
84
|
+
// Filter by expired
|
|
85
|
+
const toRemove = fileAges.filter(fileAge => fileAge.age >= this.maxAge)
|
|
86
|
+
// Delete expired cache files
|
|
87
|
+
for (const fileAge of toRemove) {
|
|
88
|
+
try {
|
|
89
|
+
await fs.unlink(fileAge.file)
|
|
90
|
+
} catch (err) {
|
|
91
|
+
logger.error(`CacheManager -- Could not clear cache file ${fileAge.file}`)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|