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