Skip to content

Commit

Permalink
Make bin cli tool apress-gem
Browse files Browse the repository at this point in the history
  • Loading branch information
bibendi committed Feb 26, 2015
1 parent f8ff431 commit daa47a9
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 319 deletions.
16 changes: 4 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,16 @@
# Apress::Gems

Rake задачи для выпуска гема на gems.railsc.ru
CLI tool для выпуска гема на gems.railsc.ru

## Installation

Add this line to your gemspec:

spec.add_development_dependency 'apress-gems'

Rewrite Rakefile like this:
gem install apress-gems

require 'apress/gems/rake_tasks'
## Usage

## Gem Releasing:

1. должен быть настроен git remote upstream и должны быть права на push
1. git checkout master
2. git pull upstream master
3. правим версию гема в файле VERSION в корне гема. (читаем правила версионирования http://semver.org/)
4. bundle exec rake release
bundle exec apress-gem --help

## Contributing

Expand Down
2 changes: 0 additions & 2 deletions Rakefile

This file was deleted.

1 change: 0 additions & 1 deletion VERSION

This file was deleted.

11 changes: 6 additions & 5 deletions apress-gems.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ Gem::Specification.new do |spec|
spec.version = Apress::Gems::VERSION
spec.authors = ['merkushin']
spec.email = ['[email protected]']
spec.summary = 'Набор rake задач дял выпуска гема на railsc.ru'
spec.description = 'Обязательно подключаемый гем для всех гемов apress-*'
spec.homepage = ''
spec.summary = 'CLI tool для выпуска гема на railsc.ru'
spec.homepage = 'https://github.com/abak-press/apress-gems/fork'
spec.license = 'MIT'

spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']

spec.add_development_dependency 'bundler', '>= 1.6'
spec.add_development_dependency 'rake'
spec.metadata['allowed_push_host'] = 'https://gems.railsc.ru'

spec.add_runtime_dependency 'apress-changelogger'
spec.add_runtime_dependency 'multipart-post'
spec.add_runtime_dependency 'bundler'
end
41 changes: 41 additions & 0 deletions bin/apress-gem
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env ruby

require 'optparse'
require 'apress/gems/cli'

options = {}

opt_parser = OptionParser.new do |opt|
opt.banner = 'Usage: apress-gem COMMAND [OPTIONS]'
opt.separator ''
opt.separator 'Abak-Press Gem Releasing Tool'
opt.separator ''
opt.separator 'Commands'
opt.separator ' release: changelog, version, tag, build and upload'
opt.separator ' changelog: generate CHANGELOG.md'
opt.separator ' update_version: update const VERSION in lin/**/version.rb'
opt.separator ' build: make gem package'
opt.separator ' upload: upload package to gems.railsc.ru'
opt.separator ' current_version: show current gem version'
opt.separator ''

opt.separator 'Options'

opt.on('-h', '--help', 'help') do
puts opt_parser
end

opt.on('-v', '--version VERSION', 'new version, ex: -v 1.0.0') do |value|
options[:version] = value
end
end

opt_parser.parse!

cli = Apress::Gems::Cli.new(options)

if %w(release changelog build upload tag current_version update_version).include?(ARGV[0])
cli.public_send(ARGV[0])
else
puts opt_parser
end
123 changes: 0 additions & 123 deletions lib/apress/gems/change_logger.rb

This file was deleted.

161 changes: 161 additions & 0 deletions lib/apress/gems/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
require 'bundler'
require 'pty'
require 'uri'
require 'net/http/post/multipart'
require 'apress/changelogger'

module Apress
module Gems
class Cli
GEMS_URL = 'https://gems.railsc.ru/'.freeze

def initialize(options)
@options = options
load_gemspec
end

def changelog
Apress::ChangeLogger.new.log_changes
spawn 'git add CHANGELOG.md'
puts 'CHANGELOG.md generated'
end

def update_version
Dir['lib/**/version.rb'].each do |file|
contents = File.read(file)
contents.gsub!(/VERSION\s*=\s*(['"])(.*?)\1/m, "VERSION = '#{version}'")
File.write(file, contents)
spawn "git add #{file}"
end
puts "VERSION updated to #{version}"
end

def build
FileUtils.mkdir_p('pkg')

spawn "gem build -V #{@spec_path}"
built_gem_path = Dir["#{@gemspec.name}-*.gem"].sort_by { |f| File.mtime(f) }.last

FileUtils.mv(built_gem_path, 'pkg')
puts 'Package built'
end

def upload
tarball_name = "#{@gemspec.name}-#{version}.gem"
upload_gem(upload_uri, tarball_name)
end

def tag
tag_name = "v#{version}"
spawn "git tag -a -m \"Version #{version}\" #{tag_name}"
puts "Git tag generated to #{tag_name}"
end

def current_version
puts "Current version is #{find_version}"
end

def release
validate_version
check_git

changelog
update_version
commit
build
upload
end

private

def version
@options.fetch(:version)
end

def find_version
Dir['lib/**/version.rb'].each do |file|
contents = File.read(file)
return contents.match(/VERSION\s*=\s*(['"])(.*?)\1/m)[2]
end
end

def upload_uri
uri = URI.parse(GEMS_URL)
uri.userinfo = Bundler.settings[GEMS_URL]
uri
end

def check_git
`git rev-parse --abbrev-ref HEAD`.chomp.strip == 'master' || abort('Can be released only from `master` branch')
`git remote | grep upstream`.chomp.strip == 'upstream' || abort('Can be released only with `upstream` remote')
spawn 'git pull upstream master'
spawn 'git pull --tags upstream'
spawn 'git push upstream master'
end

def commit
puts 'Commit and push changes'
spawn "git diff --cached --exit-code > /dev/null || git commit -m \"Release #{version}\" || echo -n"
spawn 'git push upstream master'
spawn 'git push --tags upstream'
end

def validate_version
puts version.inspect
return if Gem::Version.new(version) > Gem::Version.new(find_version)
raise 'New version less then current version'
end

# run +cmd+ in subprocess, redirect its stdout to parent's stdout
def spawn(cmd)
puts ">> #{cmd}"

cmd += ' 2>&1'
PTY.spawn cmd do |r, _w, pid|
begin
r.sync
r.each_char { |chr| STDOUT.write(chr) }
rescue Errno::EIO
# simply ignoring this
ensure
::Process.wait pid
end
end
abort "#{cmd} failed" unless $CHILD_STATUS && $CHILD_STATUS.exitstatus == 0
end

def load_gemspec
gemspecs = Dir[File.join(Dir.pwd, '{,*}.gemspec')]
raise 'Unable to determine name from existing gemspec' unless gemspecs.size == 1
@spec_path = gemspecs.first
@gemspec = Bundler.load_gemspec(@spec_path)
end

def upload_gem(repo_uri, tarball_name)
repo_uri.path = '/upload'

puts "Start uploading gem #{tarball_name} to #{repo_uri.host}"

tarball_path = File.join('pkg', tarball_name)

File.open(tarball_path) do |gem|
req = Net::HTTP::Post::Multipart.new(repo_uri.path,
'file' => UploadIO.new(gem, 'application/x-tar', tarball_name))

req.basic_auth(repo_uri.user, repo_uri.password) if repo_uri.user

res = Net::HTTP.start(repo_uri.host, repo_uri.port, use_ssl: repo_uri.scheme == 'https') do |http|
http.request(req)
end

if [200, 302].include?(res.code.to_i)
puts "#{tarball_name} uploaded successfully"
else
$stderr.puts "Cannot upload #{tarball_name}. Response status: #{res.code}"
exit(1)
end
end
end
end
end
end
3 changes: 0 additions & 3 deletions lib/apress/gems/rake_tasks.rb

This file was deleted.

Loading

0 comments on commit daa47a9

Please sign in to comment.