jekyll-github-metadata-2.13.0/0000755000004100000410000000000013610717561016164 5ustar www-datawww-datajekyll-github-metadata-2.13.0/jekyll-github-metadata.gemspec0000644000004100000410000000577513610717561024077 0ustar www-datawww-data######################################################### # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- # stub: jekyll-github-metadata 2.13.0 ruby lib Gem::Specification.new do |s| s.name = "jekyll-github-metadata".freeze s.version = "2.13.0" s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] s.authors = ["Parker Moore".freeze] s.date = "2020-01-15" s.email = ["parkrmoore@gmail.com".freeze] s.files = ["lib/jekyll-github-metadata.rb".freeze, "lib/jekyll-github-metadata/client.rb".freeze, "lib/jekyll-github-metadata/edit-link-tag.rb".freeze, "lib/jekyll-github-metadata/metadata_drop.rb".freeze, "lib/jekyll-github-metadata/owner.rb".freeze, "lib/jekyll-github-metadata/pages.rb".freeze, "lib/jekyll-github-metadata/repository.rb".freeze, "lib/jekyll-github-metadata/repository_compat.rb".freeze, "lib/jekyll-github-metadata/repository_finder.rb".freeze, "lib/jekyll-github-metadata/sanitizer.rb".freeze, "lib/jekyll-github-metadata/site_github_munger.rb".freeze, "lib/jekyll-github-metadata/value.rb".freeze, "lib/jekyll-github-metadata/version.rb".freeze] s.homepage = "https://github.com/jekyll/github-metadata".freeze s.licenses = ["MIT".freeze] s.rubygems_version = "2.5.2.1".freeze s.summary = "The site.github namespace".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, ["< 5.0", ">= 3.4"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_runtime_dependency(%q.freeze, ["!= 4.4.0", "~> 4.0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, [">= 0"]) s.add_development_dependency(%q.freeze, ["~> 3.8.0"]) s.add_development_dependency(%q.freeze, ["~> 0.5.0"]) else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["< 5.0", ">= 3.4"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["!= 4.4.0", "~> 4.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["~> 3.8.0"]) s.add_dependency(%q.freeze, ["~> 0.5.0"]) end else s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["< 5.0", ">= 3.4"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["!= 4.4.0", "~> 4.0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, [">= 0"]) s.add_dependency(%q.freeze, ["~> 3.8.0"]) s.add_dependency(%q.freeze, ["~> 0.5.0"]) end end jekyll-github-metadata-2.13.0/lib/0000755000004100000410000000000013610717561016732 5ustar www-datawww-datajekyll-github-metadata-2.13.0/lib/jekyll-github-metadata.rb0000644000004100000410000000432413610717561023612 0ustar www-datawww-data# frozen_string_literal: true require "jekyll" require "octokit" if Jekyll.env == "development" begin require "dotenv" Dotenv.load rescue LoadError Jekyll.logger.debug "Dotenv not found. Skipping" end end module Jekyll module GitHubMetadata autoload :Client, "jekyll-github-metadata/client" autoload :EditLinkTag, "jekyll-github-metadata/edit-link-tag" autoload :MetadataDrop, "jekyll-github-metadata/metadata_drop" autoload :Owner, "jekyll-github-metadata/owner" autoload :Pages, "jekyll-github-metadata/pages" autoload :Repository, "jekyll-github-metadata/repository" autoload :RepositoryFinder, "jekyll-github-metadata/repository_finder" autoload :RepositoryCompat, "jekyll-github-metadata/repository_compat" autoload :Sanitizer, "jekyll-github-metadata/sanitizer" autoload :Value, "jekyll-github-metadata/value" autoload :VERSION, "jekyll-github-metadata/version" NoRepositoryError = RepositoryFinder::NoRepositoryError require_relative "jekyll-github-metadata/site_github_munger" if Jekyll.const_defined? :Site class << self attr_reader :repository_finder attr_writer :client, :logger def site repository_finder.site end def environment Jekyll.env end def logger @logger ||= Jekyll.logger end def log(severity, message) if logger.method(severity).arity.abs >= 2 logger.public_send(severity, "GitHub Metadata:", message.to_s) else logger.public_send(severity, "GitHub Metadata: #{message}") end end def client @client ||= Client.new end def repository @repository ||= GitHubMetadata::Repository.new(repository_finder.nwo).tap do |repo| log :debug, "Generating for #{repo.nwo}" end end def site=(new_site) reset! @repository_finder = GitHubMetadata::RepositoryFinder.new(new_site) end def reset! @logger = @client = @repository = @nwo = @site = nil end end end end Liquid::Template.register_tag("github_edit_link", Jekyll::GitHubMetadata::EditLinkTag) jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/0000755000004100000410000000000013610717561023262 5ustar www-datawww-datajekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/pages.rb0000644000004100000410000000564113610717561024714 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata class Pages class << self DEFAULTS = { "PAGES_ENV" => "development", "PAGES_API_URL" => "https://api.github.com", "PAGES_HELP_URL" => "https://help.github.com", "PAGES_GITHUB_HOSTNAME" => "github.com", "PAGES_PAGES_HOSTNAME" => "github.io", "SSL" => "false", "SUBDOMAIN_ISOLATION" => "false", "PAGES_PREVIEW_HTML_URL" => nil, "PAGE_BUILD_ID" => nil, }.freeze # Whether the GitHub instance supports HTTPS # Note: this will be the same as how sites are served in Enterprise, # but may be different from how sites are served on GitHub.com. # See Repository#url_scheme def ssl? env_var("SSL") == "true" || test? end def scheme ssl? ? "https" : "http" end def subdomain_isolation? env_var("SUBDOMAIN_ISOLATION").eql? "true" end def test? env == "test" end def dotcom? env == "dotcom" end def enterprise? env == "enterprise" end def development? env == "development" end def custom_domains_enabled? dotcom? || test? end def env env_var "PAGES_ENV", ENV["JEKYLL_ENV"] end def repo_pages_html_url_preview? env_var "PAGES_PREVIEW_HTML_URL" end def github_url if dotcom? || github_hostname == "github.com" "https://github.com" else "#{scheme}://#{github_hostname}" end end def api_url trim_last_slash env_var("PAGES_API_URL", ENV["API_URL"]) end def help_url trim_last_slash env_var("PAGES_HELP_URL", ENV["HELP_URL"]) end def github_hostname trim_last_slash env_var("PAGES_GITHUB_HOSTNAME", ENV["GITHUB_HOSTNAME"]) end def pages_hostname intermediate_default = ENV["PAGES_HOSTNAME"] intermediate_default ||= "localhost:4000" if development? trim_last_slash env_var("PAGES_PAGES_HOSTNAME", intermediate_default) end def page_build? !env_var("PAGE_BUILD_ID").to_s.empty? end def configuration (methods - Object.methods - [:configuration]).sort.each_with_object({}) do |meth, memo| memo[meth.to_s] = public_send(meth) end end private def env_var(key, intermediate_default = nil) !ENV[key].to_s.empty? ? ENV[key] : (intermediate_default || DEFAULTS[key]) end def trim_last_slash(url) if url[-1] == "/" url[0..-2] else url end end end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/version.rb0000644000004100000410000000014613610717561025275 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata VERSION = "2.13.0" end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/sanitizer.rb0000644000004100000410000000336713610717561025630 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata module Sanitizer extend self # Sanitize an object. # When the resource is either `false`, `true`, `nil` or a number, # it returns the resource as-is. When the resource is an array, # it maps over the entire array, sanitizing each of its values. # When the resource responds to the #to_hash method, it returns # the value of #sanitize_resource (see below). If none of the # aforementioned conditions are met, the return value of #to_s # is used. # # resource - an Object # # Returns the sanitized resource. # rubocop:disable Metrics/CyclomaticComplexity def sanitize(resource) case resource when Array resource.map { |item| sanitize(item) } when Numeric, Time resource when FalseClass false when TrueClass true when NilClass nil when String resource else if resource.respond_to?(:to_hash) sanitize_resource(resource) else resource.to_s end end end # rubocop:enable Metrics/CyclomaticComplexity # Sanitize the Sawyer Resource or Hash # Note: the object must respond to :to_hash for this to work. # Consider using #sanitize instead of this method directly. # # resource - an Object which responds to :to_hash # # Returns the sanitized sawyer resource or hash as a hash. def sanitize_resource(resource) resource.to_hash.each_with_object({}) do |(k, v), result| result[k.to_s] = sanitize(v) result end end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/client.rb0000644000004100000410000001057113610717561025071 0ustar www-datawww-data# frozen_string_literal: true require "digest" module Jekyll module GitHubMetadata class Client InvalidMethodError = Class.new(NoMethodError) BadCredentialsError = Class.new(StandardError) # Whitelisted API calls. API_CALLS = Set.new(%w( repository organization user repository? pages contributors releases latest_release list_repos organization_public_members )) def initialize(options = nil) @client = build_octokit_client(options) end def safe_require(gem_name) require gem_name true rescue LoadError false end def default_octokit_options { :api_endpoint => Jekyll::GitHubMetadata::Pages.api_url, :web_endpoint => Jekyll::GitHubMetadata::Pages.github_url, :auto_paginate => true, } end def build_octokit_client(options = nil) options ||= {} options.merge!(pluck_auth_method) unless options.key?(:access_token) Octokit::Client.new(default_octokit_options.merge(options)) end def accepts_client_method?(method_name) API_CALLS.include?(method_name.to_s) && @client.respond_to?(method_name) end def respond_to_missing?(method_name, include_private = false) accepts_client_method?(method_name) || super end def method_missing(method_name, *args, &block) method = method_name.to_s if accepts_client_method?(method_name) key = cache_key(method_name, args) GitHubMetadata.log :debug, "Calling @client.#{method}(#{args.map(&:inspect).join(", ")})" cache[key] ||= save_from_errors { @client.public_send(method_name, *args, &block) } elsif @client.respond_to?(method_name) raise InvalidMethodError, "#{method_name} is not whitelisted on #{inspect}" else super end end # NOTE: Faraday's error classes has been promoted to under Faraday module from v1.0.0. # This patch aims to prevent on locking specific version of Faraday. FARADAY_FAILED_CONNECTION = begin Faraday::Error::ConnectionFailed rescue NameError Faraday::ConnectionFailed end def save_from_errors(default = false) unless internet_connected? GitHubMetadata.log :warn, "No internet connection. GitHub metadata may be missing or incorrect." return default end yield @client rescue Octokit::Unauthorized raise BadCredentialsError, "The GitHub API credentials you provided aren't valid." rescue FARADAY_FAILED_CONNECTION, Octokit::TooManyRequests => e GitHubMetadata.log :warn, e.message default rescue Octokit::NotFound default end def inspect "#<#{self.class.name} @client=#{client_inspect} @internet_connected=#{internet_connected?}>" end def authenticated? !@client.access_token.to_s.empty? end def internet_connected? return @internet_connected if defined?(@internet_connected) require "resolv" begin Resolv::DNS.open do |dns| dns.timeouts = 2 dns.getaddress("api.github.com") end @internet_connected = true rescue Resolv::ResolvError @internet_connected = false end end private def client_inspect if @client.nil? "nil" else "#<#{@client.class.name} (#{"un" unless authenticated?}authenticated)>" end end # rubocop:disable Metrics/CyclomaticComplexity def pluck_auth_method if ENV["JEKYLL_GITHUB_TOKEN"] || Octokit.access_token { :access_token => ENV["JEKYLL_GITHUB_TOKEN"] || Octokit.access_token } elsif !ENV["NO_NETRC"] && File.exist?(File.join(ENV["HOME"], ".netrc")) && safe_require("netrc") { :netrc => true } else GitHubMetadata.log :warn, "No GitHub API authentication could be found." \ " Some fields may be missing or have incorrect data." {}.freeze end end # rubocop:enable Metrics/CyclomaticComplexity def cache_key(method, *args) Digest::SHA1.hexdigest(method.to_s + args.join(", ")) end def cache @cache ||= {} end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/value.rb0000644000004100000410000000300313610717561024717 0ustar www-datawww-data# frozen_string_literal: true require "json" module Jekyll module GitHubMetadata class Value extend Forwardable def_delegators :render, :+, :to_s, :to_json, :eql?, :hash attr_reader :key, :value def initialize(*args) case args.size when 1 @key = "{anonymous}" @value = args.first when 2 @key = args.first.to_s @value = args.last else raise ArgumentError, "#{args.size} args given but expected 1 or 2" end end def render return @rendered if defined? @rendered @rendered = @value = Sanitizer.sanitize(call_or_value) rescue RuntimeError, NameError => e Jekyll::GitHubMetadata.log :error, "Error processing value '#{key}':" raise e end def to_liquid case render when nil, true, false, Hash, String, Numeric, Array value else to_json end end private # Calls the value Proc with the appropriate number of arguments # or returns the raw value if it's a literal def call_or_value return value unless value.respond_to?(:call) case value.arity when 0 value.call when 1 value.call(GitHubMetadata.client) when 2 value.call(GitHubMetadata.client, GitHubMetadata.repository) else raise ArgumentError, "Whoa, arity of 0, 1, or 2 please in your procs." end end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/repository.rb0000644000004100000410000001355013610717561026032 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata class Repository attr_reader :nwo, :owner, :name # Defines an instance method that delegates to a hash's key # # hash - a symbol representing the instance method to delegate to. The # instance method should return a hash or respond to #[] # key - the key to call within the hash # method - (optional) the instance method the key should be aliased to. # If not specified, defaults to the hash key # # Returns a symbol representing the instance method def self.def_hash_delegator(hash, key, method) define_method(method) do public_send(hash)[key.to_s] end end extend Forwardable def_hash_delegator :repo_info, :license, :license def_hash_delegator :repo_info, :language, :language def_hash_delegator :repo_info, :description, :tagline def_hash_delegator :repo_info, :has_downloads, :show_downloads? def_hash_delegator :repo_info, :private, :private? def_hash_delegator :repo_info, :archived, :archived? def_hash_delegator :repo_info, :disabled, :disabled? def_hash_delegator :latest_release, :url, :latest_release_url def_hash_delegator :source, :branch, :git_ref def_delegator :uri, :host, :domain def_delegator :uri, :scheme, :url_scheme def_delegator :uri, :path, :baseurl def initialize(name_with_owner) @nwo = name_with_owner @owner = nwo.split("/").first @name = nwo.split("/").last end def repo_compat @repo_compat ||= Jekyll::GitHubMetadata::RepositoryCompat.new(self) end def repo_info @repo_info ||= begin options = { :accept => "application/vnd.github.drax-preview+json" } (Value.new("repo_info", proc { |c| c.repository(nwo, options) }).render || {}) end end def repo_pages_info @repo_pages_info ||= (Value.new("repo_pages_info", proc { |c| c.pages(nwo, repo_pages_info_opts) }).render || {}) end def repo_pages_info_opts if Pages.repo_pages_html_url_preview? { :accept => "application/vnd.github.mister-fantastic-preview+json" } else {} end end def owner_metadata @owner_metadata ||= Jekyll::GitHubMetadata::Owner.new(owner) end def owner_url "#{Pages.github_url}/#{owner}" end def owner_gravatar_url "#{owner_url}.png" end def repo_clone_url "#{repository_url}.git" end def repository_url "#{owner_url}/#{name}" end def zip_url "#{repository_url}/zipball/#{git_ref}" end def tar_url "#{repository_url}/tarball/#{git_ref}" end def releases_url "#{repository_url}/releases" end def issues_url "#{repository_url}/issues" if repo_info["has_issues"] end def wiki_url "#{repository_url}/wiki" if repo_info["has_wiki"] end def organization_repository? memoize_value :@is_organization_repository, Value.new("organization_repository?", proc { |c| !!c.organization(owner) }) end def owner_public_repositories options = { :type => "public", :accept => "application/vnd.github.mercy-preview+json", } memoize_value :@owner_public_repositories, Value.new("owner_public_repositories", proc { |c| c.list_repos(owner, options) }) end def organization_public_members memoize_value :@organization_public_members, Value.new("organization_public_members", proc do |c| c.organization_public_members(owner) if organization_repository? end) end def contributors memoize_value :@contributors, Value.new("contributors", proc { |c| c.contributors(nwo) }) end def releases memoize_value :@releases, Value.new("releases", proc { |c| c.releases(nwo) }) end def latest_release memoize_value :@latest_release, Value.new("latest_release", proc { |c| c.latest_release(nwo) }) end def source repo_pages_info["source"] || repo_compat.source end def project_page? !user_page? end def github_repo? !Pages.enterprise? && owner.eql?("github") end def primary? if Pages.enterprise? name.downcase == "#{owner.to_s.downcase}.#{Pages.github_hostname}" else user_page_domains.include? name.downcase end end alias_method :user_page?, :primary? def user_page_domains domains = [default_user_domain] domains.push "#{owner}.github.com".downcase unless Pages.enterprise? domains end def default_user_domain if github_repo? "#{owner}.#{Pages.github_hostname}".downcase elsif Pages.enterprise? Pages.pages_hostname.downcase else "#{owner}.#{Pages.pages_hostname}".downcase end end def cname return nil unless Pages.custom_domains_enabled? repo_pages_info["cname"] end def html_url @html_url ||= (repo_pages_info["html_url"] || repo_compat.pages_url).chomp("/") end def uri @uri ||= URI(html_url) end def url_without_path uri.dup.tap { |u| u.path = "" }.to_s end def stargazers_count repo_pages_info["stargazers_count"] || 0 end def forks_count repo_pages_info["forks_count"] || 0 end private def memoize_value(var_name, value) return instance_variable_get(var_name) if instance_variable_defined?(var_name) instance_variable_set(var_name, value.render) end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/repository_compat.rb0000644000004100000410000000420313610717561027370 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata class RepositoryCompat attr_reader :repo def initialize(repo) @repo = repo end # In enterprise, the site's scheme will be the same as the instance's # In dotcom, this will be `https` for GitHub-owned sites that end with # `.github.com` and will be `http` for all other sites. # Note: This is not the same as *instance*'s scheme, which may differ def url_scheme if Pages.enterprise? Pages.scheme elsif repo.owner == "github" && domain.end_with?(".github.com") "https" else "http" end end def user_domain domain = repo.default_user_domain repo.user_page_domains.each do |user_repo| candidate_nwo = "#{repo.owner}/#{user_repo}" next unless Jekyll::GitHubMetadata.client.repository?(candidate_nwo) domain = Jekyll::GitHubMetadata::Repository.new(candidate_nwo).repo_compat.domain end domain end def pages_url return enterprise_url unless Pages.custom_domains_enabled? if repo.cname || repo.primary? "#{url_scheme}://#{domain}" else URI.join("#{url_scheme}://#{domain}", repo.name).to_s end end alias_method :html_url, :pages_url def domain @domain ||= if !Pages.custom_domains_enabled? Pages.github_hostname elsif repo.cname # explicit CNAME repo.cname elsif repo.primary? # user/org repo repo.default_user_domain else # project repo user_domain end end def source { "branch" => (repo.user_page? ? "master" : "gh-pages"), "path" => "/", } end private def enterprise_url path = repo.user_page? ? repo.owner : repo.nwo if Pages.subdomain_isolation? URI.join("#{Pages.scheme}://#{Pages.pages_hostname}/", path).to_s else URI.join("#{Pages.github_url}/pages/", path).to_s end end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/site_github_munger.rb0000644000004100000410000000456013610717561027477 0ustar www-datawww-datarequire "jekyll" require "uri" module Jekyll module GitHubMetadata class SiteGitHubMunger extend Forwardable def_delegators Jekyll::GitHubMetadata, :site, :repository private :repository def initialize(site) Jekyll::GitHubMetadata.site = site end def munge! Jekyll::GitHubMetadata.log :debug, "Initializing..." # This is the good stuff. site.config["github"] = github_namespace add_title_and_description_fallbacks! add_url_and_baseurl_fallbacks! if should_add_url_fallbacks? end private def github_namespace case site.config["github"] when nil drop when Hash Jekyll::Utils.deep_merge_hashes(drop, site.config["github"]) else site.config["github"] end end def drop @drop ||= MetadataDrop.new(GitHubMetadata.site) end # Set `site.url` and `site.baseurl` if unset. def add_url_and_baseurl_fallbacks! site.config["url"] ||= Value.new("url", proc { |_c, r| r.url_without_path }) return unless should_set_baseurl? site.config["baseurl"] = Value.new("baseurl", proc { |_c, r| r.baseurl }) end def add_title_and_description_fallbacks! if should_warn_about_site_name? msg = "site.name is set in _config.yml, but many plugins and themes expect " msg << "site.title to be used instead. To avoid potential inconsistency, " msg << "Jekyll GitHub Metadata will not set site.title to the repository's name." Jekyll::GitHubMetadata.log :warn, msg else site.config["title"] ||= Value.new("title", proc { |_c, r| r.name }) end site.config["description"] ||= Value.new("description", proc { |_c, r| r.tagline }) end # Set the baseurl only if it is `nil` or `/` # Baseurls should never be "/". See http://bit.ly/2s1Srid def should_set_baseurl? site.config["baseurl"].nil? || site.config["baseurl"] == "/" end def should_add_url_fallbacks? Jekyll.env == "production" || Pages.page_build? end def should_warn_about_site_name? site.config["name"] && !site.config["title"] end end end end Jekyll::Hooks.register :site, :after_init do |site| Jekyll::GitHubMetadata::SiteGitHubMunger.new(site).munge! end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/edit-link-tag.rb0000644000004100000410000000725713610717561026253 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata class EditLinkTag < Liquid::Tag attr_reader :context # Defines an instance method that delegates to a hash's key # # hash_method - a symbol representing the instance method to delegate to. The # instance method should return a hash or respond to #[] # key - the key to call within the hash # method - (optional) the instance method the key should be aliased to. # If not specified, defaults to the hash key # default - (optional) value to return if value is nil (defaults to nil) # # Returns a symbol representing the instance method def self.def_hash_delegator(hash_method, key, method, default = nil) define_method(method) do hash = send(hash_method) if hash.respond_to? :[] hash[key.to_s] || default else default end end end MISSING_DATA_MSG = "Cannot generate edit URLs due to missing site.github data" LINK_TEXT_REGEX = %r!(?:\"(.*)\"|'(.*)')!.freeze extend Forwardable private def_hash_delegator :site, :github, :site_github, {} private def_hash_delegator :site_github, :repository_url, :repository_url private def_hash_delegator :site_github, :source, :source, {} private def_hash_delegator :source, :branch, :branch private def_hash_delegator :source, :path, :source_path private def_hash_delegator :page, :path, :page_path def render(context) @context = context if link_text link else uri.to_s end end private def link_text @link_text ||= begin matches = @markup.match LINK_TEXT_REGEX matches[1] || matches[2] if matches end end def link "#{link_text}" end def uri if parts.any?(&:nil?) Jekyll.logger.warn "JekyllEditLink: ", MISSING_DATA_MSG "" else Addressable::URI.join(*parts_normalized).normalize end end def parts memoize_conditionally { [repository_url, "edit/", branch, source_path, page_path] } end def parts_normalized memoize_conditionally do parts.map.with_index do |part, index| part = remove_leading_slash(part.to_s) part = ensure_trailing_slash(part) unless index == parts.length - 1 ensure_not_just_a_slash(part) end end end def page memoize_conditionally { context.registers[:page] } end # Utility function for compatibility with Jekyll 4.0 def memoize_conditionally if renderer_cached? yield else dispatcher = "@#{caller_locations(1..1).first.label}".to_sym if instance_variable_defined?(dispatcher) instance_variable_get(dispatcher) else instance_variable_set(dispatcher, yield) end end end # Utility function to detect Jekyll 4.0 def renderer_cached? @renderer_cached ||= context.registers[:site].liquid_renderer.respond_to?(:cache) end def site @site ||= context.registers[:site].site_payload["site"] end def remove_leading_slash(part) part.start_with?("/") ? part[1..-1] : part end def ensure_trailing_slash(part) part.end_with?("/") ? part : "#{part}/" end def ensure_not_just_a_slash(part) part == "/" ? "" : part end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/repository_finder.rb0000644000004100000410000000434313610717561027361 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata class RepositoryFinder NoRepositoryError = Class.new(Jekyll::Errors::FatalException) attr_reader :site def initialize(site) @site = site end # Public: fetches the repository name with owner to fetch metadata for. # In order of precedence, this method uses: # 1. the environment variable $PAGES_REPO_NWO # 2. 'repository' variable in the site config # 3. the 'origin' git remote's URL # # site - the Jekyll::Site being processed # # Return the name with owner (e.g. 'parkr/my-repo') or raises an # error if one cannot be found. def nwo @nwo ||= begin nwo_from_env || \ nwo_from_config || \ nwo_from_git_origin_remote || \ proc do raise NoRepositoryError, "No repo name found. " \ "Specify using PAGES_REPO_NWO environment variables, " \ "'repository' in your configuration, or set up an 'origin' " \ "git remote pointing to your github.com repository." end.call end end private def nwo_from_env ENV["PAGES_REPO_NWO"] end def nwo_from_config repo = site.config["repository"] repo if repo&.is_a?(String) && repo&.include?("/") end def git_remotes _process, output = Jekyll::Utils::Exec.run("git", "remote", "--verbose") output.to_s.strip.split("\n") rescue Errno::ENOENT => e Jekyll.logger.warn "Not Installed:", e.message [] end def git_remote_url git_remotes.grep(%r!\Aorigin\t!).map do |remote| remote.sub(%r!\Aorigin\t(.*) \([a-z]+\)!, "\\1") end.uniq.first || "" end def nwo_from_git_origin_remote return unless Jekyll.env == "development" || Jekyll.env == "test" matches = git_remote_url.chomp(".git").match github_remote_regex matches[2..3].join("/") if matches end def github_remote_regex github_host_regex = Regexp.escape(Jekyll::GitHubMetadata::Pages.github_hostname) %r!#{github_host_regex}(:|/)([\w-]+)/([\w\.-]+)! end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/metadata_drop.rb0000644000004100000410000001011213610717561026406 0ustar www-datawww-data# frozen_string_literal: true require "jekyll" require "forwardable" module Jekyll module GitHubMetadata class MetadataDrop < Jekyll::Drops::Drop extend Forwardable mutable true # See https://github.com/jekyll/jekyll/pull/6338 alias_method :invoke_drop, :[] def key?(key) return false if key.nil? return true if self.class.mutable? && mutations.key?(key) respond_to?(key) || fallback_data.key?(key) end def to_s require "json" JSON.pretty_generate to_h end alias_method :to_str, :to_s def content_methods super - %w(to_s to_str) end def keys super.sort end def_delegator Jekyll::GitHubMetadata::Pages, :env, :environment def_delegator Jekyll::GitHubMetadata::Pages, :env, :pages_env def_delegator Jekyll::GitHubMetadata::Pages, :github_hostname, :hostname def_delegator Jekyll::GitHubMetadata::Pages, :pages_hostname, :pages_hostname def_delegator Jekyll::GitHubMetadata::Pages, :api_url, :api_url def_delegator Jekyll::GitHubMetadata::Pages, :help_url, :help_url private def_delegator Jekyll::GitHubMetadata, :repository def_delegator :repository, :owner_public_repositories, :public_repositories def_delegator :repository, :organization_public_members, :organization_members def_delegator :repository, :name, :project_title def_delegator :repository, :tagline, :project_tagline def_delegator :repository, :owner_metadata, :owner def_delegator :repository, :owner, :owner_name def_delegator :repository, :owner_url, :owner_url def_delegator :repository, :owner_gravatar_url, :owner_gravatar_url def_delegator :repository, :repository_url, :repository_url def_delegator :repository, :nwo, :repository_nwo def_delegator :repository, :name, :repository_name def_delegator :repository, :zip_url, :zip_url def_delegator :repository, :tar_url, :tar_url def_delegator :repository, :repo_clone_url, :clone_url def_delegator :repository, :releases_url, :releases_url def_delegator :repository, :issues_url, :issues_url def_delegator :repository, :wiki_url, :wiki_url def_delegator :repository, :language, :language def_delegator :repository, :user_page?, :is_user_page def_delegator :repository, :project_page?, :is_project_page def_delegator :repository, :show_downloads?, :show_downloads def_delegator :repository, :html_url, :url def_delegator :repository, :baseurl, :baseurl def_delegator :repository, :contributors, :contributors def_delegator :repository, :releases, :releases def_delegator :repository, :latest_release, :latest_release def_delegator :repository, :private?, :private def_delegator :repository, :archived?, :archived def_delegator :repository, :disabled?, :disabled def_delegator :repository, :license, :license def_delegator :repository, :source, :source def versions return @versions if defined?(@versions) begin require "github-pages" @versions = GitHubPages.versions rescue LoadError @versions = {} end end def build_revision @build_revision ||= begin ENV["JEKYLL_BUILD_REVISION"] || `git rev-parse HEAD`.strip end end private # Nothing to see here. def fallback_data @fallback_data ||= {} end def mutations @mutations ||= {} end end end end jekyll-github-metadata-2.13.0/lib/jekyll-github-metadata/owner.rb0000644000004100000410000000526113610717561024745 0ustar www-datawww-data# frozen_string_literal: true module Jekyll module GitHubMetadata class Owner extend Forwardable # Defines an instance method that delegates to a hash's key # # hash - a symbol representing the instance method to delegate to. The # instance method should return a hash or respond to #[] # key - the key to call within the hash # method - (optional) the instance method the key should be aliased to. # If not specified, defaults to the hash key # # Returns a symbol representing the instance method def self.def_hash_delegators(hash, *methods) content_methods.concat(methods) methods.each do |method| define_method(method) do send(hash)[method.to_s] end end end def self.content_methods @content_methods ||= [] end # List of whitelisted keys. def_hash_delegators :owner_info, :avatar_url, :bio, :blog, :collaborators, :company, :created_at, :description, :email, :followers, :following, :has_organization_projects, :has_repository_projects, :hireable, :html_url, :id, :is_verified, :location, :login, :name, :node_id, :public_gists, :public_gists, :public_repos, :public_repos, :type, :updated_at attr_reader :owner_login def initialize(owner_login) @owner_login = owner_login end def to_h @to_h ||= self.class.content_methods .each_with_object({}) { |method, hash| hash[method.to_s] = public_send(method) } end alias_method :to_hash, :to_h def_delegator :to_h, :to_json, :to_json def_delegator :to_h, :to_liquid, :to_liquid def_delegator :to_h, :to_s, :to_s alias_method :to_str, :to_s private def owner_info @owner_info ||= begin Value.new( "owner", proc do |c| (c.organization(owner_login) || c.user(owner_login) || {}).to_h end ).render || {} end end end end end