lib/teapot/command/fetch.rb in teapot-2.0.0.pre.rc2 vs lib/teapot/command/fetch.rb in teapot-2.0.0.pre.rc3
- old
+ new
@@ -17,14 +17,24 @@
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
require 'samovar'
+
require 'rugged'
module Teapot
module Command
+ class FetchError < StandardError
+ def initialize(package, message)
+ super(message)
+ @package = package
+ end
+
+ attr :package
+ end
+
class Fetch < Samovar::Command
self.description = "Fetch remote packages according to the specified configuration."
# 3 typical use cases:
# - fetch current packages according to lockfile
@@ -49,11 +59,11 @@
while true
configuration.packages.each do |package|
next if resolved.include? package
# If specific packages were listed, limit updates to them.
- if @packages.empty? || @packages.include?(package.name)
+ if @packages.nil? || @packages.empty? || @packages.include?(package.name)
fetch_package(context, configuration, package, logger, **@options)
end
# We are done with this package, don't try to process it again:
resolved << package
@@ -118,30 +128,58 @@
if base_uri.scheme == nil || base_uri.scheme == 'file'
base_uri = URI "file://" + File.expand_path(base_uri.path, context.root) + "/"
end
- branch = package.options.fetch(:branch, 'master')
+ branch_name = package.options.fetch(:branch, 'master')
if package_lock
logger.info "Package locked to commit: #{package_lock[:branch]}/#{package_lock[:commit]}"
- branch = package_lock[:branch]
+ branch_name = package_lock[:branch]
+ commit_id = package_lock[:commit]
end
- commit = package_lock ? package_lock[:commit] : nil
-
if destination_path.exist?
logger.info "Updating package at path #{destination_path}...".color(:cyan)
repository = Rugged::Repository.new(destination_path.to_s)
- repository.checkout(commit || 'origin/master')
+
+ # Are there uncommitted changes in the work tree?
+ if repository.to_enum(:status).any?
+ raise FetchError.new(package, "Uncommited local modifications")
+ end
+
+ repository.fetch('origin')
+ repository.checkout(branch_name)
+
+ # Essentially implement git pull:
+ if commit_id
+ # Lookup the named branch:
+ branch = repository.branches[branch_name].resolve
+ else
+ # Lookup the current branch and upstream commit:
+ branch = repository.branches[repository.head.name]
+ commit_id = branch.upstream.target_id
+ end
+
+ # Reset it to the requested commit if required:
+ repository.reset(commit_id, :hard)
else
logger.info "Cloning package at path #{destination_path}...".color(:cyan)
external_url = package.external_url(context.root)
- repository = Rugged::Repository.clone_at(external_url.to_s, destination_path.to_s, checkout_branch: branch)
- repository.checkout(commit) if commit
+
+ # Clone the repository with the specified branch:
+ repository = Rugged::Repository.clone_at(external_url.to_s, destination_path.to_s, checkout_branch: branch_name)
+
+ # Reset it to the requested commit if required:
+ repository.reset(commit_id, :hard) if commit_id
+ end
+
+ # Rugged currently doesn't have good (any?) support for submodules, so we diretly invoke git here:
+ if repository.submodules.any?
+ system("git", "submodule", "update", "--init", "--recursive", chdir: package.path)
end
end
def fetch_package(context, configuration, package, logger, update: false, local: false)
if package.local?