Class: JayAPI::Git::Repository

Inherits:
Object
  • Object
show all
Defined in:
lib/jay_api/git/repository.rb

Overview

Represents a Git repository. Offers a set of methods to lazy clone a repository and update it when necessary. As well as a set of methods to work with the repository’s branches and files.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url:, clone_location: nil, clone_path: nil, logger: nil) ⇒ Repository

Creates a new instance of the class.

Parameters:

  • url (String, nil)

    The URL of the git repository. This parameter can be nil ONLY for repositories that already exist.

  • clone_location (String) (defaults to: nil)

    The path to the location where the repository should be cloned. (A new folder with the Repository’s name will be created INSIDE the given directory).

  • clone_path (String) (defaults to: nil)

    The path to the directory where the repository should be cloned. (The repository will be cloned DIRECTLY in this directory).

  • logger (Logging::Logger) (defaults to: nil)

    The logger for the class (as well as for the Git client).

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
41
# File 'lib/jay_api/git/repository.rb', line 32

def initialize(url:, clone_location: nil, clone_path: nil, logger: nil)
  raise ArgumentError, 'Either clone_location or clone_path must be given' unless clone_location || clone_path
  raise ArgumentError, 'Either clone_path or url must be given' unless url || clone_path

  @url = url
  @logger = logger || Logging.logger[self]
  @clone_path = Pathname.new(clone_path || File.join(clone_location, name))
  @clone_path = Pathname.pwd.join(@clone_path) unless @clone_path.absolute?
  @clone_location = @clone_path.dirname
end

Instance Attribute Details

#clone_locationObject (readonly)

Returns the value of attribute clone_location.



19
20
21
# File 'lib/jay_api/git/repository.rb', line 19

def clone_location
  @clone_location
end

#clone_pathObject (readonly)

Returns the value of attribute clone_path.



19
20
21
# File 'lib/jay_api/git/repository.rb', line 19

def clone_path
  @clone_path
end

#urlObject (readonly)

Returns the value of attribute url.



19
20
21
# File 'lib/jay_api/git/repository.rb', line 19

def url
  @url
end

Instance Method Details

#add_worktree(path:, branch: nil) ⇒ Git::Worktree

Adds a new worktree to the repository.

Parameters:

  • path (String)

    The path where the worktree should be created.

  • branch (String) (defaults to: nil)

    The branch that should be checked out in the working tree. If no branch is provided the current HEAD will be checked out in a new branch.

Returns:

  • (Git::Worktree)

    The object representing the newly created worktree.

Raises:

  • (ArgumentError)

    If the Repository cannot be opened.

  • (Git::GitExecuteError)

    If the repository cannot be cloned or if the worktree cannot be created.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



247
248
249
250
# File 'lib/jay_api/git/repository.rb', line 247

def add_worktree(path:, branch: nil)
  open_or_clone
  add_worktree!(path: path, branch: branch)
end

#add_worktree!(path:, branch: nil) ⇒ Git::Worktree

Adds a new worktree to the repository.

Parameters:

  • path (String)

    The path where the worktree should be created.

  • branch (String) (defaults to: nil)

    The branch that should be checked out in the working tree. If no branch is provided the current HEAD will be checked out in a new branch.

Returns:

  • (Git::Worktree)

    The object representing the newly created worktree.

Raises:



263
264
265
266
267
268
# File 'lib/jay_api/git/repository.rb', line 263

def add_worktree!(path:, branch: nil)
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  repository.worktree(path, branch).add
  repository.worktree(path)
end

#branchesGit::Branches

Returns a Git::Branches object with the collection of branches in the repository.

Returns:

  • (Git::Branches)

    The collection of branches in the repository.

Raises:

  • (ArgumentError)

    If the Repository cannot be opened.

  • (Git::GitExecuteError)

    If the repository cannot be cloned.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



151
152
153
154
# File 'lib/jay_api/git/repository.rb', line 151

def branches
  open_or_clone
  branches!
end

#branches!Git::Branches

Returns a Git::Branches object with the collection of branches in the repository.

Returns:

  • (Git::Branches)

    The collection of branches in the repository.

Raises:



162
163
164
165
166
# File 'lib/jay_api/git/repository.rb', line 162

def branches!
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  repository.branches
end

#checkout(commit) ⇒ Object

Checks out the specified commit. If the Repository is not yet initialized, then

it will be opened or cloned depending on whether the repository exists.

Parameters:

  • commit (String)

    The SHA1 representing the commit.



91
92
93
94
# File 'lib/jay_api/git/repository.rb', line 91

def checkout(commit)
  open_or_clone
  checkout!(commit)
end

#checkout!(commit) ⇒ Object

Checks out the specified commit.

Parameters:

  • commit (String)

    The SHA1 representing the commit.

Raises:



98
99
100
101
102
# File 'lib/jay_api/git/repository.rb', line 98

def checkout!(commit)
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  repository.checkout commit
end

#cloneObject Also known as: update

Clones the repository or updates it, if it already exists.

Raises:



58
59
60
# File 'lib/jay_api/git/repository.rb', line 58

def clone
  valid? ? update! : clone!
end

#clone!Object

Clones the repository. If the repository already exists the directory is completely removed and the repository cloned again.

Raises:



69
70
71
72
73
74
# File 'lib/jay_api/git/repository.rb', line 69

def clone!
  clone_path.rmtree if exist?
  clone_location.mkpath
  clone_repo
  self
end

#exist?Boolean

Returns True if the repository directory exists on the disk, false otherwise.

Returns:

  • (Boolean)

    True if the repository directory exists on the disk, false otherwise



45
46
47
# File 'lib/jay_api/git/repository.rb', line 45

def exist?
  clone_path.exist?
end

#log(objectish: nil, count: nil) ⇒ Git::Log

Returns a Git::Log object: The collection of commits in the current branch or under the specified reference (if given).

Parameters:

  • objectish (String) (defaults to: nil)

    A git reference. Normally this would be a branch’s name but it could also be a tag, the SHA1 for a specific commit or any other valid git reference.

  • count (Integer) (defaults to: nil)

    The maximum number of commits to return in the collection, if omitted all the commits will be returned.

Returns:

  • (Git::Log)

    A Git::Log object with the collection of commits.

Raises:

  • (ArgumentError)

    If the Repository cannot be opened.

  • (Git::GitExecuteError)

    If the repository cannot be cloned.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



213
214
215
216
# File 'lib/jay_api/git/repository.rb', line 213

def log(objectish: nil, count: nil)
  open_or_clone
  log!(objectish: objectish, count: count)
end

#log!(objectish: nil, count: nil) ⇒ Git::Log

Returns a Git::Log object: The collection of commits in the current branch or under the specified reference (if given).

Parameters:

  • objectish (String) (defaults to: nil)

    A git reference. Normally this would be a branch’s name but it could also be a tag, the SHA1 for a specific commit or any other valid git reference.

  • count (Integer) (defaults to: nil)

    The maximum number of commits to return in the collection, if omitted all the commits will be returned.

Returns:

  • (Git::Log)

    A Git::Log object with the collection of commits.

Raises:



229
230
231
232
233
# File 'lib/jay_api/git/repository.rb', line 229

def log!(objectish: nil, count: nil)
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  objectish ? repository.gblob(objectish).log(count) : repository.log(count)
end

#nameString

was/will be cloned.

Returns:

  • (String)

    The name of the directory in which the repository



106
107
108
# File 'lib/jay_api/git/repository.rb', line 106

def name
  @name ||= url ? directory_from_url : File.basename(clone_path)
end

#object(objectish) ⇒ Object

Returns the Git object that correspond to the given reference (normally a Git::Object::Commit). If the Repository is not yet initialized then, if the repository exists it will be open if not it will be cloned.

Parameters:

  • objectish (String)

    The reference to the object whose information should be retrieved. Normally this would be a SHA1 for a specific commit but it could also be a branch, a tag or any other valid git reference.

Raises:

  • (ArgumentError)

    If the Repository cannot be opened.

  • (Git::GitExecuteError)

    If the repository cannot be cloned, or the given reference doesn’t exist or is not a valid git object reference.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



122
123
124
125
# File 'lib/jay_api/git/repository.rb', line 122

def object(objectish)
  open_or_clone
  object!(objectish)
end

#object!(objectish) ⇒ Object

Returns the Git object that correspond to the given reference (normally a Git::Object::Commit).

Parameters:

  • objectish (String)

    The reference to the object whose information should be retrieved. Normally this would be a SHA1 for a specific commit but it could also be a branch, a tag or any other valid git reference.

Raises:

  • (JayAPI::Git::Errors::InvalidRepositoryError)

    If the repository is not a valid repository (it hasn’t been initialized: cloned or open).

  • (Git::GitExecuteError)

    If the given reference doesn’t exist or is not a valid git object reference.



138
139
140
141
142
# File 'lib/jay_api/git/repository.rb', line 138

def object!(objectish)
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  repository.object(objectish)
end

#open_or_clone!JayAPI::Git::Repository

Opens the repository if it is valid or clones it if it isn’t

Returns:

Raises:

  • (ArgumentError)

    If the Repository doesn’t exist.

  • (Git::GitExecuteError)

    If the repository cannot be cloned.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



300
301
302
303
# File 'lib/jay_api/git/repository.rb', line 300

def open_or_clone!
  open_or_clone
  self
end

#remote_urlString?

Returns The URL of the remote repository.

Returns:

  • (String, nil)

    The URL of the remote repository.



197
198
199
# File 'lib/jay_api/git/repository.rb', line 197

def remote_url
  @remote_url ||= remotes.first&.url
end

#remotesArray<Git::Remote>

Returns an Array of objects representing the Remote Repositories linked to the repository. The array may be empty but normally it contains at least one element (origin).

Returns:

  • (Array<Git::Remote>)

    The collection of remote repositories linked to the repository.

Raises:

  • (ArgumentError)

    If the Repository cannot be opened.

  • (Git::GitExecuteError)

    If the repository cannot be cloned.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



177
178
179
180
# File 'lib/jay_api/git/repository.rb', line 177

def remotes
  open_or_clone
  remotes!
end

#remotes!Array<Git::Remote>

Returns an Array of objects representing the Remote Repositories linked to the repository. The array may be empty but normally it contains at least one element (origin).

Returns:

  • (Array<Git::Remote>)

    The collection of remote repositories linked to the repository.

Raises:



190
191
192
193
194
# File 'lib/jay_api/git/repository.rb', line 190

def remotes!
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  repository.remotes
end

#update!Object

Updates the repository (without checking if it already exists or cloning it beforehand).

Raises:

  • (ArgumentError)

    If the repository path doesn’t exist.

  • (Git::GitExecuteError)

    If the repository path exists but it does not contain a valid git repository.



81
82
83
84
85
86
# File 'lib/jay_api/git/repository.rb', line 81

def update!
  open_repo
  repository.fetch(remote = repository.remotes.first.name)
  repository.pull(remote, repository.current_branch)
  self
end

#valid?Boolean

Returns True if the repository directory directory exists and is a valid git repository, false otherwise.

Returns:

  • (Boolean)

    True if the repository directory directory exists and is a valid git repository, false otherwise.



51
52
53
# File 'lib/jay_api/git/repository.rb', line 51

def valid?
  exist? && clone_path.directory? && git_dir.exist? && git_dir.directory?
end

#worktreesGit::Worktrees

Returns the collection of worktrees linked to the repository.

Returns:

  • (Git::Worktrees)

    The collection of worktrees linked to the repository.

Raises:

  • (ArgumentError)

    If the Repository cannot be opened.

  • (Git::GitExecuteError)

    If the repository cannot be cloned.

  • (JayAPI::Git::Errors::MissingURLError)

    If the repository doesn’t exist yet and no repository URL was provided for the cloning.



277
278
279
280
# File 'lib/jay_api/git/repository.rb', line 277

def worktrees
  open_or_clone
  worktrees!
end

#worktrees!Git::Worktrees

Returns the collection of worktrees linked to the repository.

Returns:

  • (Git::Worktrees)

    The collection of worktrees linked to the repository.

Raises:



288
289
290
291
292
# File 'lib/jay_api/git/repository.rb', line 288

def worktrees!
  raise JayAPI::Git::Errors::InvalidRepositoryError unless repository

  repository.worktrees
end