npm-update-package 0.30.0 → 0.31.3
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 +3 -0
- package/.eslintrc.js +23 -0
- package/.github/renovate.json +15 -0
- package/.github/workflows/eslint.yml +14 -0
- package/.github/workflows/test.yml +20 -0
- package/.husky/pre-commit +4 -0
- package/.nvmrc +1 -0
- package/dist/package.json +65 -0
- package/dist/{bin.js → src/bin.js} +6 -3
- package/dist/{core → src/core}/FailedResult.js +0 -0
- package/dist/{core → src/core}/OutdatedPackage.js +0 -0
- package/dist/{core → src/core}/OutdatedPackageProcessor.js +0 -0
- package/dist/{core → src/core}/OutdatedPackagesProcessor.js +0 -0
- package/dist/{core → src/core}/SucceededResult.js +0 -0
- package/dist/{core → src/core}/index.js +0 -0
- package/dist/{file → src/file}/index.js +0 -0
- package/dist/{file → src/file}/readFile.js +0 -0
- package/dist/{git → src/git}/CommitMessageCreator.js +0 -0
- package/dist/{git → src/git}/Git.js +0 -0
- package/dist/{git → src/git}/GitRepository.js +0 -0
- package/dist/{git → src/git}/createBranchName.js +0 -0
- package/dist/{git → src/git}/index.js +0 -0
- package/dist/{github → src/github}/GitHub.js +0 -0
- package/dist/{github → src/github}/branch/finder/BranchFinder.js +0 -0
- package/dist/{github → src/github}/branch/finder/index.js +0 -0
- package/dist/{github → src/github}/branch/index.js +0 -0
- package/dist/{github → src/github}/createGitHub.js +0 -0
- package/dist/{github → src/github}/createOctokit.js +5 -2
- package/dist/{github → src/github}/errors/NotFoundError.js +0 -0
- package/dist/{github → src/github}/errors/index.js +0 -0
- package/dist/{github → src/github}/index.js +0 -0
- package/dist/{github → src/github}/label/creator/LabelCreator.js +0 -0
- package/dist/{github → src/github}/label/creator/index.js +0 -0
- package/dist/{github → src/github}/label/index.js +0 -0
- package/dist/{github → src/github}/pull-request/closer/PullRequestCloser.js +0 -0
- package/dist/{github → src/github}/pull-request/closer/index.js +0 -0
- package/dist/{github → src/github}/pull-request/creator/PullRequestCreator.js +0 -0
- package/dist/{github → src/github}/pull-request/creator/PullRequestTitleCreator.js +0 -0
- package/dist/{github → src/github}/pull-request/creator/createPullRequestBody.js +5 -5
- package/dist/{github → src/github}/pull-request/creator/index.js +0 -0
- package/dist/{github → src/github}/pull-request/finder/PullRequestFinder.js +0 -0
- package/dist/{github → src/github}/pull-request/finder/index.js +0 -0
- package/dist/{github → src/github}/pull-request/finder/isPullRequestByNpmUpdatePackage.js +0 -0
- package/dist/{github → src/github}/pull-request/index.js +0 -0
- package/dist/{github → src/github}/pull-request/metadata/PullRequestMetadata.js +0 -0
- package/dist/{github → src/github}/pull-request/metadata/createPullRequestMetadata.js +5 -2
- package/dist/{github → src/github}/pull-request/metadata/extractPullRequestMetadata.js +0 -0
- package/dist/{github → src/github}/pull-request/metadata/index.js +0 -0
- package/dist/{json → src/json}/index.js +0 -0
- package/dist/{json → src/json}/toJSON.js +0 -0
- package/dist/{logger → src/logger}/LogLevel.js +0 -0
- package/dist/{logger → src/logger}/Logger.js +0 -0
- package/dist/{logger → src/logger}/createLogger.js +0 -0
- package/dist/{logger → src/logger}/index.js +0 -0
- package/dist/{main.js → src/main.js} +0 -0
- package/dist/{ncu → src/ncu}/Ncu.js +0 -0
- package/dist/{ncu → src/ncu}/NcuResult.js +0 -0
- package/dist/{ncu → src/ncu}/index.js +0 -0
- package/dist/{options → src/options}/CLIOption.js +0 -0
- package/dist/{options → src/options}/OptionType.js +0 -0
- package/dist/{options → src/options}/Options.js +0 -0
- package/dist/{options → src/options}/cliOptions.js +0 -0
- package/dist/{options → src/options}/index.js +0 -0
- package/dist/{options → src/options}/initOptions.js +5 -2
- package/dist/{options → src/options}/toCommanderOption.js +0 -0
- package/dist/{package-json → src/package-json}/PackageMetadata.js +0 -0
- package/dist/{package-json → src/package-json}/PackageMetadataDependencies.js +0 -0
- package/dist/{package-json → src/package-json}/index.js +0 -0
- package/dist/{package-json → src/package-json}/parsePackageJson.js +0 -0
- package/dist/{package-manager → src/package-manager}/Npm.js +0 -0
- package/dist/{package-manager → src/package-manager}/PackageManager.js +0 -0
- package/dist/{package-manager → src/package-manager}/PackageManagerName.js +0 -0
- package/dist/{package-manager → src/package-manager}/Yarn.js +0 -0
- package/dist/{package-manager → src/package-manager}/createPackageManager.js +0 -0
- package/dist/{package-manager → src/package-manager}/index.js +0 -0
- package/dist/{semver → src/semver}/SemVer.js +0 -0
- package/dist/{semver → src/semver}/SemVerLevel.js +0 -0
- package/dist/{semver → src/semver}/compareSemVers.js +0 -0
- package/dist/{semver → src/semver}/index.js +0 -0
- package/dist/{terminal → src/terminal}/Terminal.js +0 -0
- package/dist/{terminal → src/terminal}/index.js +0 -0
- package/jest.config.ts +12 -0
- package/lint-staged.config.js +4 -0
- package/npm-update-package.code-workspace +10 -0
- package/package.json +2 -5
- package/src/bin.ts +22 -0
- package/src/core/FailedResult.ts +6 -0
- package/src/core/OutdatedPackage.ts +11 -0
- package/src/core/OutdatedPackageProcessor.ts +136 -0
- package/src/core/OutdatedPackagesProcessor.ts +35 -0
- package/src/core/SucceededResult.ts +7 -0
- package/src/core/index.ts +5 -0
- package/src/file/index.ts +1 -0
- package/src/file/readFile.ts +6 -0
- package/src/git/CommitMessageCreator.test.ts +17 -0
- package/src/git/CommitMessageCreator.ts +19 -0
- package/src/git/Git.ts +59 -0
- package/src/git/GitRepository.test.ts +82 -0
- package/src/git/GitRepository.ts +57 -0
- package/src/git/createBranchName.test.ts +14 -0
- package/src/git/createBranchName.ts +7 -0
- package/src/git/index.ts +4 -0
- package/src/github/GitHub.ts +198 -0
- package/src/github/branch/finder/BranchFinder.test.ts +21 -0
- package/src/github/branch/finder/BranchFinder.ts +9 -0
- package/src/github/branch/finder/index.ts +1 -0
- package/src/github/branch/index.ts +1 -0
- package/src/github/createGitHub.test.ts +16 -0
- package/src/github/createGitHub.ts +17 -0
- package/src/github/createOctokit.test.ts +27 -0
- package/src/github/createOctokit.ts +27 -0
- package/src/github/errors/NotFoundError.ts +11 -0
- package/src/github/errors/index.ts +1 -0
- package/src/github/index.ts +5 -0
- package/src/github/label/creator/LabelCreator.ts +71 -0
- package/src/github/label/creator/index.ts +1 -0
- package/src/github/label/index.ts +1 -0
- package/src/github/pull-request/closer/PullRequestCloser.test.ts +53 -0
- package/src/github/pull-request/closer/PullRequestCloser.ts +21 -0
- package/src/github/pull-request/closer/index.ts +1 -0
- package/src/github/pull-request/creator/PullRequestCreator.test.ts +98 -0
- package/src/github/pull-request/creator/PullRequestCreator.ts +84 -0
- package/src/github/pull-request/creator/PullRequestTitleCreator.test.ts +17 -0
- package/src/github/pull-request/creator/PullRequestTitleCreator.ts +19 -0
- package/src/github/pull-request/creator/createPullRequestBody.test.ts +47 -0
- package/src/github/pull-request/creator/createPullRequestBody.ts +35 -0
- package/src/github/pull-request/creator/index.ts +2 -0
- package/src/github/pull-request/finder/PullRequestFinder.ts +27 -0
- package/src/github/pull-request/finder/index.ts +1 -0
- package/src/github/pull-request/finder/isPullRequestByNpmUpdatePackage.test.ts +24 -0
- package/src/github/pull-request/finder/isPullRequestByNpmUpdatePackage.ts +5 -0
- package/src/github/pull-request/index.ts +3 -0
- package/src/github/pull-request/metadata/PullRequestMetadata.ts +22 -0
- package/src/github/pull-request/metadata/createPullRequestMetadata.test.ts +31 -0
- package/src/github/pull-request/metadata/createPullRequestMetadata.ts +21 -0
- package/src/github/pull-request/metadata/extractPullRequestMetadata.test.ts +53 -0
- package/src/github/pull-request/metadata/extractPullRequestMetadata.ts +21 -0
- package/src/github/pull-request/metadata/index.ts +3 -0
- package/src/json/index.ts +1 -0
- package/src/json/toJSON.test.ts +65 -0
- package/src/json/toJSON.ts +13 -0
- package/src/logger/LogLevel.ts +13 -0
- package/src/logger/Logger.ts +1 -0
- package/src/logger/createLogger.ts +10 -0
- package/src/logger/index.ts +3 -0
- package/src/main.ts +149 -0
- package/src/ncu/Ncu.ts +84 -0
- package/src/ncu/NcuResult.ts +10 -0
- package/src/ncu/index.ts +1 -0
- package/src/options/CLIOption.ts +19 -0
- package/src/options/OptionType.ts +8 -0
- package/src/options/Options.ts +40 -0
- package/src/options/cliOptions.ts +60 -0
- package/src/options/index.ts +2 -0
- package/src/options/initOptions.ts +24 -0
- package/src/options/toCommanderOption.ts +35 -0
- package/src/package-json/PackageMetadata.ts +24 -0
- package/src/package-json/PackageMetadataDependencies.ts +10 -0
- package/src/package-json/index.ts +2 -0
- package/src/package-json/parsePackageJson.ts +15 -0
- package/src/package-manager/Npm.ts +17 -0
- package/src/package-manager/PackageManager.ts +5 -0
- package/src/package-manager/PackageManagerName.ts +8 -0
- package/src/package-manager/Yarn.ts +17 -0
- package/src/package-manager/createPackageManager.test.ts +27 -0
- package/src/package-manager/createPackageManager.ts +20 -0
- package/src/package-manager/index.ts +5 -0
- package/src/semver/SemVer.test.ts +17 -0
- package/src/semver/SemVer.ts +40 -0
- package/src/semver/SemVerLevel.ts +9 -0
- package/src/semver/compareSemVers.test.ts +21 -0
- package/src/semver/compareSemVers.ts +16 -0
- package/src/semver/index.ts +3 -0
- package/src/terminal/Terminal.ts +12 -0
- package/src/terminal/index.ts +1 -0
- package/tsconfig.base.json +7 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +9 -0
- package/dist/app.js +0 -8
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
import pkg from '../../../../package.json'
|
|
3
|
+
import type { OutdatedPackage } from '../../../core'
|
|
4
|
+
import { SemVer } from '../../../semver'
|
|
5
|
+
import { createPullRequestMetadata } from './createPullRequestMetadata'
|
|
6
|
+
|
|
7
|
+
describe('createPullRequestMetadata', () => {
|
|
8
|
+
it('returns PullRequestMetadata', () => {
|
|
9
|
+
const outdatedPackages: OutdatedPackage[] = [
|
|
10
|
+
{
|
|
11
|
+
name: '@npm-update-package/example',
|
|
12
|
+
currentVersion: SemVer.of('1.0.0'),
|
|
13
|
+
newVersion: SemVer.of('2.0.0'),
|
|
14
|
+
level: 'major'
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
const metadata = createPullRequestMetadata(outdatedPackages)
|
|
18
|
+
|
|
19
|
+
expect(metadata).toEqual({
|
|
20
|
+
version: pkg.version,
|
|
21
|
+
packages: [
|
|
22
|
+
{
|
|
23
|
+
name: '@npm-update-package/example',
|
|
24
|
+
currentVersion: '1.0.0',
|
|
25
|
+
newVersion: '2.0.0',
|
|
26
|
+
level: 'major'
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
import pkg from '../../../../package.json'
|
|
3
|
+
import type { OutdatedPackage } from '../../../core'
|
|
4
|
+
import type { PullRequestMetadata } from './PullRequestMetadata'
|
|
5
|
+
|
|
6
|
+
export const createPullRequestMetadata = (outdatedPackages: OutdatedPackage[]): PullRequestMetadata => {
|
|
7
|
+
return {
|
|
8
|
+
version: pkg.version,
|
|
9
|
+
packages: outdatedPackages.map(({
|
|
10
|
+
name,
|
|
11
|
+
currentVersion,
|
|
12
|
+
newVersion,
|
|
13
|
+
level
|
|
14
|
+
}) => ({
|
|
15
|
+
name,
|
|
16
|
+
currentVersion: currentVersion.version,
|
|
17
|
+
newVersion: newVersion.version,
|
|
18
|
+
level
|
|
19
|
+
}))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { extractPullRequestMetadata } from './extractPullRequestMetadata'
|
|
2
|
+
|
|
3
|
+
describe('extractPullRequestMetadata', () => {
|
|
4
|
+
it('returns PullRequestMetadata if body contains metadata', () => {
|
|
5
|
+
const body = `<div id="npm-update-package-metadata">
|
|
6
|
+
|
|
7
|
+
\`\`\`json
|
|
8
|
+
{
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"name": "@npm-update-package/example",
|
|
13
|
+
"level": "major",
|
|
14
|
+
"currentVersion": "1.0.0",
|
|
15
|
+
"newVersion": "2.0.0"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
\`\`\`
|
|
20
|
+
|
|
21
|
+
</div>`
|
|
22
|
+
const metadata = extractPullRequestMetadata(body)
|
|
23
|
+
expect(metadata).toEqual({
|
|
24
|
+
version: '1.0.0',
|
|
25
|
+
packages: [
|
|
26
|
+
{
|
|
27
|
+
name: '@npm-update-package/example',
|
|
28
|
+
level: 'major',
|
|
29
|
+
currentVersion: '1.0.0',
|
|
30
|
+
newVersion: '2.0.0'
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('returns undefined if body does not contain metadata', () => {
|
|
37
|
+
const body = ''
|
|
38
|
+
const metadata = extractPullRequestMetadata(body)
|
|
39
|
+
expect(metadata).toBeUndefined()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('returns undefined if metadata is invalid', () => {
|
|
43
|
+
const body = `<div id="npm-update-package-metadata">
|
|
44
|
+
|
|
45
|
+
\`\`\`json
|
|
46
|
+
{}
|
|
47
|
+
\`\`\`
|
|
48
|
+
|
|
49
|
+
</div>`
|
|
50
|
+
const metadata = extractPullRequestMetadata(body)
|
|
51
|
+
expect(metadata).toBeUndefined()
|
|
52
|
+
})
|
|
53
|
+
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isPullRequestMetadata,
|
|
3
|
+
type PullRequestMetadata
|
|
4
|
+
} from './PullRequestMetadata'
|
|
5
|
+
|
|
6
|
+
export const extractPullRequestMetadata = (pullRequestBody: string): PullRequestMetadata | undefined => {
|
|
7
|
+
const matched = pullRequestBody.match(/<div id="npm-update-package-metadata">\s*```json\s*([\s\S]+?)\s*```\s*<\/div>/)
|
|
8
|
+
const json = matched?.[1]
|
|
9
|
+
|
|
10
|
+
if (json === undefined) {
|
|
11
|
+
return undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const metadata: unknown = JSON.parse(json)
|
|
15
|
+
|
|
16
|
+
if (!isPullRequestMetadata(metadata)) {
|
|
17
|
+
return undefined
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return metadata
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './toJSON'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { toJSON } from './toJSON'
|
|
2
|
+
|
|
3
|
+
type TestCase = [unknown, string]
|
|
4
|
+
|
|
5
|
+
describe('toJSON', () => {
|
|
6
|
+
describe('returns not indented JSON string if pretty option is false', () => {
|
|
7
|
+
const cases: TestCase[] = [
|
|
8
|
+
[
|
|
9
|
+
{
|
|
10
|
+
number: 1,
|
|
11
|
+
string: 'string'
|
|
12
|
+
},
|
|
13
|
+
'{"number":1,"string":"string"}'
|
|
14
|
+
],
|
|
15
|
+
[
|
|
16
|
+
[
|
|
17
|
+
{
|
|
18
|
+
number: 1,
|
|
19
|
+
string: 'string'
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
'[{"number":1,"string":"string"}]'
|
|
23
|
+
]
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
it.each<TestCase>(cases)('value=%j', (value, expected) => {
|
|
27
|
+
const json = toJSON(value)
|
|
28
|
+
expect(json).toBe(expected)
|
|
29
|
+
})
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
describe('returns indented JSON string if pretty option is true', () => {
|
|
33
|
+
const cases: TestCase[] = [
|
|
34
|
+
[
|
|
35
|
+
{
|
|
36
|
+
number: 1,
|
|
37
|
+
string: 'string'
|
|
38
|
+
},
|
|
39
|
+
`{
|
|
40
|
+
"number": 1,
|
|
41
|
+
"string": "string"
|
|
42
|
+
}`
|
|
43
|
+
],
|
|
44
|
+
[
|
|
45
|
+
[
|
|
46
|
+
{
|
|
47
|
+
number: 1,
|
|
48
|
+
string: 'string'
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
`[
|
|
52
|
+
{
|
|
53
|
+
"number": 1,
|
|
54
|
+
"string": "string"
|
|
55
|
+
}
|
|
56
|
+
]`
|
|
57
|
+
]
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
it.each<TestCase>(cases)('value=%j', (value, expected) => {
|
|
61
|
+
const json = toJSON(value, { pretty: true })
|
|
62
|
+
expect(json).toBe(expected)
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
})
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface Options {
|
|
2
|
+
pretty?: boolean
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export const toJSON = (value: unknown, options?: Options): string => {
|
|
6
|
+
const pretty = options?.pretty ?? false
|
|
7
|
+
|
|
8
|
+
if (pretty) {
|
|
9
|
+
return JSON.stringify(value, null, 2)
|
|
10
|
+
} else {
|
|
11
|
+
return JSON.stringify(value)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const LogLevel = {
|
|
2
|
+
Debug: 'debug',
|
|
3
|
+
Error: 'error',
|
|
4
|
+
Fatal: 'fatal',
|
|
5
|
+
Info: 'info',
|
|
6
|
+
Off: 'off',
|
|
7
|
+
Trace: 'trace',
|
|
8
|
+
Warn: 'warn'
|
|
9
|
+
} as const
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
11
|
+
export type LogLevel = typeof LogLevel[keyof typeof LogLevel]
|
|
12
|
+
const logLevels = Object.values(LogLevel)
|
|
13
|
+
export const isLogLevel = (value: any): value is LogLevel => logLevels.includes(value)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { Logger } from 'log4js'
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getLogger } from 'log4js'
|
|
2
|
+
import type { Logger } from './Logger'
|
|
3
|
+
import type { LogLevel } from './LogLevel'
|
|
4
|
+
|
|
5
|
+
// TODO: add test
|
|
6
|
+
export const createLogger = (logLevel: LogLevel): Logger => {
|
|
7
|
+
const logger = getLogger()
|
|
8
|
+
logger.level = logLevel
|
|
9
|
+
return logger
|
|
10
|
+
}
|
package/src/main.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isLeft,
|
|
3
|
+
isRight
|
|
4
|
+
} from 'fp-ts/lib/Either'
|
|
5
|
+
import {
|
|
6
|
+
OutdatedPackageProcessor,
|
|
7
|
+
OutdatedPackagesProcessor
|
|
8
|
+
} from './core'
|
|
9
|
+
import {
|
|
10
|
+
CommitMessageCreator,
|
|
11
|
+
Git
|
|
12
|
+
} from './git'
|
|
13
|
+
import {
|
|
14
|
+
BranchFinder,
|
|
15
|
+
createGitHub,
|
|
16
|
+
LabelCreator,
|
|
17
|
+
PullRequestCloser,
|
|
18
|
+
PullRequestCreator,
|
|
19
|
+
PullRequestFinder,
|
|
20
|
+
PullRequestTitleCreator
|
|
21
|
+
} from './github'
|
|
22
|
+
import type { Logger } from './logger'
|
|
23
|
+
import { Ncu } from './ncu'
|
|
24
|
+
import type { Options } from './options'
|
|
25
|
+
import { createPackageManager } from './package-manager'
|
|
26
|
+
import { Terminal } from './terminal'
|
|
27
|
+
|
|
28
|
+
// TODO: add test
|
|
29
|
+
export const main = async ({
|
|
30
|
+
options,
|
|
31
|
+
logger
|
|
32
|
+
}: {
|
|
33
|
+
options: Options
|
|
34
|
+
logger: Logger
|
|
35
|
+
}): Promise<void> => {
|
|
36
|
+
logger.debug(`options=${JSON.stringify({
|
|
37
|
+
...options,
|
|
38
|
+
githubToken: options.githubToken !== '' ? '***' : ''
|
|
39
|
+
})}`)
|
|
40
|
+
|
|
41
|
+
const ncu = new Ncu(logger)
|
|
42
|
+
const outdatedPackages = await ncu.check()
|
|
43
|
+
logger.debug(`outdatedPackages=${JSON.stringify(outdatedPackages)}`)
|
|
44
|
+
|
|
45
|
+
if (outdatedPackages.length === 0) {
|
|
46
|
+
logger.info('All packages are up-to-date.')
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
logger.info(`There are ${outdatedPackages.length} outdated packages.`)
|
|
51
|
+
|
|
52
|
+
const terminal = new Terminal()
|
|
53
|
+
const git = new Git(terminal)
|
|
54
|
+
const gitRepo = await git.getRepository()
|
|
55
|
+
logger.debug(`gitRepo=${JSON.stringify(gitRepo)}`)
|
|
56
|
+
|
|
57
|
+
const github = createGitHub({
|
|
58
|
+
repository: gitRepo,
|
|
59
|
+
token: options.githubToken
|
|
60
|
+
})
|
|
61
|
+
const githubRepo = await github.fetchRepository({
|
|
62
|
+
owner: gitRepo.owner,
|
|
63
|
+
repo: gitRepo.name
|
|
64
|
+
})
|
|
65
|
+
logger.debug(`githubRepo=${JSON.stringify(githubRepo)}`)
|
|
66
|
+
|
|
67
|
+
const branches = await github.fetchBranches({
|
|
68
|
+
owner: gitRepo.owner,
|
|
69
|
+
repo: gitRepo.name
|
|
70
|
+
})
|
|
71
|
+
logger.debug(`branches=${JSON.stringify(branches)}`)
|
|
72
|
+
|
|
73
|
+
const pullRequests = await github.fetchPullRequests({
|
|
74
|
+
owner: gitRepo.owner,
|
|
75
|
+
repo: gitRepo.name
|
|
76
|
+
})
|
|
77
|
+
logger.debug(`pullRequests=${JSON.stringify(pullRequests)}`)
|
|
78
|
+
|
|
79
|
+
const labelCreator = new LabelCreator({
|
|
80
|
+
github,
|
|
81
|
+
gitRepo,
|
|
82
|
+
logger
|
|
83
|
+
})
|
|
84
|
+
await labelCreator.create({
|
|
85
|
+
name: 'npm-update-package',
|
|
86
|
+
description: 'Created by npm-update-package',
|
|
87
|
+
color: 'A00F21'
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
const branchFinder = new BranchFinder(branches)
|
|
91
|
+
const packageManager = createPackageManager({
|
|
92
|
+
terminal,
|
|
93
|
+
packageManager: options.packageManager
|
|
94
|
+
})
|
|
95
|
+
const pullRequestTitleCreator = new PullRequestTitleCreator(options.pullRequestTitle)
|
|
96
|
+
const pullRequestCreator = new PullRequestCreator({
|
|
97
|
+
github,
|
|
98
|
+
gitRepo,
|
|
99
|
+
githubRepo,
|
|
100
|
+
pullRequestTitleCreator,
|
|
101
|
+
logger,
|
|
102
|
+
reviewers: options.reviewers
|
|
103
|
+
})
|
|
104
|
+
const commitMessageCreator = new CommitMessageCreator(options.commitMessage)
|
|
105
|
+
const pullRequestFinder = new PullRequestFinder(pullRequests)
|
|
106
|
+
const pullRequestCloser = new PullRequestCloser(github)
|
|
107
|
+
const outdatedPackageProcessor = new OutdatedPackageProcessor({
|
|
108
|
+
git,
|
|
109
|
+
ncu,
|
|
110
|
+
packageManager,
|
|
111
|
+
pullRequestCreator,
|
|
112
|
+
branchFinder,
|
|
113
|
+
logger,
|
|
114
|
+
commitMessageCreator,
|
|
115
|
+
pullRequestFinder,
|
|
116
|
+
pullRequestCloser
|
|
117
|
+
})
|
|
118
|
+
const outdatedPackagesProcessor = new OutdatedPackagesProcessor({
|
|
119
|
+
outdatedPackageProcessor,
|
|
120
|
+
logger
|
|
121
|
+
})
|
|
122
|
+
const results = await outdatedPackagesProcessor.process(outdatedPackages)
|
|
123
|
+
logger.debug(`results=${JSON.stringify(results)}`)
|
|
124
|
+
|
|
125
|
+
const succeededResults = results.filter(isRight).map(({ right }) => right)
|
|
126
|
+
logger.debug(`succeededResults=${JSON.stringify(succeededResults)}`)
|
|
127
|
+
|
|
128
|
+
const createdPackages = succeededResults
|
|
129
|
+
.filter(({ created }) => created)
|
|
130
|
+
.map(({ outdatedPackage }) => outdatedPackage)
|
|
131
|
+
logger.debug(`createdPackages=${JSON.stringify(createdPackages)}`)
|
|
132
|
+
|
|
133
|
+
const skippedPackages = succeededResults
|
|
134
|
+
.filter(({ skipped }) => skipped)
|
|
135
|
+
.map(({ outdatedPackage }) => outdatedPackage)
|
|
136
|
+
logger.debug(`skippedPackages=${JSON.stringify(skippedPackages)}`)
|
|
137
|
+
|
|
138
|
+
const failedResults = results.filter(isLeft).map(({ left }) => left)
|
|
139
|
+
logger.debug(`failedResults=${JSON.stringify(failedResults)}`)
|
|
140
|
+
|
|
141
|
+
const failedPackages = failedResults.map(({ outdatedPackage }) => outdatedPackage)
|
|
142
|
+
logger.debug(`failedPackages=${JSON.stringify(failedPackages)}`)
|
|
143
|
+
|
|
144
|
+
// TODO: show as table
|
|
145
|
+
logger.info(`Processed ${succeededResults.length + failedPackages.length} packages:
|
|
146
|
+
- ${createdPackages.length} packages: created (${createdPackages.map(({ name }) => name).join(',')})
|
|
147
|
+
- ${skippedPackages.length} packages: skipped: (${skippedPackages.map(({ name }) => name).join(',')})
|
|
148
|
+
- ${failedPackages.length} packages: failed: (${failedPackages.map(({ name }) => name).join(',')})`)
|
|
149
|
+
}
|
package/src/ncu/Ncu.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { run } from 'npm-check-updates'
|
|
2
|
+
import type { RunOptions } from 'npm-check-updates/build/src/types'
|
|
3
|
+
import { isNotUndefined } from 'type-guards'
|
|
4
|
+
import type { OutdatedPackage } from '../core'
|
|
5
|
+
import { readFile } from '../file'
|
|
6
|
+
import type { Logger } from '../logger'
|
|
7
|
+
import { parsePackageJson } from '../package-json'
|
|
8
|
+
import {
|
|
9
|
+
compareSemVers,
|
|
10
|
+
SemVer
|
|
11
|
+
} from '../semver'
|
|
12
|
+
import { isNcuResult } from './NcuResult'
|
|
13
|
+
|
|
14
|
+
// TODO: add test
|
|
15
|
+
export class Ncu {
|
|
16
|
+
constructor (private readonly logger: Logger) {}
|
|
17
|
+
|
|
18
|
+
async check (): Promise<OutdatedPackage[]> {
|
|
19
|
+
return await this.run({
|
|
20
|
+
jsonUpgraded: true
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async update (outdatedPackage: OutdatedPackage): Promise<OutdatedPackage[]> {
|
|
25
|
+
return await this.run({
|
|
26
|
+
jsonUpgraded: true,
|
|
27
|
+
filter: outdatedPackage.name,
|
|
28
|
+
upgrade: true
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private async run (options: RunOptions): Promise<OutdatedPackage[]> {
|
|
33
|
+
// Read package.json before running ncu
|
|
34
|
+
const json = await readFile('./package.json')
|
|
35
|
+
const pkg = parsePackageJson(json)
|
|
36
|
+
this.logger.debug(`pkg=${JSON.stringify(pkg)}`)
|
|
37
|
+
|
|
38
|
+
const result = await run(options)
|
|
39
|
+
this.logger.debug(`result=${JSON.stringify(result)}`)
|
|
40
|
+
|
|
41
|
+
if (!isNcuResult(result)) {
|
|
42
|
+
throw new Error('Failed to running ncu.')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const currentDependencies = {
|
|
46
|
+
...pkg.dependencies,
|
|
47
|
+
...pkg.devDependencies,
|
|
48
|
+
...pkg.peerDependencies,
|
|
49
|
+
...pkg.optionalDependencies
|
|
50
|
+
}
|
|
51
|
+
const resultEntries = Object.entries(result)
|
|
52
|
+
const outdatedPackages: OutdatedPackage[] = resultEntries
|
|
53
|
+
.map(([name, newVersionString]) => {
|
|
54
|
+
const currentVersionString = currentDependencies[name]
|
|
55
|
+
|
|
56
|
+
if (currentVersionString === undefined) {
|
|
57
|
+
return undefined
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const currentVersion = SemVer.of(currentVersionString)
|
|
61
|
+
const newVersion = SemVer.of(newVersionString)
|
|
62
|
+
const level = compareSemVers(currentVersion, newVersion)
|
|
63
|
+
|
|
64
|
+
if (level === undefined) {
|
|
65
|
+
return undefined
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const outdatedPackage: OutdatedPackage = {
|
|
69
|
+
name,
|
|
70
|
+
currentVersion,
|
|
71
|
+
newVersion,
|
|
72
|
+
level
|
|
73
|
+
}
|
|
74
|
+
return outdatedPackage
|
|
75
|
+
})
|
|
76
|
+
.filter(isNotUndefined)
|
|
77
|
+
|
|
78
|
+
if (resultEntries.length !== outdatedPackages.length) {
|
|
79
|
+
throw new Error('Failed to running ncu.')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return outdatedPackages
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
record,
|
|
3
|
+
string,
|
|
4
|
+
type TypeOf
|
|
5
|
+
} from 'io-ts'
|
|
6
|
+
|
|
7
|
+
export const NcuResult = record(string, string)
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
9
|
+
export type NcuResult = TypeOf<typeof NcuResult>
|
|
10
|
+
export const isNcuResult = NcuResult.is
|
package/src/ncu/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Ncu'
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { OptionType } from './OptionType'
|
|
2
|
+
|
|
3
|
+
interface OptionBase {
|
|
4
|
+
name: string
|
|
5
|
+
description: string
|
|
6
|
+
type: OptionType
|
|
7
|
+
choices?: string[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface RequiredOption extends OptionBase {
|
|
11
|
+
required: true
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface OptionalOption extends OptionBase {
|
|
15
|
+
required: false
|
|
16
|
+
default?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type CLIOption = RequiredOption | OptionalOption
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const OptionType = {
|
|
2
|
+
String: 'string',
|
|
3
|
+
StringArray: 'string[]'
|
|
4
|
+
} as const
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
6
|
+
export type OptionType = typeof OptionType[keyof typeof OptionType]
|
|
7
|
+
const optionTypes = Object.values(OptionType)
|
|
8
|
+
export const isOptionType = (value: any): value is OptionType => optionTypes.includes(value)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
array,
|
|
3
|
+
intersection,
|
|
4
|
+
literal,
|
|
5
|
+
partial,
|
|
6
|
+
string,
|
|
7
|
+
type,
|
|
8
|
+
union,
|
|
9
|
+
type TypeOf
|
|
10
|
+
} from 'io-ts'
|
|
11
|
+
import { LogLevel } from '../logger'
|
|
12
|
+
import { PackageManagerName } from '../package-manager'
|
|
13
|
+
|
|
14
|
+
const Options = intersection([
|
|
15
|
+
type({
|
|
16
|
+
commitMessage: string,
|
|
17
|
+
githubToken: string,
|
|
18
|
+
logLevel: union([
|
|
19
|
+
literal(LogLevel.Off),
|
|
20
|
+
literal(LogLevel.Fatal),
|
|
21
|
+
literal(LogLevel.Error),
|
|
22
|
+
literal(LogLevel.Warn),
|
|
23
|
+
literal(LogLevel.Info),
|
|
24
|
+
literal(LogLevel.Debug),
|
|
25
|
+
literal(LogLevel.Trace)
|
|
26
|
+
]),
|
|
27
|
+
packageManager: union([
|
|
28
|
+
literal(PackageManagerName.Npm),
|
|
29
|
+
literal(PackageManagerName.Yarn)
|
|
30
|
+
]),
|
|
31
|
+
pullRequestTitle: string
|
|
32
|
+
}),
|
|
33
|
+
partial({
|
|
34
|
+
reviewers: array(string)
|
|
35
|
+
})
|
|
36
|
+
])
|
|
37
|
+
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
39
|
+
export type Options = TypeOf<typeof Options>
|
|
40
|
+
export const isOptions = Options.is
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { LogLevel } from '../logger'
|
|
2
|
+
import { PackageManagerName } from '../package-manager'
|
|
3
|
+
import type { CLIOption } from './CLIOption'
|
|
4
|
+
import { OptionType } from './OptionType'
|
|
5
|
+
|
|
6
|
+
export const cliOptions: CLIOption[] = [
|
|
7
|
+
{
|
|
8
|
+
name: 'commit-message',
|
|
9
|
+
description: 'Commit message template',
|
|
10
|
+
type: OptionType.String,
|
|
11
|
+
required: false,
|
|
12
|
+
default: 'chore(deps): {{level}} update {{{packageName}}} to v{{newVersion}}'
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'github-token',
|
|
16
|
+
description: 'GitHub token',
|
|
17
|
+
type: OptionType.String,
|
|
18
|
+
required: true
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'log-level',
|
|
22
|
+
description: 'Log level to show',
|
|
23
|
+
type: OptionType.String,
|
|
24
|
+
required: false,
|
|
25
|
+
choices: [
|
|
26
|
+
LogLevel.Off,
|
|
27
|
+
LogLevel.Fatal,
|
|
28
|
+
LogLevel.Error,
|
|
29
|
+
LogLevel.Warn,
|
|
30
|
+
LogLevel.Info,
|
|
31
|
+
LogLevel.Debug,
|
|
32
|
+
LogLevel.Trace
|
|
33
|
+
],
|
|
34
|
+
default: LogLevel.Info
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'package-manager',
|
|
38
|
+
description: 'Package manager of your project',
|
|
39
|
+
type: OptionType.String,
|
|
40
|
+
required: false,
|
|
41
|
+
choices: [
|
|
42
|
+
PackageManagerName.Npm,
|
|
43
|
+
PackageManagerName.Yarn
|
|
44
|
+
],
|
|
45
|
+
default: PackageManagerName.Npm
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'pull-request-title',
|
|
49
|
+
description: 'Pull request title template',
|
|
50
|
+
type: OptionType.String,
|
|
51
|
+
required: false,
|
|
52
|
+
default: 'chore(deps): {{level}} update {{{packageName}}} to v{{newVersion}}'
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: 'reviewers',
|
|
56
|
+
description: 'User names to request reviews',
|
|
57
|
+
type: OptionType.StringArray,
|
|
58
|
+
required: false
|
|
59
|
+
}
|
|
60
|
+
]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { program } from 'commander'
|
|
2
|
+
import pkg from '../../package.json'
|
|
3
|
+
import { cliOptions } from './cliOptions'
|
|
4
|
+
import {
|
|
5
|
+
isOptions,
|
|
6
|
+
type Options
|
|
7
|
+
} from './Options'
|
|
8
|
+
import { toCommanderOption } from './toCommanderOption'
|
|
9
|
+
|
|
10
|
+
// TODO: add test
|
|
11
|
+
export const initOptions = (): Options => {
|
|
12
|
+
program.version(pkg.version)
|
|
13
|
+
cliOptions
|
|
14
|
+
.map(toCommanderOption)
|
|
15
|
+
.forEach(option => program.addOption(option))
|
|
16
|
+
program.parse(process.argv)
|
|
17
|
+
const options = program.opts()
|
|
18
|
+
|
|
19
|
+
if (!isOptions(options)) {
|
|
20
|
+
throw new Error(`Failed to parse command-line options. options=${JSON.stringify(options)}`)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return options
|
|
24
|
+
}
|