Added test to ensure that release notes are parsed properly Updated to latest dependencies to fix security vulnerability Updated GH Actions Workflow to run test before updating tag Updated README.md to reflect proper whatsnew documentation.
126 lines
4.0 KiB
JavaScript
126 lines
4.0 KiB
JavaScript
'use strict'
|
|
var url = require('url')
|
|
var gitHosts = require('./git-host-info.js')
|
|
var GitHost = module.exports = require('./git-host.js')
|
|
|
|
var protocolToRepresentationMap = {
|
|
'git+ssh:': 'sshurl',
|
|
'git+https:': 'https',
|
|
'ssh:': 'sshurl',
|
|
'git:': 'git'
|
|
}
|
|
|
|
function protocolToRepresentation (protocol) {
|
|
return protocolToRepresentationMap[protocol] || protocol.slice(0, -1)
|
|
}
|
|
|
|
var authProtocols = {
|
|
'git:': true,
|
|
'https:': true,
|
|
'git+https:': true,
|
|
'http:': true,
|
|
'git+http:': true
|
|
}
|
|
|
|
var cache = {}
|
|
|
|
module.exports.fromUrl = function (giturl, opts) {
|
|
if (typeof giturl !== 'string') return
|
|
var key = giturl + JSON.stringify(opts || {})
|
|
|
|
if (!(key in cache)) {
|
|
cache[key] = fromUrl(giturl, opts)
|
|
}
|
|
|
|
return cache[key]
|
|
}
|
|
|
|
function fromUrl (giturl, opts) {
|
|
if (giturl == null || giturl === '') return
|
|
var url = fixupUnqualifiedGist(
|
|
isGitHubShorthand(giturl) ? 'github:' + giturl : giturl
|
|
)
|
|
var parsed = parseGitUrl(url)
|
|
var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)'))
|
|
var matches = Object.keys(gitHosts).map(function (gitHostName) {
|
|
try {
|
|
var gitHostInfo = gitHosts[gitHostName]
|
|
var auth = null
|
|
if (parsed.auth && authProtocols[parsed.protocol]) {
|
|
auth = decodeURIComponent(parsed.auth)
|
|
}
|
|
var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null
|
|
var user = null
|
|
var project = null
|
|
var defaultRepresentation = null
|
|
if (shortcutMatch && shortcutMatch[1] === gitHostName) {
|
|
user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2])
|
|
project = decodeURIComponent(shortcutMatch[3])
|
|
defaultRepresentation = 'shortcut'
|
|
} else {
|
|
if (parsed.host && parsed.host !== gitHostInfo.domain && parsed.host.replace(/^www[.]/, '') !== gitHostInfo.domain) return
|
|
if (!gitHostInfo.protocols_re.test(parsed.protocol)) return
|
|
if (!parsed.path) return
|
|
var pathmatch = gitHostInfo.pathmatch
|
|
var matched = parsed.path.match(pathmatch)
|
|
if (!matched) return
|
|
/* istanbul ignore else */
|
|
if (matched[1] !== null && matched[1] !== undefined) {
|
|
user = decodeURIComponent(matched[1].replace(/^:/, ''))
|
|
}
|
|
project = decodeURIComponent(matched[2])
|
|
defaultRepresentation = protocolToRepresentation(parsed.protocol)
|
|
}
|
|
return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts)
|
|
} catch (ex) {
|
|
/* istanbul ignore else */
|
|
if (ex instanceof URIError) {
|
|
} else throw ex
|
|
}
|
|
}).filter(function (gitHostInfo) { return gitHostInfo })
|
|
if (matches.length !== 1) return
|
|
return matches[0]
|
|
}
|
|
|
|
function isGitHubShorthand (arg) {
|
|
// Note: This does not fully test the git ref format.
|
|
// See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
|
|
//
|
|
// The only way to do this properly would be to shell out to
|
|
// git-check-ref-format, and as this is a fast sync function,
|
|
// we don't want to do that. Just let git fail if it turns
|
|
// out that the commit-ish is invalid.
|
|
// GH usernames cannot start with . or -
|
|
return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg)
|
|
}
|
|
|
|
function fixupUnqualifiedGist (giturl) {
|
|
// necessary for round-tripping gists
|
|
var parsed = url.parse(giturl)
|
|
if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) {
|
|
return parsed.protocol + '/' + parsed.host
|
|
} else {
|
|
return giturl
|
|
}
|
|
}
|
|
|
|
function parseGitUrl (giturl) {
|
|
var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/)
|
|
if (!matched) return url.parse(giturl)
|
|
return {
|
|
protocol: 'git+ssh:',
|
|
slashes: true,
|
|
auth: matched[1],
|
|
host: matched[2],
|
|
port: null,
|
|
hostname: matched[2],
|
|
hash: matched[4],
|
|
search: null,
|
|
query: null,
|
|
pathname: '/' + matched[3],
|
|
path: '/' + matched[3],
|
|
href: 'git+ssh://' + matched[1] + '@' + matched[2] +
|
|
'/' + matched[3] + (matched[4] || '')
|
|
}
|
|
}
|