seagull 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/seagull/configuration.rb +136 -0
- data/lib/seagull/deployment_strategies/file.rb +37 -0
- data/lib/seagull/deployment_strategies/hockey_app.rb +61 -0
- data/lib/seagull/deployment_strategies.rb +60 -0
- data/lib/seagull/tasks.rb +207 -0
- data/lib/seagull/version.rb +4 -165
- data/lib/seagull.rb +1 -4
- data/seagull.gemspec +13 -5
- metadata +108 -41
- data/VERSION.yml +0 -5
- data/bin/seagull +0 -17
- data/lib/seagull/cli.rb +0 -30
- data/lib/seagull/config.rb +0 -41
- data/lib/seagull/tasks/config.rb +0 -57
- data/lib/seagull/tasks/version.rb +0 -79
- data/lib/seagull/versionomy/format_definitions/apple.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eca246ae739c6916e531c26e71df1abd766e44db
|
4
|
+
data.tar.gz: 091a023531c9958b84c4e899d8a9b191de2697b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9ae3d32e76a7c0b6fc4cef7d848eb0c42083b18b34fadd61f7fcb33741bc92f3548aa70629d83cf1d496285885eb190fa1272bc21d5f2ce94baf666858d12fc
|
7
|
+
data.tar.gz: 4f6de74dc40da0910ea3ec23dff467a4266da1a6c36f96c73787500be6418d498f323f58af8b9e757052ffabb13c560c05e9cfae1de92d50cd0684be7e0c696b
|
@@ -0,0 +1,136 @@
|
|
1
|
+
require 'app_conf'
|
2
|
+
require 'seagull/deployment_strategies'
|
3
|
+
|
4
|
+
module Seagull
|
5
|
+
class Configuration < AppConf
|
6
|
+
def initialize(defaults = {})
|
7
|
+
super()
|
8
|
+
|
9
|
+
# Set defaults
|
10
|
+
from_hash({
|
11
|
+
:configuration => {:debug => 'Debug', :beta => 'AdHoc', :release => 'Release'},
|
12
|
+
:build_dir => 'build',
|
13
|
+
:auto_archive => true,
|
14
|
+
:changelog_file => File.expand_path('CHANGELOG.md'),
|
15
|
+
:archive_path => File.expand_path("~/Library/Developer/Xcode/Archives"),
|
16
|
+
:ipa_path => File.expand_path("~/Library/Developer/Xcode/Archives"),
|
17
|
+
:dsym_path => File.expand_path("~/Library/Developer/Xcode/Archives"),
|
18
|
+
:xcpretty => true,
|
19
|
+
:xctool_path => "xctool",
|
20
|
+
:xcodebuild_path => "xcodebuild",
|
21
|
+
:workspace_path => nil,
|
22
|
+
:scheme => nil,
|
23
|
+
:app_name => nil,
|
24
|
+
:arch => nil,
|
25
|
+
:skip_clean => false,
|
26
|
+
:verbose => false,
|
27
|
+
:dry_run => false,
|
28
|
+
|
29
|
+
:deploy => {
|
30
|
+
:release_notes_items => 5,
|
31
|
+
},
|
32
|
+
:release_type => :beta,
|
33
|
+
:deployment_strategies => {},
|
34
|
+
})
|
35
|
+
|
36
|
+
self.load('.seagull.yml') if File.exists?(".seagull.yml")
|
37
|
+
self.from_hash(defaults)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Configuration
|
41
|
+
def deployment(release_type, strategy_name, &block)
|
42
|
+
if DeploymentStrategies.valid_strategy?(strategy_name.to_sym)
|
43
|
+
deployment_strategy = DeploymentStrategies.build(strategy_name, self)
|
44
|
+
|
45
|
+
self.deployment_strategies.send("#{release_type}=", deployment_strategy)
|
46
|
+
self.deployment_strategies.send("#{release_type}").configure(&block)
|
47
|
+
else
|
48
|
+
raise "Unknown deployment strategy '#{strategy_name}'."
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def deployment_strategy(type)
|
53
|
+
self.active_release_type = type
|
54
|
+
self.deployment_strategies.send(type)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Accessors
|
58
|
+
def archive_name
|
59
|
+
app_name || target || scheme
|
60
|
+
end
|
61
|
+
|
62
|
+
def archive_file_name(override = {})
|
63
|
+
"#{archive_name}-#{full_version}_#{configuration.send(override.fetch(:release_type, release_type))}.xcarchive"
|
64
|
+
end
|
65
|
+
|
66
|
+
def archive_full_path(type)
|
67
|
+
File.join(archive_path, archive_file_name(release_type: type))
|
68
|
+
end
|
69
|
+
|
70
|
+
def ipa_name
|
71
|
+
app_name || target || scheme
|
72
|
+
end
|
73
|
+
|
74
|
+
def ipa_file_name(override = {})
|
75
|
+
"#{archive_name}-#{full_version}_#{configuration.send(override.fetch(:release_type, release_type))}.ipa"
|
76
|
+
end
|
77
|
+
|
78
|
+
def ipa_full_path(type)
|
79
|
+
File.join(ipa_path, ipa_file_name(release_type: type))
|
80
|
+
end
|
81
|
+
|
82
|
+
def dsym_file_name(override = {})
|
83
|
+
"#{archive_name}-#{full_version}_#{configuration.send(override.fetch(:release_type, release_type))}.dSYM.zip"
|
84
|
+
end
|
85
|
+
|
86
|
+
def dsym_full_path(type)
|
87
|
+
File.join(dsym_path, dsym_file_name(release_type: type))
|
88
|
+
end
|
89
|
+
|
90
|
+
def version_data
|
91
|
+
@version_data ||= begin
|
92
|
+
vers = %x{agvtool vers -terse|tail -1}.strip
|
93
|
+
mvers = %x{agvtool mvers -terse1|tail -1}.strip
|
94
|
+
{marketing: mvers, version: vers}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def reload_version!
|
99
|
+
@version_data = nil; version_data
|
100
|
+
end
|
101
|
+
|
102
|
+
def marketing_version
|
103
|
+
version_data[:marketing]
|
104
|
+
end
|
105
|
+
|
106
|
+
def version
|
107
|
+
version_data[:version]
|
108
|
+
end
|
109
|
+
|
110
|
+
def full_version
|
111
|
+
"#{marketing_version}.#{version}"
|
112
|
+
end
|
113
|
+
|
114
|
+
def version_tag
|
115
|
+
"v#{full_version}"
|
116
|
+
end
|
117
|
+
|
118
|
+
def build_arguments(override = {})
|
119
|
+
args = {}
|
120
|
+
if workspace
|
121
|
+
args[:workspace] = "#{workspace}.xcworkspace"
|
122
|
+
args[:scheme] = scheme
|
123
|
+
else
|
124
|
+
args[:target] = target
|
125
|
+
args[:project] = project_file_path if project_file_path
|
126
|
+
end
|
127
|
+
|
128
|
+
args[:configuration] = configuration.send(release_type)
|
129
|
+
args[:arch] = arch unless arch.nil?
|
130
|
+
|
131
|
+
args.merge!(override)
|
132
|
+
|
133
|
+
args.collect{|k,v| "-#{k} #{Shellwords.escape(v)}"}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Seagull
|
2
|
+
module DeploymentStrategies
|
3
|
+
class File < DeploymentStrategy
|
4
|
+
def extended_configuration_for_strategy
|
5
|
+
proc do
|
6
|
+
def generate_release_notes(&block)
|
7
|
+
self.release_notes = block if block
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def prepare
|
13
|
+
end
|
14
|
+
|
15
|
+
def deploy
|
16
|
+
# Make sure destionation directoy exists
|
17
|
+
FileUtils.mkpath(@configuration.deploy.path) unless ::File.directory?(@configuration.deploy.path)
|
18
|
+
|
19
|
+
# Copy xcarchive
|
20
|
+
Dir.chdir(@configuration.archive_path) do
|
21
|
+
deploy_path = ::File.join(@configuration.deploy.path, @configuration.archive_file_name(release_type: @configuration.active_release_type) + ".zip")
|
22
|
+
FileUtils.rm deploy_path if ::File.exists?(deploy_path)
|
23
|
+
system("/usr/bin/zip --symlinks --recurse-paths #{Shellwords.escape(deploy_path)} #{Shellwords.escape(@configuration.archive_file_name(release_type: @configuration.active_release_type))}")
|
24
|
+
end
|
25
|
+
|
26
|
+
[
|
27
|
+
@configuration.ipa_full_path(@configuration.active_release_type),
|
28
|
+
@configuration.dsym_full_path(@configuration.active_release_type),
|
29
|
+
].each do |f|
|
30
|
+
FileUtils.cp_r f, @configuration.deploy.path
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'json'
|
3
|
+
require 'launchy'
|
4
|
+
|
5
|
+
module Seagull
|
6
|
+
module DeploymentStrategies
|
7
|
+
class HockeyApp < DeploymentStrategy
|
8
|
+
|
9
|
+
def defaults
|
10
|
+
{
|
11
|
+
:allow_download => true,
|
12
|
+
:notify => true,
|
13
|
+
:mandatory => false,
|
14
|
+
:tags => '',
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
# Nothing to prepare
|
19
|
+
def prepare
|
20
|
+
end
|
21
|
+
|
22
|
+
def deploy
|
23
|
+
# Create response file
|
24
|
+
response_file = Tempfile.new('seagull_deploy_hockey')
|
25
|
+
payload = {
|
26
|
+
status: @configuration.deploy.allow_download ? 2 : 1,
|
27
|
+
notify: @configuration.deploy.notify ? 1 : 0,
|
28
|
+
mandatory: @configuration.deploy.mandatory ? 1 : 0,
|
29
|
+
tags: @configuration.deploy.tags,
|
30
|
+
notes: release_notes,
|
31
|
+
notes_type: 1,
|
32
|
+
ipa: "@#{Shellwords.escape(@configuration.ipa_full_path(@configuration.active_release_type))}",
|
33
|
+
dsym: "@#{Shellwords.escape(@configuration.dsym_full_path(@configuration.active_release_type))}",
|
34
|
+
commit_sha: %x{git rev-parse HEAD}.strip,
|
35
|
+
repository_url: %x{git remote -v|grep fetch|awk '{print $2;}'}.strip,
|
36
|
+
}
|
37
|
+
opts = payload.collect{|k,v| "-F #{k}=#{Shellwords.escape(v)}"}.join(" ")
|
38
|
+
|
39
|
+
puts "Uploading to Hockeyapp... Please wait..."
|
40
|
+
system("curl #{opts} -o #{response_file.path} -H 'X-HockeyAppToken: #{@configuration.deploy.token}' https://rink.hockeyapp.net/api/2/apps/#{@configuration.deploy.appid}/app_versions/upload")
|
41
|
+
|
42
|
+
response_body = if response_file.size > 0
|
43
|
+
response_file.read
|
44
|
+
else
|
45
|
+
"{}"
|
46
|
+
end
|
47
|
+
response = JSON.parse(response_body)
|
48
|
+
if response['config_url']
|
49
|
+
puts "Version page: #{response['config_url']}"
|
50
|
+
Launchy.open(response['config_url'])
|
51
|
+
else
|
52
|
+
puts "FAILED to upload app"
|
53
|
+
end
|
54
|
+
ensure
|
55
|
+
response_file.unlink
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'vandamme'
|
2
|
+
|
3
|
+
module Seagull
|
4
|
+
module DeploymentStrategies
|
5
|
+
def self.valid_strategy?(strategy_name)
|
6
|
+
strategies.keys.include?(strategy_name.to_sym)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.build(strategy_name, configuration)
|
10
|
+
strategies[strategy_name.to_sym].new(configuration)
|
11
|
+
end
|
12
|
+
|
13
|
+
class DeploymentStrategy
|
14
|
+
def initialize(configuration)
|
15
|
+
@configuration = configuration
|
16
|
+
|
17
|
+
if respond_to?(:extended_configuration_for_strategy)
|
18
|
+
@configuration.instance_eval(&extended_configuration_for_strategy)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def configure(&block)
|
23
|
+
@configuration.deploy.from_hash(defaults)
|
24
|
+
|
25
|
+
yield @configuration.deploy
|
26
|
+
end
|
27
|
+
|
28
|
+
def defaults
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
def prepare
|
33
|
+
puts "Nothing to prepare!"
|
34
|
+
end
|
35
|
+
|
36
|
+
def deploy
|
37
|
+
raise "NOT IMPLEMENTED"
|
38
|
+
end
|
39
|
+
|
40
|
+
def release_notes
|
41
|
+
changelog = ::File.exists?(@configuration.changelog_file) ? ::File.read(@configuration.changelog_file) : ""
|
42
|
+
|
43
|
+
parser = Vandamme::Parser.new(changelog: changelog, version_header_exp: '^\*\*?([\w\d\.-]+\.[\w\d\.-]+[a-zA-Z0-9])( \/ (\d{4}-\d{2}-\d{2}|\w+))?\*\*\n?[=-]*', format: 'markdown')
|
44
|
+
changes = parser.parse
|
45
|
+
|
46
|
+
changes.first(@configuration.deploy.release_notes_items).collect{|v, c| "**#{v}**\n\n#{c}" }.join("\n\n")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def self.strategies
|
53
|
+
{:file => File, :hockeyapp => HockeyApp}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
require 'seagull/deployment_strategies/file'
|
59
|
+
require 'seagull/deployment_strategies/hockey_app'
|
60
|
+
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
require 'vandamme'
|
4
|
+
require 'date'
|
5
|
+
require 'term/ansicolor'
|
6
|
+
require 'seagull/configuration'
|
7
|
+
|
8
|
+
module Seagull
|
9
|
+
class Tasks < ::Rake::TaskLib
|
10
|
+
def initialize(namespace = :seagull, &block)
|
11
|
+
@configuration = Configuration.new
|
12
|
+
@namespace = namespace
|
13
|
+
|
14
|
+
yield @configuration if block_given?
|
15
|
+
|
16
|
+
# Check we can find our xctool
|
17
|
+
unless File.executable?(%x{which #{@configuration.xctool_path}}.strip)
|
18
|
+
raise "xctool is required. Please install using Homebrew: brew install xctool."
|
19
|
+
end
|
20
|
+
|
21
|
+
unless File.executable?(%x{which #{@configuration.xcodebuild_path}}.strip)
|
22
|
+
raise "xcodebuild is required. Please install XCode."
|
23
|
+
end
|
24
|
+
|
25
|
+
define
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def define
|
30
|
+
# Detect some defaults
|
31
|
+
namespace(@namespace) do
|
32
|
+
task :clean do
|
33
|
+
unless @configuration.skip_clean
|
34
|
+
xctool @configuration.build_arguments, "clean"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Build and run tests"
|
39
|
+
task test: [] do
|
40
|
+
xctool @configuration.build_arguments(configuration: @configuration.configuration.debug, arch: 'i386', sdk: 'iphonesimulator'), "clean", "test", "-freshInstall", "-freshSimulator"
|
41
|
+
end
|
42
|
+
|
43
|
+
# File dependencies
|
44
|
+
@configuration.configuration.to_hash.each do |type, conf|
|
45
|
+
file @configuration.archive_full_path(type) do
|
46
|
+
xctool @configuration.build_arguments(configuration: conf), "archive", "-archivePath", Shellwords.escape(@configuration.archive_full_path(type))
|
47
|
+
end
|
48
|
+
|
49
|
+
file @configuration.ipa_full_path(type) => @configuration.archive_full_path(type) do
|
50
|
+
xcodebuild "-exportArchive", "-exportFormat", "ipa", "-archivePath", Shellwords.escape(@configuration.archive_full_path(type)), "-exportPath", Shellwords.escape(@configuration.ipa_full_path(type))
|
51
|
+
end
|
52
|
+
|
53
|
+
file @configuration.dsym_full_path(type) => @configuration.archive_full_path(type) do
|
54
|
+
dsym_path = File.expand_path(Dir["#{@configuration.archive_full_path(type)}/dSYMS/*"].first)
|
55
|
+
Dir.chdir dsym_path do
|
56
|
+
sh("/usr/bin/zip --symlinks --verbose --recurse-paths '#{@configuration.dsym_full_path(type)}' .")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
['beta', 'release'].each do |type|
|
62
|
+
namespace(type) do
|
63
|
+
desc "Archive the #{type} version as an XCArchive file"
|
64
|
+
task archive: [@configuration.archive_full_path(type)]
|
65
|
+
|
66
|
+
desc "Package the #{type} version as an IPA file"
|
67
|
+
task package: [@configuration.ipa_full_path(type), @configuration.dsym_full_path(type)]
|
68
|
+
|
69
|
+
if @configuration.deployment_strategies
|
70
|
+
desc "Prepare your app for deployment"
|
71
|
+
task prepare: ['git:verify', :package] do
|
72
|
+
@configuration.deployment_strategy(type).prepare
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "Deploy the beta using your chosen deployment strategy"
|
76
|
+
task deploy: [:prepare] do
|
77
|
+
@configuration.deployment_strategy(type).deploy
|
78
|
+
end
|
79
|
+
|
80
|
+
desc "Deploy the last build"
|
81
|
+
task redeploy: [:prepre, :deploy]
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
desc "Build, package and deploy beta build"
|
87
|
+
task type => ["#{type}:deploy"] do
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Version control
|
92
|
+
namespace(:version) do
|
93
|
+
desc "Bumps build number"
|
94
|
+
task bump: ['git:verify:dirty'] do
|
95
|
+
sh("agvtool bump -all")
|
96
|
+
@configuration.reload_version!
|
97
|
+
|
98
|
+
# Edit changelog
|
99
|
+
Rake::Task["#{@namespace}:changelog:edit"].invoke
|
100
|
+
Rake::Task["#{@namespace}:version:commit"].invoke
|
101
|
+
Rake::Task["#{@namespace}:version:tag"].invoke
|
102
|
+
end
|
103
|
+
|
104
|
+
task :tag do
|
105
|
+
current_tag = %x{git describe --exact-match `git rev-parse HEAD` 2>/dev/null}.strip
|
106
|
+
unless current_tag == @configuration.version_tag
|
107
|
+
sh("git tag -m 'Released version #{@configuration.full_version}' -s '#{@configuration.version_tag}'")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
task :commit do
|
112
|
+
ver_files = %x{git status --porcelain}.split("\n").collect{|a| Shellwords.escape(a.gsub(/[ AM\?]+ (.*)/, '\1'))}
|
113
|
+
|
114
|
+
Dir.chdir(git_directory) do
|
115
|
+
sh("git add #{ver_files.join(' ')}")
|
116
|
+
sh("git commit -m 'Bumped version to #{@configuration.full_version}' #{ver_files.join(' ')}")
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
namespace(:changelog) do
|
122
|
+
desc "Edit changelog for current version"
|
123
|
+
task :edit do
|
124
|
+
changelog = if File.exists?(@configuration.changelog_file)
|
125
|
+
File.read(@configuration.changelog_file)
|
126
|
+
else
|
127
|
+
""
|
128
|
+
end
|
129
|
+
|
130
|
+
tag = %x{git describe --exact-match `git rev-parse HEAD` 2>/dev/null}.strip
|
131
|
+
tag_date = Date.parse(%x{git log -1 --format=%ai #{tag}})
|
132
|
+
|
133
|
+
# Parse current changelog
|
134
|
+
parser = Vandamme::Parser.new(changelog: changelog, version_header_exp: '^\*\*?([\w\d\.-]+\.[\w\d\.-]+[a-zA-Z0-9])( \/ (\d{4}-\d{2}-\d{2}|\w+))?\*\*\n?[=-]*', format: 'markdown')
|
135
|
+
changes = parser.parse
|
136
|
+
|
137
|
+
# Write entry to changelog
|
138
|
+
File.open('CHANGELOG.md', 'w') do |io|
|
139
|
+
unless @configuration.full_version
|
140
|
+
io.puts "**#{@configuration.full_version} / #{tag_date.strftime('%Y-%m-%d')}**"
|
141
|
+
io.puts ""
|
142
|
+
%w{FIXED SECURITY FEATURE ENHANCEMENT PERFORMANCE}.each do |kw|
|
143
|
+
io.puts " * **#{kw}** Describe changes here or remove if not required"
|
144
|
+
end
|
145
|
+
io.puts ""
|
146
|
+
end
|
147
|
+
io.puts changelog
|
148
|
+
end
|
149
|
+
sh("#{ENV['EDITOR']} CHANGELOG.md")
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
namespace(:git) do
|
154
|
+
namespace(:verify) do
|
155
|
+
# Verify GIT tag
|
156
|
+
task :tag do
|
157
|
+
current_tag = %x{git describe --exact-match `git rev-parse HEAD` 2>/dev/null}.strip
|
158
|
+
unless current_tag == @configuration.version_tag
|
159
|
+
puts ""
|
160
|
+
puts Term::ANSIColor.red("!!! Current commit is not properly tagged in GIT. Please tag and release version.")
|
161
|
+
puts ""
|
162
|
+
|
163
|
+
fail unless ENV['IGNORE_GIT_TAG']
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# Verify dirty
|
168
|
+
task :dirty do
|
169
|
+
unless %x{git status -s --ignore-submodules=dirty 2> /dev/null}.empty?
|
170
|
+
puts ""
|
171
|
+
puts Term::ANSIColor.red("!!! Current GIT tree is dirty. Please commit changes before building release.")
|
172
|
+
puts ""
|
173
|
+
|
174
|
+
fail unless ENV['IGNORE_GIT_DIRTY']
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
task verify: ['verify:tag', 'verify:dirty']
|
180
|
+
end
|
181
|
+
|
182
|
+
def xctool(*args)
|
183
|
+
sh("#{@configuration.xctool_path} #{args.join(" ")}")
|
184
|
+
end
|
185
|
+
|
186
|
+
def xcodebuild(*args)
|
187
|
+
sh("#{@configuration.xcodebuild_path} #{args.join(" ")} | xcpretty -c; exit ${PIPESTATUS[0]}")
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def git_directory
|
193
|
+
original_cwd = Dir.pwd
|
194
|
+
|
195
|
+
loop do
|
196
|
+
if File.directory?('.git')
|
197
|
+
git_dir = Dir.pwd
|
198
|
+
Dir.chdir(original_cwd) and return git_dir
|
199
|
+
end
|
200
|
+
|
201
|
+
Dir.chdir(original_cwd) and return if Pathname.new(Dir.pwd).root?
|
202
|
+
|
203
|
+
Dir.chdir('..')
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
data/lib/seagull/version.rb
CHANGED
@@ -1,170 +1,9 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
require 'seagull/config'
|
3
|
-
require 'versionomy'
|
4
|
-
require 'seagull/versionomy/format_definitions/apple'
|
5
|
-
|
6
1
|
module Seagull
|
7
2
|
class Version
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@config = Seagull::Config.instance
|
12
|
-
|
13
|
-
@version = if File.exists?(@config.version.file)
|
14
|
-
Versionomy.create(YAML.load_file(@config.version.file), @config.version.format)
|
15
|
-
else
|
16
|
-
Versionomy.create({}, @config.version.format)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def peek(what)
|
21
|
-
peek = case what
|
22
|
-
when :release
|
23
|
-
bump(:major)
|
24
|
-
when :patch
|
25
|
-
bump(:minor)
|
26
|
-
when :update
|
27
|
-
bump(:update)
|
28
|
-
when :build
|
29
|
-
bump(:build)
|
30
|
-
else
|
31
|
-
@version
|
32
|
-
end
|
33
|
-
|
34
|
-
peek.unparse
|
35
|
-
end
|
36
|
-
|
37
|
-
# Output marketing version
|
38
|
-
def marketing
|
39
|
-
case @config.version.format
|
40
|
-
when :apple
|
41
|
-
major, minor = if @config.versions![@version.major]
|
42
|
-
@config.versions[@version.major].split('.')
|
43
|
-
else
|
44
|
-
[@version.major, @version.minor]
|
45
|
-
end
|
46
|
-
tiny = @version.convert(:standard).tiny
|
47
|
-
|
48
|
-
Versionomy.create(major: major, minor: minor, tiny: tiny).unparse(:required_fields => :tiny)
|
49
|
-
else
|
50
|
-
@version.convert(:standard).unparse(:required_fields => [:major, :minor, :tiny])
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def bundle
|
55
|
-
case @config.version.format
|
56
|
-
when :apple
|
57
|
-
@version.unparse
|
58
|
-
else
|
59
|
-
@version.convert(:standard).tiny2
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def bundle_numeric
|
64
|
-
case @config.version.format
|
65
|
-
when :apple
|
66
|
-
@version.build
|
67
|
-
else
|
68
|
-
@version.convert(:standard).tiny2
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def save
|
73
|
-
if File.extname(@config.version.file) == '.yml'
|
74
|
-
yaml = if File.exists?(@config.version.file)
|
75
|
-
YAML.load_file(@config.version.file)
|
76
|
-
else
|
77
|
-
{}
|
78
|
-
end
|
79
|
-
|
80
|
-
yaml.merge!(@version.values_hash)
|
81
|
-
|
82
|
-
# Some shortcuts
|
83
|
-
yaml.merge!({
|
84
|
-
marketing: self.marketing,
|
85
|
-
bundle: self.bundle,
|
86
|
-
bundle_numeric: self.bundle_numeric,
|
87
|
-
short: self.marketing,
|
88
|
-
string: self.marketing,
|
89
|
-
})
|
90
|
-
|
91
|
-
File.open(@config.version.file, 'w') {|io| io.puts yaml.to_yaml }
|
92
|
-
|
93
|
-
else
|
94
|
-
File.open(@config.version.file, 'w') {|io| io.puts @version.unparse }
|
95
|
-
end
|
3
|
+
MAJOR = 0
|
4
|
+
MINOR = 1
|
5
|
+
PATCH = 0
|
96
6
|
|
97
|
-
|
98
|
-
system "git commit #{@config.version.file} -m 'Bumped version to #{self.bundle}'"
|
99
|
-
end
|
100
|
-
|
101
|
-
# Accessors
|
102
|
-
def build
|
103
|
-
bump!(:build); self
|
104
|
-
end
|
105
|
-
|
106
|
-
def update
|
107
|
-
bump!(:update); self
|
108
|
-
end
|
109
|
-
|
110
|
-
def patch
|
111
|
-
bump!(:minor); self
|
112
|
-
end
|
113
|
-
|
114
|
-
def release(major = nil, version = nil)
|
115
|
-
old_major = @version.major
|
116
|
-
old_version = @config.versions![old_major.to_s]
|
117
|
-
|
118
|
-
bump!(:major)
|
119
|
-
|
120
|
-
major ||= @version.major
|
121
|
-
version ||= Versionomy.parse(@config.versions![old_major.to_s] || "0.#{major}").bump(:minor).unparse
|
122
|
-
|
123
|
-
if @config.versions![major] or @config.versions!.invert[version]
|
124
|
-
raise "Version #{version} or major #{major} already exists"
|
125
|
-
end
|
126
|
-
|
127
|
-
@config.versions![major] = version; @config.save
|
128
|
-
|
129
|
-
# Commit
|
130
|
-
system "git tag 'v#{self.marketing}' -m 'Released version #{self.marketing}'"
|
131
|
-
|
132
|
-
self
|
133
|
-
end
|
134
|
-
|
135
|
-
def bump(field)
|
136
|
-
_tr = {
|
137
|
-
:apple => {},
|
138
|
-
:standard => {
|
139
|
-
:update => :tiny, :build => :tiny2
|
140
|
-
}
|
141
|
-
}
|
142
|
-
|
143
|
-
_field = _tr[@config.version.format][field] || field
|
144
|
-
|
145
|
-
if @config.version.format == :apple and field == :update and @version.update.empty?
|
146
|
-
@version.change(update: 'a')
|
147
|
-
else
|
148
|
-
@version.bump(field)
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
def bump!(field)
|
153
|
-
@version = bump(field); save; self
|
154
|
-
end
|
155
|
-
|
156
|
-
def to_s(format = @config.version.format)
|
157
|
-
@version.convert(format).unparse
|
158
|
-
end
|
159
|
-
|
160
|
-
# Proxy
|
161
|
-
def method_missing(m, *args, &blk)
|
162
|
-
@version.send(m, *args, &blk)
|
163
|
-
end
|
164
|
-
|
165
|
-
def respond_to?(m)
|
166
|
-
@version.respond_to?(m)
|
167
|
-
end
|
168
|
-
|
7
|
+
STRING = [MAJOR, MINOR, PATCH].join('.')
|
169
8
|
end
|
170
9
|
end
|
data/lib/seagull.rb
CHANGED
data/seagull.gemspec
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'seagull/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |spec|
|
6
7
|
spec.name = "seagull"
|
7
|
-
spec.version =
|
8
|
+
spec.version = Seagull::Version::STRING
|
8
9
|
spec.authors = ["Mikko Kokkonen"]
|
9
10
|
spec.email = ["mikko@owlforestry.com"]
|
10
11
|
spec.description = %q{Seagull makes managing XCode projects easy as flying is for seagulls}
|
@@ -17,9 +18,16 @@ Gem::Specification.new do |spec|
|
|
17
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
19
|
spec.require_paths = ["lib"]
|
19
20
|
|
20
|
-
spec.add_dependency "
|
21
|
-
spec.add_dependency "
|
22
|
-
spec.add_dependency "
|
21
|
+
spec.add_dependency "rake", "~> 10.1"
|
22
|
+
spec.add_dependency "xcpretty", "~> 0.1.3"
|
23
|
+
spec.add_dependency "app_conf", "~> 0.4.2"
|
24
|
+
spec.add_dependency "unicode", "~> 0.4.4"
|
25
|
+
spec.add_dependency "nokogiri", "~> 1.6.1"
|
26
|
+
spec.add_dependency "vandamme", "~> 0.0.7"
|
27
|
+
spec.add_dependency "json", "~> 1.8.1"
|
28
|
+
spec.add_dependency "term-ansicolor", "~> 1.3.0"
|
29
|
+
spec.add_dependency "launchy", "~> 2.4.2"
|
30
|
+
|
31
|
+
|
23
32
|
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
-
spec.add_development_dependency "rake", "~> 10.1"
|
25
33
|
end
|
metadata
CHANGED
@@ -1,107 +1,174 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seagull
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikko Kokkonen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-03-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rake
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '10.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '10.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: xcpretty
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.1.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.1.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: app_conf
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 0.4.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.4.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: unicode
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
type: :
|
61
|
+
version: 0.4.4
|
62
|
+
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.4.4
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.6.1
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.6.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: vandamme
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.0.7
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.0.7
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: json
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 1.8.1
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 1.8.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: term-ansicolor
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.3.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.3.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: launchy
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 2.4.2
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.4.2
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: bundler
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '1.3'
|
76
146
|
type: :development
|
77
147
|
prerelease: false
|
78
148
|
version_requirements: !ruby/object:Gem::Requirement
|
79
149
|
requirements:
|
80
|
-
- - ~>
|
150
|
+
- - "~>"
|
81
151
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
152
|
+
version: '1.3'
|
83
153
|
description: Seagull makes managing XCode projects easy as flying is for seagulls
|
84
154
|
email:
|
85
155
|
- mikko@owlforestry.com
|
86
|
-
executables:
|
87
|
-
- seagull
|
156
|
+
executables: []
|
88
157
|
extensions: []
|
89
158
|
extra_rdoc_files: []
|
90
159
|
files:
|
91
|
-
- .gitignore
|
160
|
+
- ".gitignore"
|
92
161
|
- Gemfile
|
93
162
|
- LICENSE.txt
|
94
163
|
- README.md
|
95
164
|
- Rakefile
|
96
|
-
- VERSION.yml
|
97
|
-
- bin/seagull
|
98
165
|
- lib/seagull.rb
|
99
|
-
- lib/seagull/
|
100
|
-
- lib/seagull/
|
101
|
-
- lib/seagull/
|
102
|
-
- lib/seagull/
|
166
|
+
- lib/seagull/configuration.rb
|
167
|
+
- lib/seagull/deployment_strategies.rb
|
168
|
+
- lib/seagull/deployment_strategies/file.rb
|
169
|
+
- lib/seagull/deployment_strategies/hockey_app.rb
|
170
|
+
- lib/seagull/tasks.rb
|
103
171
|
- lib/seagull/version.rb
|
104
|
-
- lib/seagull/versionomy/format_definitions/apple.rb
|
105
172
|
- seagull.gemspec
|
106
173
|
homepage: ''
|
107
174
|
licenses:
|
@@ -113,17 +180,17 @@ require_paths:
|
|
113
180
|
- lib
|
114
181
|
required_ruby_version: !ruby/object:Gem::Requirement
|
115
182
|
requirements:
|
116
|
-
- -
|
183
|
+
- - ">="
|
117
184
|
- !ruby/object:Gem::Version
|
118
185
|
version: '0'
|
119
186
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
187
|
requirements:
|
121
|
-
- -
|
188
|
+
- - ">="
|
122
189
|
- !ruby/object:Gem::Version
|
123
190
|
version: '0'
|
124
191
|
requirements: []
|
125
192
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.0
|
193
|
+
rubygems_version: 2.2.0
|
127
194
|
signing_key:
|
128
195
|
specification_version: 4
|
129
196
|
summary: Manage Xcode projects with total control
|
data/VERSION.yml
DELETED
data/bin/seagull
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
4
|
-
|
5
|
-
# Do we have seagull inside bundler?
|
6
|
-
if File.exists?("Gemfile") and File.read("Gemfile") =~ /#{File.basename($0)}/
|
7
|
-
# Restart tool from bundle if facing load error
|
8
|
-
require 'bundler'
|
9
|
-
begin
|
10
|
-
Bundler.require(:default)
|
11
|
-
rescue LoadError
|
12
|
-
exec "bundle", "exec", File.basename($0), *ARGV
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
require 'seagull/cli'
|
17
|
-
Seagull::CLI.start
|
data/lib/seagull/cli.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'thor'
|
2
|
-
# require 'seagull/config'
|
3
|
-
|
4
|
-
module Seagull
|
5
|
-
class CLI < Thor
|
6
|
-
def initialize(*args)
|
7
|
-
super
|
8
|
-
|
9
|
-
# @config = Seagull::Config.instance
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "debug", "Opens debug console"
|
13
|
-
def debug
|
14
|
-
require 'pry'
|
15
|
-
|
16
|
-
binding.pry
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
#
|
22
|
-
require 'seagull/tasks/config'
|
23
|
-
require 'seagull/tasks/version'
|
24
|
-
|
25
|
-
module Seagull
|
26
|
-
class CLI
|
27
|
-
register(Seagull::Tasks::Config, 'config', 'config <command>', 'Manage and display configuration settings')
|
28
|
-
register(Seagull::Tasks::Version, 'version', 'version <command>', 'Version release tasks')
|
29
|
-
end
|
30
|
-
end
|
data/lib/seagull/config.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
require 'hashie/mash'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module Seagull
|
6
|
-
class Config
|
7
|
-
include Singleton
|
8
|
-
|
9
|
-
def initialize
|
10
|
-
@config = Hashie::Mash.new({
|
11
|
-
config: {file: '.seagull'},
|
12
|
-
version: {file: 'VERSION.yml', format: :apple}
|
13
|
-
})
|
14
|
-
|
15
|
-
load
|
16
|
-
end
|
17
|
-
|
18
|
-
def load
|
19
|
-
if File.exists?(@config.config.file)
|
20
|
-
@config.deep_merge!(YAML.load_file(@config.config.file))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def save
|
25
|
-
File.open(@config.config.file, 'w') {|io| io.puts self.to_yaml }
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_yaml
|
29
|
-
@config.to_hash.to_yaml
|
30
|
-
end
|
31
|
-
|
32
|
-
# Proxy
|
33
|
-
def method_missing(m, *args, &blk)
|
34
|
-
@config.send(m, *args, &blk)
|
35
|
-
end
|
36
|
-
|
37
|
-
def respond_to?(m)
|
38
|
-
@config.respond_to?(m)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
data/lib/seagull/tasks/config.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
module Seagull
|
2
|
-
module Tasks
|
3
|
-
class Config < Thor
|
4
|
-
def initialize(*args)
|
5
|
-
super
|
6
|
-
|
7
|
-
@config = Seagull::Config.instance
|
8
|
-
end
|
9
|
-
|
10
|
-
desc "print [KEY]", "Prints current config, with optionally filtering using key"
|
11
|
-
def print(key = nil)
|
12
|
-
cfgs = _build_config_array(@config.to_hash)
|
13
|
-
|
14
|
-
cfgs.select!{|cfg| cfg.first[/#{key}/] } if key
|
15
|
-
|
16
|
-
print_table(cfgs)
|
17
|
-
end
|
18
|
-
|
19
|
-
desc "set KEY VALUE", 'Sets given key (as path) to given value'
|
20
|
-
def set(key, value)
|
21
|
-
_value = case value
|
22
|
-
when 'true' then true
|
23
|
-
when 'yes' then true
|
24
|
-
when 'false' then false
|
25
|
-
when 'no' then false
|
26
|
-
when /^[0-9]+$/ then value.to_i
|
27
|
-
when /^:[a-zA-Z]+$/ then value[1..-1].to_sym
|
28
|
-
else value
|
29
|
-
end
|
30
|
-
|
31
|
-
keypath = key.split('/')
|
32
|
-
cfg = Hash[keypath.pop, _value]
|
33
|
-
while k = keypath.pop
|
34
|
-
cfg = Hash[k, cfg]
|
35
|
-
end
|
36
|
-
@config.deep_merge!(cfg)
|
37
|
-
|
38
|
-
@config.save
|
39
|
-
say_status "config", "#{key} set to #{_value}", :green
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
def _build_config_array(cfg, prefix = '')
|
44
|
-
cfgs = []
|
45
|
-
|
46
|
-
cfg.each do |key, value|
|
47
|
-
if value.kind_of?(Hash)
|
48
|
-
cfgs += _build_config_array(value, "#{prefix}/#{key}")
|
49
|
-
else
|
50
|
-
cfgs << ["#{prefix}/#{key}", value]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
cfgs
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'seagull/version'
|
2
|
-
|
3
|
-
module Seagull
|
4
|
-
module Tasks
|
5
|
-
class Version < Thor
|
6
|
-
VERSION = Seagull::Version.instance
|
7
|
-
CONFIG = Seagull::Config.instance
|
8
|
-
|
9
|
-
desc "print", "Prints current version (#{VERSION.to_s})"
|
10
|
-
def print
|
11
|
-
say_status "current", "Version %s (%s)" % [VERSION.marketing, VERSION.bundle], :blue
|
12
|
-
end
|
13
|
-
|
14
|
-
desc "list", "List all versions and majors"
|
15
|
-
def list
|
16
|
-
if CONFIG.version.format != :apple
|
17
|
-
say_status "UNKNOWN", "Used version format not using version <-> major coding"
|
18
|
-
exit
|
19
|
-
end
|
20
|
-
|
21
|
-
if !CONFIG.versions?
|
22
|
-
say_status "UNKNOWN", "Versions and majors have not been defined"
|
23
|
-
exit
|
24
|
-
end
|
25
|
-
|
26
|
-
table = [['Version', 'Major Version']]
|
27
|
-
table += CONFIG.versions.collect{|k,v| ["%6s.%-3s" % v.split('.'), k.to_i]}.sort
|
28
|
-
|
29
|
-
print_table table
|
30
|
-
end
|
31
|
-
|
32
|
-
desc "bumplist", "List all possible bump versions"
|
33
|
-
def bumplist
|
34
|
-
peeks = [:release, :patch, :update, :build]
|
35
|
-
versions = [['Type', 'Version']]
|
36
|
-
versions += peeks.collect{|t| [t.to_s, VERSION.peek(t)]}
|
37
|
-
|
38
|
-
print_table versions
|
39
|
-
end
|
40
|
-
|
41
|
-
desc "release [MAJOR] [VERSION]", "Releases new version (#{VERSION.peek(:release)})"
|
42
|
-
def release(major = nil, version = nil)
|
43
|
-
VERSION.release(major, version)
|
44
|
-
|
45
|
-
say_status "RELEASE", "Version #{VERSION.to_s} has been released", :green
|
46
|
-
rescue => e
|
47
|
-
say_status "FAILED", e.message, :red
|
48
|
-
end
|
49
|
-
|
50
|
-
desc "name [VERSION_NAME]", "Name current major release (#{VERSION.major})"
|
51
|
-
def name(ver_name)
|
52
|
-
CONFIG.versions![VERSION.major] = ver_name; CONFIG.save
|
53
|
-
say_status "version", "Version #{VERSION.major} named as #{ver_name}"
|
54
|
-
end
|
55
|
-
|
56
|
-
desc "patch", "Release new patch version (#{VERSION.peek(:patch)})"
|
57
|
-
def patch
|
58
|
-
VERSION.patch
|
59
|
-
say_status "PATCH", "Version increased #{VERSION.to_s}"
|
60
|
-
end
|
61
|
-
|
62
|
-
desc "update", "Release new update (#{VERSION.peek(:update)})"
|
63
|
-
def update
|
64
|
-
VERSION.update
|
65
|
-
say_status "update", "Version update to #{VERSION.to_s}"
|
66
|
-
end
|
67
|
-
|
68
|
-
desc "build [BUILDNUMBER]", "Increases build number (#{VERSION.peek(:build)}), optionally set to given number"
|
69
|
-
def build(buildnumber = nil)
|
70
|
-
if buildnumber
|
71
|
-
VERSION.set(build: buildnumber)
|
72
|
-
else
|
73
|
-
VERSION.build
|
74
|
-
end
|
75
|
-
say_status "version", "Increased build number to #{VERSION.to_s}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'versionomy'
|
2
|
-
|
3
|
-
module Versionomy
|
4
|
-
module Format
|
5
|
-
def self.apple
|
6
|
-
get('apple')
|
7
|
-
end
|
8
|
-
|
9
|
-
module Apple
|
10
|
-
module ExtraMethods
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.create
|
15
|
-
schema_ = Schema.create do
|
16
|
-
field(:major, :type => :integer, :default_value => 1) do
|
17
|
-
field(:minor, :type => :string, :default_value => 'A') do
|
18
|
-
field(:build, :type => :integer, :default_value => 1) do
|
19
|
-
field(:update, :type => :string)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
add_module(Format::Apple::ExtraMethods)
|
25
|
-
end
|
26
|
-
|
27
|
-
Format::Delimiter.new(schema_) do
|
28
|
-
field(:major) do
|
29
|
-
recognize_number(:delimiter_regexp => '', :default_delimiter => '')
|
30
|
-
end
|
31
|
-
|
32
|
-
field(:minor) do
|
33
|
-
recognize_regexp('[A-Z]',:delimiter_regexp => '', :default_delimiter => '')
|
34
|
-
end
|
35
|
-
|
36
|
-
field(:build) do
|
37
|
-
recognize_number(:delimiter_regexp => '', :default_delimiter => '')
|
38
|
-
end
|
39
|
-
|
40
|
-
field(:update) do
|
41
|
-
recognize_regexp('[a-z]', :delimiter_regexp => '', :default_delimiter => '', :default_value_optional => true)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
register('apple', Format::Apple.create, true)
|
48
|
-
end
|
49
|
-
|
50
|
-
module Conversion
|
51
|
-
module Apple
|
52
|
-
def self.create_standard_to_apple
|
53
|
-
Conversion::Parsing.new do
|
54
|
-
to_modify_original_value do |original_, convert_params_|
|
55
|
-
apple_version = {
|
56
|
-
major: original_.major,
|
57
|
-
minor: ('A'..'Z').to_a[original_.minor],
|
58
|
-
build: original_.tiny2,
|
59
|
-
update: (original_.tiny > 0 ? ('a'..'z').to_a[original_.tiny - 1] : nil),
|
60
|
-
}
|
61
|
-
Versionomy.create(apple_version, :apple)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def self.create_apple_to_standard
|
67
|
-
Conversion::Parsing.new do
|
68
|
-
to_modify_original_value do |original_, convert_params_|
|
69
|
-
if convert_params_[:versions]
|
70
|
-
major, minor = convert_params_[:versions][original_.major].split(".").map(&:to_i)
|
71
|
-
tiny = ('A'..'Z').to_a.index(original_.minor)
|
72
|
-
tiny2 = original_.build
|
73
|
-
patchlevel = !original_.update.empty? ? (('a'..'z').to_a.index(original_.update) + 1) : nil
|
74
|
-
else
|
75
|
-
major = original_.major
|
76
|
-
minor = ('A'..'Z').to_a.index(original_.minor)
|
77
|
-
tiny = !original_.update.empty? ? (('a'..'z').to_a.index(original_.update) + 1) : nil
|
78
|
-
tiny2 = original_.build
|
79
|
-
patchlevel = nil
|
80
|
-
end
|
81
|
-
|
82
|
-
Versionomy.create({major: major, minor: minor, tiny: tiny, tiny2: tiny2, patchlevel: patchlevel})
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
register(:standard, :apple, Conversion::Apple.create_standard_to_apple, true)
|
89
|
-
register(:apple, :standard, Conversion::Apple.create_apple_to_standard, true)
|
90
|
-
end
|
91
|
-
end
|