Skip to content

Commit 792ad9c

Browse files
authored
Fix to resolve package.jsons from file, not process
Closes GH-39. Closes GH-41. Reviewed-by: Titus Wormer <tituswormer@gmail.com> Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com>
1 parent b512f0b commit 792ad9c

4 files changed

Lines changed: 180 additions & 168 deletions

File tree

lib/get-repo-from-package.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,20 @@
33
*/
44

55
import fs from 'fs'
6-
import process from 'process'
76
import path from 'path'
87

98
/**
109
* Get the repository from `package.json`.
1110
*
11+
* @param {string} cwd
1212
* @returns {string|undefined}
1313
*/
14-
export function getRepoFromPackage() {
14+
export function getRepoFromPackage(cwd) {
1515
/** @type {PackageJson|undefined} */
1616
let pkg
1717

1818
try {
19-
pkg = JSON.parse(
20-
String(fs.readFileSync(path.join(process.cwd(), 'package.json')))
21-
)
19+
pkg = JSON.parse(String(fs.readFileSync(path.join(cwd, 'package.json'))))
2220
} catch {}
2321

2422
const repository =

lib/index.js

Lines changed: 153 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,22 @@ const mentionRegex = new RegExp(
139139
* @type {import('unified').Plugin<[Options?]|void[], Root>}
140140
*/
141141
export default function remarkGithub(options = {}) {
142-
const repository = options.repository || getRepoFromPackage()
142+
return (tree, vfile) => {
143+
const repository = options.repository || getRepoFromPackage(vfile.cwd)
143144

144-
// Parse the URL: See the tests for all possible kinds.
145-
const repositoryMatch = repoRegex.exec(repository || '')
145+
// Parse the URL: See the tests for all possible kinds.
146+
const repositoryMatch = repoRegex.exec(repository || '')
146147

147-
if (!repositoryMatch) {
148-
throw new Error('Missing or invalid `repository` field in `options`')
149-
}
148+
if (!repositoryMatch) {
149+
throw new Error('Missing or invalid `repository` field in `options`')
150+
}
150151

151-
/** @type {RepositoryInfo} */
152-
const repositoryInfo = {user: repositoryMatch[1], project: repositoryMatch[2]}
152+
/** @type {RepositoryInfo} */
153+
const repositoryInfo = {
154+
user: repositoryMatch[1],
155+
project: repositoryMatch[2]
156+
}
153157

154-
return (tree) => {
155158
findAndReplace(
156159
tree,
157160
[
@@ -210,174 +213,174 @@ export default function remarkGithub(options = {}) {
210213

211214
node.children = children
212215
})
213-
}
214-
215-
/**
216-
* @param {BuildUrlValues} values
217-
* @returns {string|false}
218-
*/
219-
function buildUrl(values) {
220-
if (options.buildUrl) return options.buildUrl(values, defaultBuildUrl)
221-
return defaultBuildUrl(values)
222-
}
223216

224-
/**
225-
* @type {ReplaceFunction}
226-
* @param {string} value
227-
* @param {string} username
228-
* @param {Match} match
229-
*/
230-
function replaceMention(value, username, match) {
231-
if (
232-
/[\w`]/.test(match.input.charAt(match.index - 1)) ||
233-
/[/\w`]/.test(match.input.charAt(match.index + value.length)) ||
234-
denyMention.has(username)
235-
) {
236-
return false
217+
/**
218+
* @param {BuildUrlValues} values
219+
* @returns {string|false}
220+
*/
221+
function buildUrl(values) {
222+
if (options.buildUrl) return options.buildUrl(values, defaultBuildUrl)
223+
return defaultBuildUrl(values)
237224
}
238225

239-
const url = buildUrl({type: 'mention', user: username})
226+
/**
227+
* @type {ReplaceFunction}
228+
* @param {string} value
229+
* @param {string} username
230+
* @param {Match} match
231+
*/
232+
function replaceMention(value, username, match) {
233+
if (
234+
/[\w`]/.test(match.input.charAt(match.index - 1)) ||
235+
/[/\w`]/.test(match.input.charAt(match.index + value.length)) ||
236+
denyMention.has(username)
237+
) {
238+
return false
239+
}
240240

241-
if (!url) return false
241+
const url = buildUrl({type: 'mention', user: username})
242242

243-
/** @type {StaticPhrasingContent} */
244-
let node = {type: 'text', value}
243+
if (!url) return false
245244

246-
if (options.mentionStrong !== false) {
247-
node = {type: 'strong', children: [node]}
248-
}
245+
/** @type {StaticPhrasingContent} */
246+
let node = {type: 'text', value}
249247

250-
return {type: 'link', title: null, url, children: [node]}
251-
}
248+
if (options.mentionStrong !== false) {
249+
node = {type: 'strong', children: [node]}
250+
}
252251

253-
/**
254-
* @type {ReplaceFunction}
255-
* @param {string} value
256-
* @param {string} no
257-
* @param {Match} match
258-
*/
259-
function replaceIssue(value, no, match) {
260-
if (
261-
/\w/.test(match.input.charAt(match.index - 1)) ||
262-
/\w/.test(match.input.charAt(match.index + value.length))
263-
) {
264-
return false
252+
return {type: 'link', title: null, url, children: [node]}
265253
}
266254

267-
const url = buildUrl({type: 'issue', ...repositoryInfo, no})
255+
/**
256+
* @type {ReplaceFunction}
257+
* @param {string} value
258+
* @param {string} no
259+
* @param {Match} match
260+
*/
261+
function replaceIssue(value, no, match) {
262+
if (
263+
/\w/.test(match.input.charAt(match.index - 1)) ||
264+
/\w/.test(match.input.charAt(match.index + value.length))
265+
) {
266+
return false
267+
}
268268

269-
return url
270-
? {type: 'link', title: null, url, children: [{type: 'text', value}]}
271-
: false
272-
}
269+
const url = buildUrl({type: 'issue', ...repositoryInfo, no})
273270

274-
/**
275-
* @type {ReplaceFunction}
276-
* @param {string} value
277-
* @param {string} a
278-
* @param {string} b
279-
* @param {Match} match
280-
*/
281-
function replaceHashRange(value, a, b, match) {
282-
if (
283-
/[^\t\n\r (@[{]/.test(match.input.charAt(match.index - 1)) ||
284-
/\w/.test(match.input.charAt(match.index + value.length)) ||
285-
denyHash.has(value)
286-
) {
287-
return false
271+
return url
272+
? {type: 'link', title: null, url, children: [{type: 'text', value}]}
273+
: false
288274
}
289275

290-
const url = buildUrl({
291-
type: 'compare',
292-
...repositoryInfo,
293-
base: a,
294-
compare: b
295-
})
296-
297-
return url
298-
? {
299-
type: 'link',
300-
title: null,
301-
url,
302-
children: [{type: 'inlineCode', value: abbr(a) + '...' + abbr(b)}]
303-
}
304-
: false
305-
}
276+
/**
277+
* @type {ReplaceFunction}
278+
* @param {string} value
279+
* @param {string} a
280+
* @param {string} b
281+
* @param {Match} match
282+
*/
283+
function replaceHashRange(value, a, b, match) {
284+
if (
285+
/[^\t\n\r (@[{]/.test(match.input.charAt(match.index - 1)) ||
286+
/\w/.test(match.input.charAt(match.index + value.length)) ||
287+
denyHash.has(value)
288+
) {
289+
return false
290+
}
306291

307-
/**
308-
* @type {ReplaceFunction}
309-
* @param {string} value
310-
* @param {Match} match
311-
*/
312-
function replaceHash(value, match) {
313-
if (
314-
/[^\t\n\r (@[{.]/.test(match.input.charAt(match.index - 1)) ||
315-
// For some weird reason GH does link two dots, but not one 🤷‍♂️
316-
(match.input.charAt(match.index - 1) === '.' &&
317-
match.input.charAt(match.index - 2) !== '.') ||
318-
/\w/.test(match.input.charAt(match.index + value.length)) ||
319-
denyHash.has(value)
320-
) {
321-
return false
292+
const url = buildUrl({
293+
type: 'compare',
294+
...repositoryInfo,
295+
base: a,
296+
compare: b
297+
})
298+
299+
return url
300+
? {
301+
type: 'link',
302+
title: null,
303+
url,
304+
children: [{type: 'inlineCode', value: abbr(a) + '...' + abbr(b)}]
305+
}
306+
: false
322307
}
323308

324-
const url = buildUrl({type: 'commit', ...repositoryInfo, hash: value})
309+
/**
310+
* @type {ReplaceFunction}
311+
* @param {string} value
312+
* @param {Match} match
313+
*/
314+
function replaceHash(value, match) {
315+
if (
316+
/[^\t\n\r (@[{.]/.test(match.input.charAt(match.index - 1)) ||
317+
// For some weird reason GH does link two dots, but not one 🤷‍♂️
318+
(match.input.charAt(match.index - 1) === '.' &&
319+
match.input.charAt(match.index - 2) !== '.') ||
320+
/\w/.test(match.input.charAt(match.index + value.length)) ||
321+
denyHash.has(value)
322+
) {
323+
return false
324+
}
325325

326-
return url
327-
? {
328-
type: 'link',
329-
title: null,
330-
url,
331-
children: [{type: 'inlineCode', value: abbr(value)}]
332-
}
333-
: false
334-
}
326+
const url = buildUrl({type: 'commit', ...repositoryInfo, hash: value})
335327

336-
/**
337-
* @type {ReplaceFunction}
338-
* @param {string} $0
339-
* @param {string} user
340-
* @param {string} specificProject
341-
* @param {string} no
342-
* @param {string} hash
343-
* @param {Match} match
344-
*/
345-
// eslint-disable-next-line max-params
346-
function replaceReference($0, user, specificProject, no, hash, match) {
347-
if (
348-
/[^\t\n\r (@[{]/.test(match.input.charAt(match.index - 1)) ||
349-
/\w/.test(match.input.charAt(match.index + $0.length))
350-
) {
351-
return false
328+
return url
329+
? {
330+
type: 'link',
331+
title: null,
332+
url,
333+
children: [{type: 'inlineCode', value: abbr(value)}]
334+
}
335+
: false
352336
}
353337

354-
const project = specificProject || repositoryInfo.project
355-
const url = no
356-
? buildUrl({type: 'issue', user, project, no})
357-
: buildUrl({type: 'commit', user, project, hash})
338+
/**
339+
* @type {ReplaceFunction}
340+
* @param {string} $0
341+
* @param {string} user
342+
* @param {string} specificProject
343+
* @param {string} no
344+
* @param {string} hash
345+
* @param {Match} match
346+
*/
347+
// eslint-disable-next-line max-params
348+
function replaceReference($0, user, specificProject, no, hash, match) {
349+
if (
350+
/[^\t\n\r (@[{]/.test(match.input.charAt(match.index - 1)) ||
351+
/\w/.test(match.input.charAt(match.index + $0.length))
352+
) {
353+
return false
354+
}
358355

359-
if (!url) return false
356+
const project = specificProject || repositoryInfo.project
357+
const url = no
358+
? buildUrl({type: 'issue', user, project, no})
359+
: buildUrl({type: 'commit', user, project, hash})
360360

361-
/** @type {StaticPhrasingContent[]} */
362-
const nodes = []
363-
let value = ''
361+
if (!url) return false
364362

365-
if (project !== repositoryInfo.project) {
366-
value += user + '/' + project
367-
} else if (user !== repositoryInfo.user) {
368-
value += user
369-
}
363+
/** @type {StaticPhrasingContent[]} */
364+
const nodes = []
365+
let value = ''
370366

371-
if (no) {
372-
value += '#' + no
373-
} else {
374-
value += '@'
375-
nodes.push({type: 'inlineCode', value: abbr(hash)})
376-
}
367+
if (project !== repositoryInfo.project) {
368+
value += user + '/' + project
369+
} else if (user !== repositoryInfo.user) {
370+
value += user
371+
}
377372

378-
nodes.unshift({type: 'text', value})
373+
if (no) {
374+
value += '#' + no
375+
} else {
376+
value += '@'
377+
nodes.push({type: 'inlineCode', value: abbr(hash)})
378+
}
379379

380-
return {type: 'link', title: null, url, children: nodes}
380+
nodes.unshift({type: 'text', value})
381+
382+
return {type: 'link', title: null, url, children: nodes}
383+
}
381384
}
382385
}
383386

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"type-coverage": "^2.0.0",
6969
"type-fest": "^2.0.0",
7070
"typescript": "^4.0.0",
71+
"vfile": "^5.0.0",
7172
"xo": "^0.50.0"
7273
},
7374
"scripts": {

0 commit comments

Comments
 (0)