Files
linguist/script/helpers/grammar_source.rb
2018-04-13 22:54:18 +10:00

89 lines
2.9 KiB
Ruby

require_relative "./all"
require_relative "./host"
require_relative "./unique"
# Represents the source of a language grammar
#
# NOTE: Sources are mostly - but not always - connected to a
# Submodule. Some ad-hoc exceptions exist which aren't
# connected with a Git repository.
#
class GrammarSource < Unique
# RegExp for matching trusted domain hosts
HOSTS = Regexp.union(Host.whitelist)
def initialize(attr = {})
@name = attr[:name] || nil # Unique name of repository
@host = attr[:host] || nil # Hostname of repo's provider
@author = attr[:author] || nil # Username of repo's author
@url = attr[:url] || nil # Resolved absolute URL
# Resolve missing properties
@url ||= "https://#{@host.long}/#{@author}/#{@name}.git"
@short_url ||= @host.prefix + @author + "/#{@name}"
@long_url ||= @url
end
# Format source as a Markdown link
def to_markdown
"[#{self.url.short}](#{self.url.long})"
end
# Define a grammar source by its upstream URL.
#
# url - an HTTPS, HTTP, or SSH address accepted by git-remote(1)
# Only domains listed in HOSTS are accepted; unrecognised
# hostnames or invalid URLs will raise an ArgumentError.
#
# Assumption: Repo URLs will never include subdomains.
# We only check for a possible `www`, nothing else.
def self.by_url(url)
case url
when "https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz"
self.define({
name: "sublimesystemverilog",
host: Host.define("bitbucket.org"),
author: "Clams",
url: url,
short_url: "bitbucket:Clams/sublimesystemverilog",
long_url: "https://bitbucket.org/Clams/sublimesystemverilog"
})
when "https://svn.edgewall.org/repos/genshi/contrib/textmate/Genshi.tmbundle/Syntaxes/Markup%20Template%20%28XML%29.tmLanguage"
self.define({
name: "Genshi.tmbundle",
host: Host.define("genshi.edgewall.org"),
url: url,
short_url: "genshi.edgewall.org/query",
long_url: "https://genshi.edgewall.org/query"
})
when "vendor/grammars/oz-tmbundle/Syntaxes/Oz.tmLanguage"
self.define({
name: "oz-tmbundle",
host: Host.define("github.com"),
author: "eregon",
url: url,
short_url: "eregon/oz-tmbundle",
long_url: "https://github.com/eregon/oz-tmbundle"
})
else
if parsed = URL.parse(url)
self.define(parsed)
else
raise ArgumentError, "Unsupported URL: #{url}"
end
end
end
# Define a new GrammarSource, or reference an existing one
def self.define(attr)
unless attr[:url]
host = Host.define(attr[:host])
author = attr[:author]
name = attr[:name]
attr[:url] = "https://#{host.long}/#{author}/#{name}.git"
end
BY_URL[attr[:url]] ||= self.new(attr)
end
end