Commit 410b9417 authored by Fabio Pelosin's avatar Fabio Pelosin

[Command::Push] Move to Command::Repo

parent 13b9b3c7
......@@ -14,7 +14,6 @@ module Pod
require 'cocoapods/command/list'
require 'cocoapods/command/outdated'
require 'cocoapods/command/project'
require 'cocoapods/command/push'
require 'cocoapods/command/repo'
require 'cocoapods/command/search'
require 'cocoapods/command/setup'
......
require 'fileutils'
require 'active_support/core_ext/string/inflections'
module Pod
class Command
class Push < Command
self.summary = 'Push new specifications to a spec-repo'
self.description = <<-DESC
Validates NAME.podspec or `*.podspec' in the current working dir, creates
a directory and version folder for the pod in the local copy of
REPO (~/.cocoapods/repos/[REPO]), copies the podspec file into the version
directory, and finally it pushes REPO to its remote.
DESC
self.arguments = [
['REPO', :required],
['NAME.podspec', :optional]
]
def self.options
[ ["--allow-warnings", "Allows pushing even if there are warnings"],
["--local-only", "Does not perform the step of pushing REPO to its remote"] ].concat(super)
end
def initialize(argv)
@allow_warnings = argv.flag?('allow-warnings')
@local_only = argv.flag?('local-only')
@repo = argv.shift_argument
@podspec = argv.shift_argument
super
end
def validate!
super
help! "A spec-repo name is required." unless @repo
if @repo == 'master'
help! "To push to the master repo use the `pod trunk push` command"
end
end
def run
validate_podspec_files
check_repo_status
update_repo
add_specs_to_repo
push_repo unless @local_only
end
#-----------------------------------------------------------------------#
private
# @!group Push sub-steps
extend Executable
executable :git
# Performs a full lint against the podspecs.
#
def validate_podspec_files
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
podspec_files.each do |podspec|
validator = Validator.new(podspec)
validator.only_errors = @allow_warnings
begin
validator.validate
rescue Exception
raise Informative, "The `#{podspec}` specification does not validate."
end
raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
end
end
# Checks that the repo is clean.
#
# @raise If the repo is not clean.
#
# @todo Add specs for staged and unstaged files.
#
# @todo Gracefully handle the case where source is not under git
# source control.
#
# @return [void]
#
def check_repo_status
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
raise Informative, "The repo `#{@repo}` is not clean" unless clean
end
# Updates the git repo against the remote.
#
# @return [void]
#
def update_repo
UI.puts "Updating the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git pull 2>&1` }
end
# Commits the podspecs to the source, which should be a git repo.
#
# @note The pre commit hook of the repo is skipped as the podspecs have
# already been linted.
#
# @return [void]
#
def add_specs_to_repo
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
if Pathname.new(output_path).exist?
message = "[Fix] #{spec}"
elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
message = "[Update] #{spec}"
else
message = "[Add] #{spec}"
end
FileUtils.mkdir_p(output_path)
FileUtils.cp(spec_file, output_path)
Dir.chdir(repo_dir) do
# only commit if modified
if git!("status --porcelain 2>&1").include?(spec.name)
UI.puts " - #{message}"
git!("add #{spec.name}")
git!("commit --no-verify -m '#{message}'")
else
UI.puts " - [No change] #{spec}"
end
end
end
end
# Pushes the git repo against the remote.
#
# @return [void]
#
def push_repo
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git push origin master 2>&1` }
end
#-----------------------------------------------------------------------#
private
# @!group Private helpers
# @return [Pathname] The directory of the repository.
#
def repo_dir
dir = config.repos_dir + @repo
raise Informative, "`#{@repo}` repo not found" unless dir.exist?
dir
end
# @return [Array<Pathname>] The path of the specifications to push.
#
def podspec_files
files = Pathname.glob(@podspec || "*.podspec")
raise Informative, "Couldn't find any .podspec file in current directory" if files.empty?
files
end
# @return [Integer] The number of the podspec files to push.
#
def count
podspec_files.count
end
#-----------------------------------------------------------------------#
end
end
end
require 'fileutils'
require 'cocoapods/command/repo/push'
module Pod
class Command
......
require 'fileutils'
require 'active_support/core_ext/string/inflections'
module Pod
class Command
class Repo < Command
class Push < Repo
self.summary = 'Push new specifications to a spec-repo'
self.description = <<-DESC
Validates NAME.podspec or `*.podspec' in the current working dir, creates
a directory and version folder for the pod in the local copy of
REPO (~/.cocoapods/repos/[REPO]), copies the podspec file into the version
directory, and finally it pushes REPO to its remote.
DESC
self.arguments = [
['REPO', :required],
['NAME.podspec', :optional]
]
def self.options
[ ["--allow-warnings", "Allows pushing even if there are warnings"],
["--local-only", "Does not perform the step of pushing REPO to its remote"] ].concat(super)
end
def initialize(argv)
@allow_warnings = argv.flag?('allow-warnings')
@local_only = argv.flag?('local-only')
@repo = argv.shift_argument
@podspec = argv.shift_argument
super
end
def validate!
super
help! "A spec-repo name is required." unless @repo
if @repo == 'master'
help! "To push to the master repo use the `pod trunk push` command"
end
end
def run
validate_podspec_files
check_repo_status
update_repo
add_specs_to_repo
push_repo unless @local_only
end
#---------------------------------------------------------------------#
private
# @!group Push sub-steps
extend Executable
executable :git
# Performs a full lint against the podspecs.
#
def validate_podspec_files
UI.puts "\nValidating #{'spec'.pluralize(count)}".yellow
podspec_files.each do |podspec|
validator = Validator.new(podspec)
validator.only_errors = @allow_warnings
begin
validator.validate
rescue Exception
raise Informative, "The `#{podspec}` specification does not validate."
end
raise Informative, "The `#{podspec}` specification does not validate." unless validator.validated?
end
end
# Checks that the repo is clean.
#
# @raise If the repo is not clean.
#
# @todo Add specs for staged and unstaged files.
#
# @todo Gracefully handle the case where source is not under git
# source control.
#
# @return [void]
#
def check_repo_status
clean = Dir.chdir(repo_dir) { `git status --porcelain 2>&1` } == ''
raise Informative, "The repo `#{@repo}` is not clean" unless clean
end
# Updates the git repo against the remote.
#
# @return [void]
#
def update_repo
UI.puts "Updating the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git pull 2>&1` }
end
# Commits the podspecs to the source, which should be a git repo.
#
# @note The pre commit hook of the repo is skipped as the podspecs have
# already been linted.
#
# @return [void]
#
def add_specs_to_repo
UI.puts "\nAdding the #{'spec'.pluralize(count)} to the `#{@repo}' repo\n".yellow
podspec_files.each do |spec_file|
spec = Pod::Specification.from_file(spec_file)
output_path = File.join(repo_dir, spec.name, spec.version.to_s)
if Pathname.new(output_path).exist?
message = "[Fix] #{spec}"
elsif Pathname.new(File.join(repo_dir, spec.name)).exist?
message = "[Update] #{spec}"
else
message = "[Add] #{spec}"
end
FileUtils.mkdir_p(output_path)
FileUtils.cp(spec_file, output_path)
Dir.chdir(repo_dir) do
# only commit if modified
if git!("status --porcelain 2>&1").include?(spec.name)
UI.puts " - #{message}"
git!("add #{spec.name}")
git!("commit --no-verify -m '#{message}'")
else
UI.puts " - [No change] #{spec}"
end
end
end
end
# Pushes the git repo against the remote.
#
# @return [void]
#
def push_repo
UI.puts "\nPushing the `#{@repo}' repo\n".yellow
Dir.chdir(repo_dir) { UI.puts `git push origin master 2>&1` }
end
#---------------------------------------------------------------------#
private
# @!group Private helpers
# @return [Pathname] The directory of the repository.
#
def repo_dir
dir = config.repos_dir + @repo
raise Informative, "`#{@repo}` repo not found" unless dir.exist?
dir
end
# @return [Array<Pathname>] The path of the specifications to push.
#
def podspec_files
files = Pathname.glob(@podspec || "*.podspec")
raise Informative, "Couldn't find any .podspec file in current directory" if files.empty?
files
end
# @return [Integer] The number of the podspec files to push.
#
def count
podspec_files.count
end
#---------------------------------------------------------------------#
end
end
end
end
......@@ -5,8 +5,8 @@ module Pod
extend SpecHelper::Command
it "invokes the right command with --help flag" do
command = command('help', 'push')
command.send(:help_command).should.be.instance_of Pod::Command::Push
command = command('help', 'repo', 'push')
command.send(:help_command).should.be.instance_of Pod::Command::Repo::Push
lambda { command.run }.should.raise CLAide::Help
end
......
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../../../../spec_helper', __FILE__)
module Pod
describe Command::Push do
describe Command::Repo::Push do
extend SpecHelper::Command
extend SpecHelper::TemporaryRepos
......@@ -11,7 +11,7 @@ module Pod
it "complains if it can't find the repo" do
Dir.chdir(fixture('banana-lib')) do
cmd = command('push', 'missing_repo')
cmd = command('repo', 'push', 'missing_repo')
cmd.expects(:validate_podspec_files).returns(true)
e = lambda { cmd.run }.should.raise Informative
e.message.should.match(/repo not found/)
......@@ -20,7 +20,7 @@ module Pod
it "complains if it can't find a spec" do
repo_make('test_repo')
e = lambda { run_command('push', 'test_repo') }.should.raise Pod::Informative
e = lambda { run_command('repo', 'push', 'test_repo') }.should.raise Pod::Informative
e.message.should.match(/Couldn't find any .podspec/)
end
......@@ -29,7 +29,7 @@ module Pod
Dir.chdir(temporary_directory) do
spec = "Spec.new do |s|; s.name = 'Broken'; s.version = '1.0' end"
File.open('Broken.podspec', 'w') {|f| f.write(spec) }
cmd = command('push', 'test_repo')
cmd = command('repo', 'push', 'test_repo')
Validator.any_instance.stubs(:validated?).returns(false)
e = lambda { cmd.run }.should.raise Pod::Informative
......@@ -68,7 +68,7 @@ module Pod
Dir.chdir(test_repo_path) do
`touch DIRTY_FILE`
end
cmd = command('push', 'master')
cmd = command('repo', 'push', 'master')
cmd.expects(:validate_podspec_files).returns(true)
e = lambda { cmd.run }.should.raise Pod::Informative
e.message.should.match(/repo.*not clean/)
......@@ -76,8 +76,7 @@ module Pod
end
it "successfully pushes a spec" do
cmd = command('push', 'master')
cmd = command('repo', 'push', 'master')
Dir.chdir(@upstream) { `git checkout -b tmp_for_push -q` }
cmd.expects(:validate_podspec_files).returns(true)
Dir.chdir(temporary_directory) { cmd.run }
......
......@@ -7,7 +7,6 @@ module Pod
Command.parse(%w{ install }).should.be.instance_of Command::Install
Command.parse(%w{ list }).should.be.instance_of Command::List
Command.parse(%w{ outdated }).should.be.instance_of Command::Outdated
Command.parse(%w{ push }).should.be.instance_of Command::Push
Command.parse(%w{ repo }).should.be.instance_of Command::Repo
Command.parse(%w{ repo add }).should.be.instance_of Command::Repo::Add
Command.parse(%w{ repo lint }).should.be.instance_of Command::Repo::Lint
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment