mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 09:40:21 +00:00
Revert every commit made while sleep-deprived
JFC, I have no sense of boundaries when exhausted. Reverts:6669270e84[CRAP: part Ⅱ] Reverts:13f83372a2[@vmg decides] Reverts:4fadaf80e0[CRAP: part Ⅰ] ... which are all moot points, since this is a topic-branch that's being squash-merged, and this commit exists only for @lildude's sick amusement (and the off-chance parts of it are worth salvaging).
This commit is contained in:
@@ -1,24 +1,75 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "optparse"
|
||||
require_relative "./helpers/all"
|
||||
require "open3"
|
||||
|
||||
usage = <<-EOH
|
||||
Usage:
|
||||
ROOT = File.expand_path("../../", __FILE__)
|
||||
|
||||
|
||||
# Break a repository URL into its separate components
|
||||
def parse_url(input)
|
||||
hosts = "github\.com|bitbucket\.org|gitlab\.com"
|
||||
|
||||
# HTTPS/HTTP link pointing to recognised hosts
|
||||
if input =~ /^(?:https?:\/\/)?(?:[^.@]+@)?(?:www\.)?(#{hosts})\/([^\/]+)\/([^\/]+)/i
|
||||
{ host: $1.downcase(), user: $2, repo: $3.sub(/\.git$/, "") }
|
||||
# SSH
|
||||
elsif input =~ /^git@(#{hosts}):([^\/]+)\/([^\/]+)\.git$/i
|
||||
{ host: $1.downcase(), user: $2, repo: $3 }
|
||||
# provider:user/repo
|
||||
elsif input =~ /^(github|bitbucket|gitlab):\/?([^\/]+)\/([^\/]+)\/?$/i
|
||||
{ host: $1.downcase(), user: $2, repo: $3 }
|
||||
# user/repo - Common GitHub shorthand
|
||||
elsif input =~ /^\/?([^\/]+)\/([^\/]+)\/?$/
|
||||
{ host: "github.com", user: $1, repo: $2 }
|
||||
else
|
||||
raise "Unsupported URL: #{input}"
|
||||
end
|
||||
end
|
||||
|
||||
# Isolate the vendor-name component of a submodule path
|
||||
def parse_submodule(name)
|
||||
name =~ /^(?:.*(?:vendor\/)?grammars\/)?([^\/]+)/i
|
||||
path = "vendor/grammars/#{$1}"
|
||||
unless File.exist?("#{ROOT}/" + path)
|
||||
warn "Submodule '#{path}' does not exist. Aborting."
|
||||
exit 1
|
||||
end
|
||||
path
|
||||
end
|
||||
|
||||
# Print debugging feedback to STDOUT if running with --verbose
|
||||
def log(msg)
|
||||
puts msg if $verbose
|
||||
end
|
||||
|
||||
def command(*args)
|
||||
log "$ #{args.join(' ')}"
|
||||
output, status = Open3.capture2e(*args)
|
||||
if !status.success?
|
||||
output.each_line do |line|
|
||||
log " > #{line}"
|
||||
end
|
||||
warn "Command failed. Aborting."
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
usage = """Usage:
|
||||
#{$0} [-v|--verbose] [--replace grammar] url
|
||||
|
||||
Examples:
|
||||
#{$0} https://github.com/Alhadis/language-roff
|
||||
#{$0} --replace sublime-apl https://github.com/Alhadis/language-apl
|
||||
EOH
|
||||
"""
|
||||
|
||||
$compile = false
|
||||
$replace = nil
|
||||
$verbose = true
|
||||
$compile = false
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = usage
|
||||
opts.on("-q", "--quiet", "Do not print output unless there's a failure") do
|
||||
$quiet = true
|
||||
$verbose = false
|
||||
end
|
||||
opts.on("-rSUBMODULE", "--replace=SUBMODDULE", "Replace an existing grammar submodule.") do |name|
|
||||
$replace = name
|
||||
@@ -34,27 +85,29 @@ $url = ARGV[0]
|
||||
# No URL? Print a usage message and bail.
|
||||
unless $url
|
||||
warn usage
|
||||
exit 1
|
||||
exit 1;
|
||||
end
|
||||
|
||||
# Exit early if docker isn't installed or running.
|
||||
log "Checking Docker is installed and running"
|
||||
log "Checking docker is installed and running"
|
||||
command('docker', 'ps')
|
||||
|
||||
repo_new = GrammarSource.by_url $url
|
||||
# Ensure the given URL is an HTTPS link
|
||||
parts = parse_url $url
|
||||
https = "https://#{parts[:host]}/#{parts[:user]}/#{parts[:repo]}"
|
||||
repo_new = "vendor/grammars/#{parts[:repo]}"
|
||||
repo_old = parse_submodule($replace) if $replace
|
||||
|
||||
Dir.chdir(ROOT)
|
||||
|
||||
if $replace
|
||||
repo_old = GrammarSource.by_path $replace
|
||||
log "Deregistering: #{repo_old.path}"
|
||||
$removed = repo_old
|
||||
command('git', 'submodule', 'deinit', repo_old.path)
|
||||
command('git', 'rm', '-rf', repo_old.path)
|
||||
if repo_old
|
||||
log "Deregistering: #{repo_old}"
|
||||
command('git', 'submodule', 'deinit', repo_old)
|
||||
command('git', 'rm', '-rf', repo_old)
|
||||
command('script/grammar-compiler', 'update', '-f') if $compile
|
||||
end
|
||||
|
||||
log "Registering new submodule: #{repo_new.path}"
|
||||
log "Registering new submodule: #{repo_new}"
|
||||
command('git', 'submodule', 'add', '-f', https, repo_new)
|
||||
command('script/grammar-compiler', 'add', repo_new) if $compile
|
||||
|
||||
@@ -62,7 +115,6 @@ log "Confirming license"
|
||||
if repo_old
|
||||
command('script/licensed')
|
||||
else
|
||||
repo_new = File.absolute_path(repo_new)
|
||||
command('script/licensed', '--module', repo_new)
|
||||
end
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
require_relative "./grammar_list"
|
||||
require_relative "./grammar_source"
|
||||
require_relative "./host"
|
||||
require_relative "./submodule"
|
||||
require "open3"
|
||||
|
||||
$quiet = false
|
||||
|
||||
# Print debugging feedback to STDOUT if $verbose global is set
|
||||
def log(msg)
|
||||
puts msg unless $quiet
|
||||
end
|
||||
|
||||
def command(*args)
|
||||
log "$ #{args.join(' ')}"
|
||||
output, status = Open3.capture2e(*args)
|
||||
if !status.success?
|
||||
output.each_line do |line|
|
||||
log " > #{line}"
|
||||
end
|
||||
warn "Command failed. Aborting."
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
ROOT = File.expand_path "../../../", __FILE__
|
||||
|
||||
# Expand a file path relative to Linguist's base directory
|
||||
def repo_path(path)
|
||||
path = path.sub /^#{Regexp.escape ROOT}\/?/, ""
|
||||
"#{ROOT}/#{path}"
|
||||
end
|
||||
|
||||
def exists?(path)
|
||||
File.exist? repo_path(path)
|
||||
end
|
||||
|
||||
def read(path)
|
||||
File.read repo_path(path)
|
||||
end
|
||||
|
||||
def write(path, data)
|
||||
File.write repo_path(path), data
|
||||
end
|
||||
@@ -1,75 +0,0 @@
|
||||
require_relative "./grammar_source"
|
||||
require_relative "./submodule"
|
||||
require_relative "./helpers"
|
||||
require "bundler/setup"
|
||||
require "linguist"
|
||||
require "json"
|
||||
require "yaml"
|
||||
|
||||
class GrammarList
|
||||
|
||||
ROOT = File.expand_path "../../../", __FILE__
|
||||
|
||||
def initialize
|
||||
@submodules = Submodule.list
|
||||
@language_names = load_languages()
|
||||
@sources = load_sources()
|
||||
end
|
||||
|
||||
# Grab the name of each language, sorted case-insensitively
|
||||
def load_languages
|
||||
Linguist::Language.all.map(&:name).sort do |a, b|
|
||||
a.downcase() <=> b.downcase()
|
||||
end
|
||||
end
|
||||
|
||||
# Load grammars.yml
|
||||
def load_sources
|
||||
sources = {}
|
||||
YAML.load_file("#{ROOT}/grammars.yml").each do |path, scopes|
|
||||
scopes.each { |scope| sources[scope] = @submodules[path] }
|
||||
end
|
||||
sources
|
||||
end
|
||||
|
||||
# Format list as Markdown
|
||||
def to_markdown
|
||||
markdown = ""
|
||||
@language_names.each do |item|
|
||||
lang = Linguist::Language["#{item}"]
|
||||
scope = lang.tm_scope
|
||||
next if scope == "none"
|
||||
path = @sources[scope] || scope
|
||||
case path
|
||||
when "https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz"
|
||||
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"
|
||||
short_url = "genshi.edgewall.org/query"
|
||||
long_url = "https://genshi.edgewall.org/query"
|
||||
when "vendor/grammars/oz-tmbundle/Syntaxes/Oz.tmLanguage"
|
||||
short_url = "eregon/oz-tmbundle"
|
||||
long_url = "https://github.com/eregon/oz-tmbundle"
|
||||
else
|
||||
submodule = @submodules[@sources[scope].chomp("/")]
|
||||
next unless submodule
|
||||
short_url = submodule[:short]
|
||||
long_url = submodule[:url]
|
||||
end
|
||||
markdown += "- **#{item}:** [#{short_url}](#{long_url})\n"
|
||||
end
|
||||
markdown
|
||||
end
|
||||
|
||||
def update_lists
|
||||
# Update .gitsubmodules
|
||||
sorted = @sources.sort { |a,b| a[0] <=> b[0] }.collect{ |i| i[1] }
|
||||
File.write "#{ROOT}/.gitmodules", sorted
|
||||
|
||||
# Update the file displaying the reader-friendly list of grammar repos
|
||||
readme = "#{ROOT}/vendor/README.md"
|
||||
preamble = File.read(readme).match(/\A.+?<!--.+?-->\n/ms)
|
||||
list = self.to_markdown
|
||||
File.write(readme, preamble.to_s + list)
|
||||
end
|
||||
end
|
||||
@@ -1,88 +0,0 @@
|
||||
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
|
||||
@@ -1,57 +0,0 @@
|
||||
# Hostname, which can be expressed with or without a TLD
|
||||
class Host
|
||||
attr_accessor :name, :tld
|
||||
alias_method :short, :name
|
||||
alias_method :long, :to_s
|
||||
|
||||
INSTANCES = {}
|
||||
|
||||
def initialize(input)
|
||||
if input =~ /^(.+)\.([^.]+)$/
|
||||
@name = $1.downcase
|
||||
@tld = $2.downcase
|
||||
else
|
||||
@name = input.downcase
|
||||
@tld = ""
|
||||
end
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
if other.responds_to?(name)
|
||||
@name == other.name
|
||||
else
|
||||
@name == other_to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Short-name with colon appended
|
||||
def prefix
|
||||
@prefix || "#{@name}:"
|
||||
end
|
||||
|
||||
# Hostname including TLD
|
||||
def to_s
|
||||
"#{@name}.#{@tld}"
|
||||
end
|
||||
|
||||
def to_regexp
|
||||
name = Regexp.escape @name
|
||||
tld = Regexp.escape @tld
|
||||
Regexp.new("#{name}(?:\\.#{tld})?")
|
||||
end
|
||||
|
||||
def self.define(input)
|
||||
INSTANCES[input] ||= Host.new(input)
|
||||
end
|
||||
|
||||
# Whitelist of trusted hosting providers
|
||||
:github =
|
||||
:bitbucket = self.define("bitbucket.org")
|
||||
:gitlab = self.define("gitlab.com")
|
||||
:github.prefix = ""
|
||||
WHITELIST = {
|
||||
:github => self.define("github.com")
|
||||
}
|
||||
:github, :bitbucket, :gitlab].freeze
|
||||
WHITELIST[:"github.com"].prefix = ""
|
||||
end
|
||||
@@ -1,90 +0,0 @@
|
||||
require_relative "./grammar_source"
|
||||
require_relative "./all"
|
||||
|
||||
# Public: Represents a registered Git submodule in use by Linguist.
|
||||
#
|
||||
# Any updates to this class should consider submodules which aren't
|
||||
# grammar-related, such as CodeMirror. See also: GrammarSource
|
||||
#
|
||||
# Examples
|
||||
#
|
||||
# Submodule.new('vendor/CodeMirror', {url: "codemirror/CodeMirror"})
|
||||
# # => #<Submodule url="https://github.com/codemirror/CodeMirror.git">
|
||||
#
|
||||
# Submodule.for_grammar('vendor/grammars/language-roff')
|
||||
# # => #<Submodule url="https://github.com/Alhadis/language-roff.git">
|
||||
#
|
||||
class Submodule
|
||||
attr_accessor :id, :attr
|
||||
|
||||
def initialize(id, attr = {})
|
||||
@id = id
|
||||
@attr = attr
|
||||
@attr[:path] ||= @id
|
||||
|
||||
# If a grammar submodule, store a pointer to source
|
||||
if /^vendor\/grammars/.test attr[:url]
|
||||
@grammar = GrammarSource.by_url attr[:url]
|
||||
end
|
||||
end
|
||||
|
||||
def <=>(other)
|
||||
@id <=> other.id
|
||||
end
|
||||
|
||||
# Is the submodule registered with Git and checked out locally?
|
||||
def registered?
|
||||
@configured? and @exists?
|
||||
end
|
||||
|
||||
# Is the submodule registered with Git?
|
||||
def configured?
|
||||
system "git", "config", "submodule.#{@id}.url"
|
||||
end
|
||||
|
||||
# Has the submodule been checked out locally?
|
||||
def exists?
|
||||
exists?(@id)
|
||||
end
|
||||
|
||||
# Format an entry to use in `.gitmodules`
|
||||
def to_s
|
||||
attr = @attr.to_a.map do |key, value|
|
||||
"\t#{key} = #{value}"
|
||||
end
|
||||
<<~EOS
|
||||
[submodule "#{@id}"]
|
||||
#{ attr.sort.join "\n" }
|
||||
EOS
|
||||
end
|
||||
|
||||
# Define a GrammarSource for an existing registered submodule.
|
||||
#
|
||||
# path - path of submodule as used by .gitmodules
|
||||
def self.for_grammar(path)
|
||||
path =~ /^(?:.*(?:vendor\/)?grammars\/)?([^\/]+)/i
|
||||
path = "vendor/grammars/#{$1}"
|
||||
unless exists?(path)
|
||||
raise "Submodule '#{path}' does not exist"
|
||||
end
|
||||
self.list.by_id[:path]
|
||||
end
|
||||
|
||||
# Load the contents of .gitmodules
|
||||
def self.list
|
||||
if @list.nil?
|
||||
all = []
|
||||
ids = {}
|
||||
pattern = /^\[submodule\s*"([^"]+)"\]$\n((?:^(?!\[).+(?:\n|$))+)/is
|
||||
read_file(".gitmodules").scan(pattern) do |id, data|
|
||||
attr = {}
|
||||
data.match(/^\s*(?<key>[^\s=]+)\s*=\s*(?<value>.+)$/m) do |match|
|
||||
attr[match[:key]] = match[:value].strip
|
||||
end
|
||||
all << ids[id] = self.new(id, attr)
|
||||
end
|
||||
@list = {all: all.sort, by_id: ids}
|
||||
end
|
||||
@list
|
||||
end
|
||||
end
|
||||
@@ -1,80 +0,0 @@
|
||||
require_relative "./host"
|
||||
|
||||
# Public: Helper methods for resolving various URL notations
|
||||
class RepoURL
|
||||
|
||||
def initialize(attr = {})
|
||||
@host = Host.define(attr[:host])
|
||||
@author = attr[:user] || attr[:author]
|
||||
@name = attr[:repo] || attr[:name]
|
||||
@short = attr[:short_url]
|
||||
@long = attr[:long_url]
|
||||
end
|
||||
|
||||
# Shortened representation of URL: `[provider:]user/repo`
|
||||
def short
|
||||
@short || "#{@host.prefix}#{@author}/#{@name}"
|
||||
end
|
||||
|
||||
def to_s
|
||||
"https://#{@host.}"
|
||||
end
|
||||
|
||||
# Split a URL into named subcomponents
|
||||
def self.parse(url)
|
||||
self.match_https(url) ||
|
||||
self.match_ssh(url) ||
|
||||
self.match_shorthand(url) ||
|
||||
self.match_implicit(url)
|
||||
end
|
||||
|
||||
# Match a well-formed HTTP or HTTPS address
|
||||
def self.match_https(url)
|
||||
if match = url.match(/
|
||||
^ (?<protocol> https? :\/\/ )?
|
||||
(?<userauth> [^@.]+ @ )?
|
||||
(?<subdomain> www \. )?
|
||||
(?<host> #{HOSTS} )
|
||||
\/ (?<user> [^\/]+ )
|
||||
\/ (?<repo> [^\/]+ )
|
||||
/xi)
|
||||
match[:repo].sub! /\.git$/, ""
|
||||
self.new(match)
|
||||
end
|
||||
end
|
||||
|
||||
# Match an SSH address starting with `git@`
|
||||
def self.match_ssh(url)
|
||||
if match = url.match(/
|
||||
^ git@
|
||||
(?<host> #{HOSTS}) :
|
||||
(?<user> [^\/]+) \/
|
||||
(?<repo> [^\/]+) \.git $
|
||||
/xi)
|
||||
self.new(match)
|
||||
end
|
||||
end
|
||||
|
||||
# Match `provider:user/repo`
|
||||
def self.match_shorthand(url)
|
||||
if match = url.match(/
|
||||
^ (?<host> #{HOSTS}) : \/?
|
||||
(?<user> [^\/]+) \/
|
||||
(?<repo> [^\/]+) \/? $
|
||||
/xi)
|
||||
self.new(match)
|
||||
end
|
||||
end
|
||||
|
||||
# Match `user/repo` shorthand, assumed to be GitHub
|
||||
def self.match_implicit(url)
|
||||
if match = url.match(/
|
||||
^ \/? (?<user>[^\/]+)
|
||||
\/ (?<repo>[^\/]+)
|
||||
\/? $
|
||||
/xi)
|
||||
match[:host] = "github.com"
|
||||
self.new(match)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,102 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require_relative "./helpers/grammar_list"
|
||||
require "bundler/setup"
|
||||
require "linguist"
|
||||
require "json"
|
||||
require "yaml"
|
||||
|
||||
class GrammarList
|
||||
|
||||
ROOT = File.expand_path "../../", __FILE__
|
||||
|
||||
def initialize
|
||||
@submodules = load_submodules()
|
||||
@sources = load_sources()
|
||||
@language_names = load_languages()
|
||||
end
|
||||
|
||||
# Load .gitmodules
|
||||
def load_submodules
|
||||
submodules = {}
|
||||
submodule_file = File.read("#{ROOT}/.gitmodules")
|
||||
pattern = /^\[submodule\s*"([^"]+)"\]$\n((?:^(?!\[).+(?:\n|$))+)/is
|
||||
submodule_file.scan(pattern) do |id, attr|
|
||||
submod = {}
|
||||
submod[:path] = $1 if attr =~ /^\s*path\s*=\s*(.+)$/
|
||||
submod[:url] = $1 if attr =~ /^\s*url\s*=\s*(.+)$/
|
||||
submod[:url].gsub!(/\.git$/, "")
|
||||
submod[:short] = shorten(submod[:url])
|
||||
submodules["#{id}"] = submod
|
||||
end
|
||||
submodules
|
||||
end
|
||||
|
||||
# Grab the name of each language, sorted case-insensitively
|
||||
def load_languages
|
||||
Linguist::Language.all.map(&:name).sort do |a, b|
|
||||
a.downcase() <=> b.downcase()
|
||||
end
|
||||
end
|
||||
|
||||
# Load grammars.yml
|
||||
def load_sources
|
||||
sources = {}
|
||||
grammars = YAML.load_file("#{ROOT}/grammars.yml")
|
||||
grammars.each do |path, scopes|
|
||||
scopes.each { |scope| sources[scope] = path }
|
||||
end
|
||||
sources
|
||||
end
|
||||
|
||||
# Shorten a repository URL
|
||||
def shorten(url)
|
||||
if url =~ /^https?:\/\/(?:www\.)?github\.com\/([^\/]+\/[^\/]+)/i
|
||||
$1
|
||||
elsif url =~ /^https?:\/\/(?:www\.)?(bitbucket|gitlab)\.(?:com|org)\/([^\/]+\/[^\/]+)/i
|
||||
"#{$1.downcase()}:#{$2}"
|
||||
else
|
||||
url.replace(/^https?:\/\/(?:www\.)?/i, "")
|
||||
end
|
||||
end
|
||||
|
||||
# Markdown: Generate grammar list
|
||||
def to_markdown
|
||||
markdown = ""
|
||||
@language_names.each do |item|
|
||||
lang = Linguist::Language["#{item}"]
|
||||
scope = lang.tm_scope
|
||||
next if scope == "none"
|
||||
path = @sources[scope] || scope
|
||||
case path
|
||||
when "https://bitbucket.org/Clams/sublimesystemverilog/get/default.tar.gz"
|
||||
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"
|
||||
short_url = "genshi.edgewall.org/query"
|
||||
long_url = "https://genshi.edgewall.org/query"
|
||||
when "vendor/grammars/oz-tmbundle/Syntaxes/Oz.tmLanguage"
|
||||
short_url = "eregon/oz-tmbundle"
|
||||
long_url = "https://github.com/eregon/oz-tmbundle"
|
||||
else
|
||||
submodule = @submodules[@sources[scope].chomp("/")]
|
||||
next unless submodule
|
||||
short_url = submodule[:short]
|
||||
long_url = submodule[:url]
|
||||
end
|
||||
markdown += "- **#{item}:** [#{short_url}](#{long_url})\n"
|
||||
end
|
||||
|
||||
markdown
|
||||
end
|
||||
|
||||
# Update the file displaying the reader-friendly list of grammar repos
|
||||
def update_readme
|
||||
readme = "#{ROOT}/vendor/README.md"
|
||||
preamble = File.read(readme).match(/\A.+?<!--.+?-->\n/ms)
|
||||
list = self.to_markdown
|
||||
File.write(readme, preamble.to_s + list)
|
||||
end
|
||||
end
|
||||
|
||||
list = GrammarList.new
|
||||
if ARGV.include? "--print"
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "optparse"
|
||||
require_relative "./helpers/submodule"
|
||||
|
||||
ROOT = File.expand_path "../../", __FILE__
|
||||
|
||||
|
||||
# Extract and sort a list of submodules
|
||||
def sort_entries(file_data)
|
||||
submodules = []
|
||||
file_data.scan(/(^\[submodule[^\n]+\n)((?:\t[^\n]+\n)+)/).each do |head, body|
|
||||
path = body.match(/^\tpath\s*=\s*\K(.+)$/)[0]
|
||||
submodules << [path, head + body]
|
||||
end
|
||||
submodules.sort! { |a,b| a[0] <=> b[0] }
|
||||
submodules.collect { |i| i[1] }
|
||||
end
|
||||
|
||||
|
||||
usage = <<-EOH
|
||||
Usage:
|
||||
@@ -14,7 +28,6 @@ Examples:
|
||||
EOH
|
||||
|
||||
$testing = false
|
||||
|
||||
OptionParser.new do |opts|
|
||||
opts.banner = usage
|
||||
opts.on("-h", "--help") do
|
||||
@@ -26,11 +39,12 @@ OptionParser.new do |opts|
|
||||
end
|
||||
end.parse!
|
||||
|
||||
unsorted = read ".gitmodules"
|
||||
sorted = Submodule.list.join
|
||||
|
||||
unsorted = File.read("#{ROOT}/.gitmodules")
|
||||
sorted = sort_entries(unsorted).join
|
||||
|
||||
if $testing
|
||||
exit unsorted == sorted
|
||||
else
|
||||
write ".gitmodules", sorted
|
||||
File.write "#{ROOT}/.gitmodules", sorted
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user