kup-cli 0.1.2 → 0.1.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/README.md +3 -2
- package/lib/main.js +12 -1
- package/lib/repo.js +89 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,8 +75,9 @@ Kup 会把 `file.md` 文件的内容更新到 `foo/bar` 仓库的编号为 `123`
|
|
|
75
75
|
|
|
76
76
|
1. 调用命令行时指定的 `--repo` 参数。
|
|
77
77
|
1. Markdown 文件内的 [元数据](https://github.com/cssmagic/kup/issues/1) 的 `repo` 字段。
|
|
78
|
-
1. 当前项目的 `package.json` 文件内的 `kup.repo` 字段。Kup
|
|
79
|
-
1.
|
|
78
|
+
1. 当前项目的 `package.json` 文件内的 `kup.repo` 字段。Kup 会以 Markdown 文件所在目录为起点逐级向上寻找 `package.json` 文件。
|
|
79
|
+
1. 如果 `package.json` 文件内没有 `kup.repo` 字段,则 Kup 会尝试根据 `repository` 字段来猜测仓库名(在使用前会向用户确认)。
|
|
80
|
+
1. 如果以上方式都没有成功,则 Kup 会继续查找同级或上级目录中的 `.git/config` 文件,并尝试根据其中 `remote "origin"` 的 `url` 字段来猜测仓库名(在使用前会向用户确认)。
|
|
80
81
|
|
|
81
82
|
如果整个项目的同步目标都是同一个仓库,则建议采用 `kup.repo` 字段统一指定 `repo` 参数。
|
|
82
83
|
|
package/lib/main.js
CHANGED
|
@@ -56,7 +56,7 @@ async function main(argv) {
|
|
|
56
56
|
{
|
|
57
57
|
name: 'useGuessedRepo',
|
|
58
58
|
type: 'confirm',
|
|
59
|
-
message: `Kup guessed the GitHub repo "${ repoResult.repo }" from
|
|
59
|
+
message: `Kup guessed the GitHub repo "${ repoResult.repo }" from ${ getRepoSourceLabel(repoResult.source) }, use it?`,
|
|
60
60
|
default: true,
|
|
61
61
|
},
|
|
62
62
|
])
|
|
@@ -91,6 +91,17 @@ async function main(argv) {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
function getRepoSourceLabel(source = '') {
|
|
95
|
+
switch (source) {
|
|
96
|
+
case 'package.repository':
|
|
97
|
+
return 'package.json#repository'
|
|
98
|
+
case 'git.origin':
|
|
99
|
+
return '.git/config remote "origin"'
|
|
100
|
+
default:
|
|
101
|
+
return 'an inferred source'
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
94
105
|
export {
|
|
95
106
|
main,
|
|
96
107
|
}
|
package/lib/repo.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import fs from 'fs/promises'
|
|
1
2
|
import { findUp } from 'find-up'
|
|
2
3
|
import path from 'path'
|
|
3
4
|
|
|
@@ -6,38 +7,44 @@ import { validateRepo } from './validate.js'
|
|
|
6
7
|
|
|
7
8
|
async function getRepo(sourceFile = '') {
|
|
8
9
|
const json = await _getPkg(sourceFile)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
|
|
11
|
+
if (json) {
|
|
12
|
+
const packageRepo = _getRepoFromPkgKup(json)
|
|
13
|
+
if (packageRepo.repo) {
|
|
14
|
+
return {
|
|
15
|
+
repo: packageRepo.repo,
|
|
16
|
+
source: 'package',
|
|
17
|
+
needsConfirm: false,
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
|
-
}
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
if (!packageRepo.hasKupRepoField) {
|
|
22
|
+
const guessedRepo = _getRepoFromPkgRepo(json)
|
|
23
|
+
if (guessedRepo) {
|
|
24
|
+
return {
|
|
25
|
+
repo: guessedRepo,
|
|
26
|
+
source: 'package.repository',
|
|
27
|
+
needsConfirm: true,
|
|
28
|
+
}
|
|
29
|
+
}
|
|
23
30
|
}
|
|
24
31
|
}
|
|
25
32
|
|
|
26
|
-
const guessedRepo =
|
|
33
|
+
const guessedRepo = await _getRepoFromGit(sourceFile)
|
|
27
34
|
return {
|
|
28
35
|
repo: guessedRepo,
|
|
29
|
-
source: guessedRepo ? '
|
|
36
|
+
source: guessedRepo ? 'git.origin' : '',
|
|
30
37
|
needsConfirm: !!guessedRepo,
|
|
31
38
|
}
|
|
32
39
|
}
|
|
33
40
|
|
|
34
41
|
function _getRepoFromPkgKup(json) {
|
|
35
|
-
const
|
|
42
|
+
const hasKupRepoField = !!json?.kup && Object.prototype.hasOwnProperty.call(json.kup, 'repo')
|
|
36
43
|
const repo = json?.kup?.repo
|
|
37
44
|
const result = validateRepo(repo)
|
|
38
45
|
return {
|
|
39
46
|
repo: result.status ? repo : '',
|
|
40
|
-
|
|
47
|
+
hasKupRepoField,
|
|
41
48
|
}
|
|
42
49
|
}
|
|
43
50
|
function _getRepoFromPkgRepo(json) {
|
|
@@ -54,8 +61,18 @@ function _getRepoFromPkgRepo(json) {
|
|
|
54
61
|
|
|
55
62
|
return ''
|
|
56
63
|
}
|
|
57
|
-
async function _getRepoFromGit() {
|
|
58
|
-
|
|
64
|
+
async function _getRepoFromGit(sourceFile = '') {
|
|
65
|
+
const configFile = await _getGitConfigFile(sourceFile)
|
|
66
|
+
if (!configFile) return ''
|
|
67
|
+
|
|
68
|
+
let config = ''
|
|
69
|
+
try {
|
|
70
|
+
config = await readTextFile(configFile)
|
|
71
|
+
} catch {
|
|
72
|
+
return ''
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return _getRepoFromGitConfig(config)
|
|
59
76
|
}
|
|
60
77
|
|
|
61
78
|
async function _getPkg(sourceFile = '') {
|
|
@@ -81,6 +98,58 @@ async function _getPkg(sourceFile = '') {
|
|
|
81
98
|
return json
|
|
82
99
|
}
|
|
83
100
|
|
|
101
|
+
async function _getGitConfigFile(sourceFile = '') {
|
|
102
|
+
let cwd = sourceFile ? path.resolve(path.dirname(sourceFile)) : process.cwd()
|
|
103
|
+
while (true) {
|
|
104
|
+
const gitPath = path.join(cwd, '.git')
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const stats = await fs.stat(gitPath)
|
|
108
|
+
if (stats.isDirectory()) {
|
|
109
|
+
const configFile = path.join(gitPath, 'config')
|
|
110
|
+
try {
|
|
111
|
+
await fs.access(configFile)
|
|
112
|
+
return configFile
|
|
113
|
+
} catch {
|
|
114
|
+
return ''
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return ''
|
|
118
|
+
} catch {
|
|
119
|
+
const parent = path.dirname(cwd)
|
|
120
|
+
if (parent === cwd) return ''
|
|
121
|
+
cwd = parent
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function _getRepoFromGitConfig(config) {
|
|
127
|
+
if (typeof config !== 'string' || !config.trim()) return ''
|
|
128
|
+
|
|
129
|
+
const lines = config.split(/\r?\n/)
|
|
130
|
+
let inOriginRemote = false
|
|
131
|
+
for (const line of lines) {
|
|
132
|
+
const trimmed = line.trim()
|
|
133
|
+
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith(';')) continue
|
|
134
|
+
|
|
135
|
+
const sectionMatched = /^\[\s*(.*?)\s*\]$/.exec(trimmed)
|
|
136
|
+
if (sectionMatched) {
|
|
137
|
+
inOriginRemote = /^remote\s+"origin"$/i.test(sectionMatched[1])
|
|
138
|
+
continue
|
|
139
|
+
}
|
|
140
|
+
if (!inOriginRemote) continue
|
|
141
|
+
|
|
142
|
+
const entryMatched = /^([A-Za-z][\w-]*)\s*=\s*(.*?)\s*$/.exec(trimmed)
|
|
143
|
+
if (!entryMatched) continue
|
|
144
|
+
|
|
145
|
+
const key = entryMatched[1].toLowerCase()
|
|
146
|
+
const value = entryMatched[2]
|
|
147
|
+
if (key === 'url') return normalizeRepositoryToRepo(value)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return ''
|
|
151
|
+
}
|
|
152
|
+
|
|
84
153
|
function normalizeRepositoryToRepo(repository) {
|
|
85
154
|
if (typeof repository !== 'string') return ''
|
|
86
155
|
|
|
@@ -111,6 +180,7 @@ export {
|
|
|
111
180
|
getRepo,
|
|
112
181
|
_getRepoFromPkgKup as __getRepoFromPkgKup,
|
|
113
182
|
_getRepoFromPkgRepo as __getRepoFromPkgRepo,
|
|
114
|
-
|
|
183
|
+
_getRepoFromGit as __getRepoFromGit,
|
|
184
|
+
_getRepoFromGitConfig as __getRepoFromGitConfig,
|
|
115
185
|
normalizeRepositoryToRepo as __normalizeRepositoryToRepo,
|
|
116
186
|
}
|