lib/qb/repo/git.rb in qb-0.3.7 vs lib/qb/repo/git.rb in qb-0.3.8

- old
+ new

@@ -1,19 +1,45 @@ +# Requirements +# ======================================================================= + +# Stdlib +# ----------------------------------------------------------------------- + +# Deps +# ----------------------------------------------------------------------- require 'cmds' -require 'nrser/refinements/types' +# Project / Package +# ----------------------------------------------------------------------- + + +# Refinements +# ======================================================================= + +require 'nrser/refinements' +using NRSER + +require 'nrser/refinements/types' using NRSER::Types -module QB -module Repo +# Declarations +# ======================================================================= + +module QB; end +module QB::Repo; end + + +# Definitions +# ======================================================================= + # Encapsulate information about a Git repository and expose useful operations as # instance methods. # # The main entry point is {QB::Repo::Git.from_path}, which creates a # -class Git < NRSER::Meta::Props::Base +class QB::Repo::Git < NRSER::Meta::Props::Base GITHUB_SSH_URL_RE = /^git@github\.com\:(?<owner>.*)\/(?<name>.*)\.git$/ GITHUB_HTTPS_URL_RE = /^https:\/\/github\.com\/(?<owner>.*)\/(?<name>.*)\.git$/ class User < NRSER::Meta::Props::Base prop :name, type: t.maybe(t.str), default: nil @@ -91,23 +117,34 @@ # Class Methods # ===================================================================== - # @todo Document from_path method. + # Instantiate a {QB::Package::Git} resource for whatever Git repo `path` + # is in, or return `nil` if `path` is not in a Git repo. # - # @param [String, Pathname] input_path - # A path that is in the Git repo. + # @param [String, Pathname] path + # A path that may be in the Git repo. # + # @param [Boolean] use_github_api: + # When `true` will will contact the GitHub API for information to populate + # the {QB::Repo::Git#github} property for repos that have a GitHub origin + # URL. + # + # Otherwise we will just assume GitHub repos are private since it's the + # safe guess, resulting in a {QB::Repo::Git#github} value of + # `{private: true}`. + # # @return [QB::Repo::Git] + # If `path` is in a Git repo. # + # @return [nil] + # If `path` is not in a Git repo. + # # @raise [QB::FSStateError] # - If we can't find any existing directory to look in based on # `input_path`. - # - # - If the directory we do find to look in does not seems to be part of - # a Git repo. # def self.from_path path, use_github_api: false raw_input_path = path # Create a Pathname from the input @@ -127,13 +164,11 @@ # Change into the directory to make shell life easier Dir.chdir closest_dir do root_result = Cmds.capture "git rev-parse --show-toplevel" unless root_result.ok? - raise QB::FSStateError, - "Path #{ raw_input_path.inspect } does not appear to be in a " + - "Git repo (looked in #{ closest_dir.inspect })." + return nil end root = Pathname.new root_result.out.chomp user = User.new **NRSER.map_values(User.props.keys) {|key, _| @@ -215,24 +250,56 @@ end # chdir end # .from_path + # Instantiate a {QB::Package::Git} resource for whatever Git repo `path` + # is in, raising an error if it's not in one. + # + # @param [String, Pathname] path + # A path that is in the Git repo. + # + # @param use_github_api: see #from_path + # + # @return [QB::Repo::Git] + # + # @raise [QB::FSStateError] + # - If we can't find any existing directory to look in based on + # `input_path`. + # + # - If the directory we do find to look in does not seems to be part of + # a Git repo. + # + def from_path! path, use_github_api: false + from_path( path, use_github_api: use_github_api ).tap { |git| + if git.nil? + raise QB::FSStateError, + "Path #{ path.inspect } does not appear to be in a " + + "Git repo." + end + } + end # #from_path! + + # Props # ===================================================================== - prop :raw_input_path, type: t.maybe(t.union(Pathname, t.str)), default: nil - prop :root, type: Pathname + prop :raw_input_path, type: t.path, default: nil, to_data: :to_s + prop :root, type: t.pathname, to_data: :to_s prop :user, type: User prop :is_clean, type: t.bool prop :head, type: t.maybe(t.str), default: nil prop :branch, type: t.maybe(t.str), default: nil prop :origin, type: t.maybe(t.str), default: nil prop :owner, type: t.maybe(t.str), default: nil prop :name, type: t.maybe(t.str), default: nil prop :github, type: t.maybe(t.hash_), default: nil + + # Derived Properties + # --------------------------------------------------------------------- + prop :head_short, type: t.maybe(t.str), source: :head_short prop :full_name, type: t.maybe(t.str), source: :full_name prop :is_github, type: t.bool, source: :github? @@ -249,13 +316,17 @@ def github? !github.nil? end + + # Reading Repo State + # --------------------------------------------------------------------- + + # @return [Boolean] + # `false` if the repo has any uncommitted changes or untracked files. + # def clean? is_clean end -end # class Git - -end # module Repo -end # module QB +end # class QB::Repo::Git