mesmerize 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mesmerize (0.0.6)
4
+ mesmerize (0.1.0)
5
5
  commander (~> 4.1.2)
6
6
  faraday (~> 0.8.0)
7
7
  faraday_middleware (~> 0.8.7)
data/bin/mesmerize CHANGED
@@ -4,7 +4,6 @@ require 'commander/import'
4
4
 
5
5
  $:.push File.expand_path("../../lib", __FILE__)
6
6
  require 'mesmerize'
7
- require 'mesmerize/commands'
8
7
 
9
8
  HighLine.track_eof = false # Fix for built-in Ruby
10
9
 
@@ -12,8 +11,10 @@ program :version, Mesmerize::VERSION
12
11
  program :description, 'A command-line interface for Mesmerize'
13
12
 
14
13
  program :help, 'Author', 'Mattt Thompson <m@mattt.me>'
15
- program :help, 'Website', 'http://mesmerizeapp.com'
14
+ program :help, 'Website', 'https://mesmerizeapp.com'
16
15
  program :help_formatter, :compact
17
16
 
18
- global_option '--verbose'
17
+ # global_option '--verbose'
19
18
  default_command :help
19
+
20
+ require 'mesmerize/commands'
@@ -66,11 +66,7 @@ module Mesmerize
66
66
  end
67
67
  end
68
68
 
69
- def post_release(app, release, file)
70
- params = {
71
- :version => release.to_s
72
- }
73
-
69
+ def post_release(app, params, file)
74
70
  @connection.post("/api/apps/#{app}/releases", params).on_complete do |env|
75
71
  if (200...300).include? env[:status]
76
72
  params = env[:body]["params"]
@@ -0,0 +1,86 @@
1
+ command :build do |c|
2
+ c.syntax = 'mesmerize build [options] [output]'
3
+ c.summary = 'Create a new build of your app'
4
+ c.description = ''
5
+
6
+ c.example 'description', 'mesmerize release 478 --tag 3.7.2 --scheme MyApp+Sparkle'
7
+ c.option '-w', '--workspace WORKSPACE', 'Workspace (.xcworkspace) file to use to build app (automatically detected in current directory)'
8
+ c.option '-p', '--project PROJECT', 'Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed)'
9
+ c.option '-s', '--scheme SCHEME', 'Scheme used to build app'
10
+ c.option '-q', '--quiet', 'Silence warning and success messages'
11
+
12
+ c.action do |args, options|
13
+ require_authorization!
14
+ validate_xcode_version!
15
+
16
+ begin
17
+ @xcodebuild_info = Mesmerize::XcodeBuildInfo.info
18
+
19
+ @workspace = options.workspace
20
+ @project = options.project
21
+ @scheme = options.scheme
22
+
23
+ determine_workspace_or_project! unless @workspace || @project
24
+
25
+ determine_scheme! unless @scheme
26
+ say_error "Scheme #{@scheme} not found" and abort unless @xcodebuild_info.schemes.include?(@scheme)
27
+
28
+ say_warning "Building \"#{@workspace || @project}\" with scheme \"#{@scheme}\"\n" unless options.quiet
29
+
30
+ destination = File.join("/tmp/mesmerize/", "#{@xcodebuild_info.project}-#{Time.now.to_i}")
31
+ log "xcodebuild", (@workspace || @project)
32
+
33
+ opts = []
34
+ opts << "-workspace '#{@workspace}'" if @workspace
35
+ opts << "-project '#{@project}'" if @project
36
+ opts << "-scheme '#{@scheme}'" if @scheme
37
+
38
+ ["DSTROOT", "DWARF_DSYM_FOLDER_PATH", "CONFIGURATION_BUILD_DIR"].each do |k|
39
+ opts << "#{k}=#{destination}"
40
+ end
41
+ opts << "DEPLOYMENT_LOCATION=YES"
42
+
43
+ ENV['CC'] = nil # Fix for RVM
44
+ abort unless system "xcodebuild -sdk macosx #{opts.join(' ')} clean build 1> /dev/null"
45
+
46
+ app = Dir["#{destination}/**/*.app"].detect{|app| File.basename(app, ".app") == @xcodebuild_info.project}
47
+ say_error "Could not find build product in #{destination}" and abort unless app
48
+
49
+ output = args.pop || "./"
50
+ say_error "Could not move #{app} to #{output}" and abort unless system "mv #{app} #{output}"
51
+ say_ok "#{File.basename(app)} successfully built" unless options.quiet
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def determine_workspace_or_project!
58
+ workspaces, projects = Dir["*.xcworkspace"], Dir["*.xcodeproj"]
59
+
60
+ if workspaces.empty?
61
+ if projects.empty?
62
+ say_error "No Xcode projects or workspaces found in current directory" and abort
63
+ else
64
+ if projects.length == 1
65
+ @project = projects.first
66
+ else
67
+ @project = choose "Select a project:", *projects
68
+ end
69
+ end
70
+ else
71
+ if workspaces.length == 1
72
+ @workspace = workspaces.first
73
+ else
74
+ @workspace = choose "Select a workspace:", *workspaces
75
+ end
76
+ end
77
+ end
78
+
79
+ def determine_scheme!
80
+ if @xcodebuild_info.schemes.length == 1
81
+ @scheme = @xcodebuild_info.schemes.first
82
+ else
83
+ @scheme = choose "Select a scheme:", *@xcodebuild_info.schemes
84
+ end
85
+ end
86
+ end
@@ -1,121 +1,82 @@
1
1
  command :release do |c|
2
- c.syntax = 'mesmerize release [VERSION] [options]'
2
+ c.syntax = 'mesmerize release [options]'
3
3
  c.summary = 'Release a new build of your app'
4
4
  c.description = ''
5
5
 
6
6
  c.example 'description', 'mesmerize release 478 --tag 3.7.2 --scheme MyApp+Sparkle'
7
7
  c.option '-a', '--app APP', 'Name of App'
8
- c.option '-t', '--tag TAG', 'Marketing Version Number (e.g. 3.7.2)'
8
+ c.option '-r', '--build BUILD', Integer, "Build Version Number (CFBundleVersion, e.g. 2663)"
9
+ c.option '-t', '--tag TAG', 'Marketing Version Number (CFBundleShortVersionString, e.g. 3.7.2)'
9
10
  c.option '-w', '--workspace WORKSPACE', 'Workspace (.xcworkspace) file to use to build app (automatically detected in current directory)'
10
11
  c.option '-p', '--project PROJECT', 'Project (.xcodeproj) file to use to build app (automatically detected in current directory, overridden by --workspace option, if passed)'
11
12
  c.option '-s', '--scheme SCHEME', 'Scheme used to build app'
13
+ c.option '-m', '--release-notes NOTES', 'Notes for this release'
12
14
 
13
15
  c.action do |args, options|
14
16
  require_authorization!
17
+ validate_xcode_version!
15
18
 
16
19
  begin
17
- @info = Mesmerize::XcodeBuildInfo.info
18
-
19
- @appName = options.app || @info.project
20
- @version = args.shift.to_i
21
- @tag = options.tag
22
- @workspace = options.workspace
23
- @project = options.project
24
- @scheme = options.scheme
25
-
26
- @appSlug = @appName.strip.gsub(/\s+/, '-')
27
-
28
- say "Found project \"#{@appName}\"."
29
- say "Looking up current release information..."
30
-
31
- response = client.get_app(@appSlug)
32
- if response.status == 404
33
- say_error "Could not find listing for #{@appName}." and say_error "Do `mesmerize create #{@appName}` first." and abort
34
- end
35
-
36
- @app = response.body
37
- if @version.nonzero?
38
- if @version <= @app["version"].to_i
39
- say_error "Specified release (#{@version}) must be greater than current release (#{@app["version"]})" and abort
40
- end
41
- else
42
- if @app["version"]
43
- @version = @app["version"] + 1
44
- say_warning "Bumping release to version #{@version}"
45
- elsif Mesmerize::Agvtool.vers
46
- @version = Mesmerize::Agvtool.vers + 1
47
- say_warning "Bumping release to version #{@version}"
48
- else
49
- say_error "Specify a release version" and abort
50
- end
51
- end
20
+ @xcodebuild_info = Mesmerize::XcodeBuildInfo.info
52
21
 
53
- unless @workspace || @project
54
- workspaces, projects = Dir["*.xcworkspace"], Dir["*.xcodeproj"]
55
- abort "No Xcode projects or workspaces found in current directory" if workspaces.empty? && projects.empty?
56
-
57
- case workspaces.length
58
- when 0
59
- case projects.length
60
- when 0
61
- abort "No Xcode projects or workspaces found in current directory"
62
- when 1
63
- @project = projects.first
64
- else
65
- @project = choose "Select a project:", *projects
66
- end
67
- when 1
68
- @workspace = workspaces.first
69
- else
70
- @workspace = choose "Select a workspace:", *workspaces
71
- end
72
- end
22
+ @app = options.app
23
+ @build_number = options.build
24
+ @tag = options.tag
73
25
 
74
- if @scheme and not @info.schemes.include?(@scheme)
75
- abort "Scheme #{@scheme} not found"
76
- end
26
+ @release_notes = options.release_notes
77
27
 
78
- if @scheme.nil?
79
- @scheme = choose "Select a scheme:", *@info.schemes
80
- end
28
+ determine_current_release_information!
81
29
 
82
- ENV['CC'] = nil # Fix for rvm
30
+ determine_build_number! unless @build_number
31
+ validate_build_number!
32
+
33
+ determine_tag! unless @tag
34
+ validate_tag!
83
35
 
84
- puts
85
- say "Building \"#{@workspace || @project}\" version #{@version} with scheme \"#{@scheme}\"\n"
36
+ determine_release_notes! unless @release_notes
86
37
 
87
38
  log "agvtool", "new-version"
88
- `agvtool -noscm new-version -all #{@version}`
39
+ `agvtool -noscm new-version -all #{@build_number}`
89
40
 
90
41
  if @tag
91
42
  log "agvtool", "new-marketing-version"
92
43
  `agvtool -noscm new-marketing-version #{@tag}`
93
44
  end
94
45
 
95
- [:clean, :build, :archive, :install].each do |action|
96
- log "xcodebuild", action
46
+ @filename = "#{@app["name"]}-#{@build_number}.zip"
97
47
 
98
- options = []
99
- options << "-workspace '#{@workspace}'" if @workspace
100
- options << "-project '#{@project}'" if @project
101
- options << "-scheme '#{@scheme}'" if @scheme
48
+ # Un-parsing and passing options to `build` command
49
+ cargs = options.__hash__.keep_if{|k, v| [:workspace, :project, :scheme].include?(k)}
50
+ command(:build).run(*cargs.collect{|k, v| "--#{k} #{v}"}, "-q", "#{File.basename(@filename, '.zip')}.app")
102
51
 
103
- `xcodebuild #{options.join(" ")} -sdk macosx DSTROOT='./.mesmerize' #{action}`# 1> /dev/null 2> /dev/null`
104
- end
52
+ abort unless system "zip -rmTq #{@filename} #{File.basename(@filename, '.zip')}.app"
105
53
 
54
+ log "upload", @filename
55
+
56
+ params = {
57
+ :version => @build_number.to_s,
58
+ :description => @release_notes,
59
+ :tag => @tag
60
+ }
106
61
 
107
- @filename = "#{@app['name']}-#{@version}.zip"
108
- `pushd .mesmerize/Applications; zip -r #{@filename} #{@app['name']}.app; popd`
62
+ client.post_release(@app["slug"], params, @filename) do |status, body|
63
+ case status
64
+ when 200...300, nil
65
+ log "publish appcast.xml"
109
66
 
110
- @file = ".mesmerize/Applications/" + @filename
67
+ log "delete #{@filename}"
68
+ system "rm -f #{File.basename(@filename, '.zip')}.*"
111
69
 
112
- log "upload", @filename
70
+ puts
71
+ say_ok "Successfully created release, #{@app["name"]} r#{@build_number}"
72
+
73
+ url = "https://#{@app["slug"]}.#{Mesmerize::Client::HOSTNAME}"
74
+ say "See the updated appcast at #{url}/appcast.xml"
113
75
 
114
- client.post_release(@appSlug, @version, @file) do |status, body|
115
- if (200...300).include?(status) || status.nil?
116
- say_ok "Successfully created release, #{@app['name']} r#{@version}"
76
+ puts
77
+ say "Download the latest version at #{url}/latest"
117
78
  else
118
- abort "Unable to create release"
79
+ say_error "Error creating release: #{body}" and abort
119
80
  end
120
81
  end
121
82
  rescue Mesmerize::XcodeBuildInfo::NilOutputError
@@ -124,8 +85,65 @@ command :release do |c|
124
85
  say_error "Xcode Build Error: #{e}" and abort
125
86
  rescue => e
126
87
  say_error "Error: #{e}" and abort
127
- ensure
128
- `rm -rf .mesmerize`
129
88
  end
130
89
  end
131
- end
90
+
91
+ private
92
+
93
+ def validate_xcode_version!
94
+ version = Mesmerize::XcodeBuildInfo.version
95
+ say_error "Mesmerize requires Xcode 4 (found #{version}). Please install or switch to the latest Xcode." and abort if version < "4.0.0"
96
+ end
97
+
98
+ def validate_build_number!
99
+ version = @app["version"].to_i
100
+ if version and @build_number and @build_number <= version
101
+ say_error "Specified build number (#{@build_number}) must be greater than current release (#{version})" and abort
102
+ end
103
+ end
104
+
105
+ def validate_tag!
106
+ # TODO
107
+ end
108
+
109
+ def determine_current_release_information!
110
+ name = @app || @xcodebuild_info.project
111
+
112
+ say "Found project \"#{name}\"."
113
+ say "Looking up current release information..."
114
+
115
+ response = client.get_app(name.gsub(/\s+/, '-'))
116
+ case response.status
117
+ when 200...300
118
+ @app = response.body
119
+ when 404
120
+ say_error "Could not find listing for #{name}." and say_error "Do `mesmerize create #{@app["name"]}` first." and abort
121
+ else
122
+ say_error "Error finding listing for #{name}: #{response.body}" and abort
123
+ end
124
+ end
125
+
126
+ def determine_build_number!
127
+ version = @app["version"].to_i
128
+ if version.nonzero?
129
+ @build_number = version + 1
130
+ say_warning "Bumping release to version #{@build_number}"
131
+ elsif Mesmerize::Agvtool.vers
132
+ @build_number = Mesmerize::Agvtool.vers + 1
133
+ say_warning "Bumping release to version #{@build_number}"
134
+ else
135
+ @build_number = ask_for_integer "Specify a build number (CFBundleVersion)"
136
+ end
137
+ end
138
+
139
+ def determine_tag!
140
+ @tag = Mesmerize::Agvtool.mvers
141
+ end
142
+
143
+ def determine_release_notes!
144
+ placeholder = %{What's new in this release: }
145
+
146
+ @release_notes = ask_editor placeholder
147
+ @release_notes = nil if @release_notes == placeholder
148
+ end
149
+ end
@@ -6,4 +6,5 @@ require 'commands/signup'
6
6
  require 'commands/login'
7
7
  require 'commands/logout'
8
8
  require 'commands/create'
9
- require 'commands/release'
9
+ require 'commands/build'
10
+ require 'commands/release'
@@ -2,22 +2,22 @@ require 'ostruct'
2
2
 
3
3
  module Mesmerize::XcodeBuildInfo
4
4
  class Info < OpenStruct; end
5
-
5
+
6
6
  class Error < StandardError; end
7
7
  class NilOutputError < Error; end
8
-
8
+
9
9
  class << self
10
10
  def info
11
11
  output = `xcodebuild -list 2> /dev/null`
12
12
  raise Error.new $1 if /^xcodebuild\: error\: (.+)$/ === output
13
13
  raise NilOutputError unless /\S/ === output
14
-
14
+
15
15
  lines = output.split(/\n/)
16
16
  hash = {}
17
17
  group = nil
18
-
18
+
19
19
  hash[:project] = lines.shift.match(/\"(.+)\"\:/)[1]
20
-
20
+
21
21
  lines.each do |line|
22
22
  if /\:$/ === line
23
23
  group = line.strip[0...-1].downcase.gsub(/\s+/, '-')
@@ -29,8 +29,13 @@ module Mesmerize::XcodeBuildInfo
29
29
  hash[group] << line.strip
30
30
  end
31
31
  end
32
-
32
+
33
33
  Info.new(hash)
34
34
  end
35
+
36
+ def version
37
+ output = `xcodebuild -version`
38
+ output.scan(/([\d\.?]+)/).flatten.first rescue nil
39
+ end
35
40
  end
36
41
  end
data/lib/mesmerize.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Mesmerize
2
- VERSION = '0.0.6'
2
+ VERSION = '0.1.0'
3
3
  end
4
4
 
5
5
  $:.push File.expand_path('../', __FILE__)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mesmerize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-09 00:00:00.000000000Z
12
+ date: 2012-06-18 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70335819400880 !ruby/object:Gem::Requirement
16
+ requirement: &70094542236220 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.6.1
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70335819400880
24
+ version_requirements: *70094542236220
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70335819400320 !ruby/object:Gem::Requirement
27
+ requirement: &70094542235720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.2
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70335819400320
35
+ version_requirements: *70094542235720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: commander
38
- requirement: &70335819399800 !ruby/object:Gem::Requirement
38
+ requirement: &70094542235260 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 4.1.2
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70335819399800
46
+ version_requirements: *70094542235260
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: json
49
- requirement: &70335819399080 !ruby/object:Gem::Requirement
49
+ requirement: &70094542234800 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.7.3
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70335819399080
57
+ version_requirements: *70094542234800
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: faraday
60
- requirement: &70335819389480 !ruby/object:Gem::Requirement
60
+ requirement: &70094542234340 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.8.0
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70335819389480
68
+ version_requirements: *70094542234340
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: faraday_middleware
71
- requirement: &70335819388920 !ruby/object:Gem::Requirement
71
+ requirement: &70094542233880 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.8.7
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *70335819388920
79
+ version_requirements: *70094542233880
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: netrc
82
- requirement: &70335819388360 !ruby/object:Gem::Requirement
82
+ requirement: &70094542233420 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: 0.7.2
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *70335819388360
90
+ version_requirements: *70094542233420
91
91
  description: Command-Line Interface for Mesmerize
92
92
  email: m@mattt.me
93
93
  executables:
@@ -100,6 +100,7 @@ files:
100
100
  - ./lib/mesmerize/agvtool.rb
101
101
  - ./lib/mesmerize/authentication.rb
102
102
  - ./lib/mesmerize/client.rb
103
+ - ./lib/mesmerize/commands/build.rb
103
104
  - ./lib/mesmerize/commands/create.rb
104
105
  - ./lib/mesmerize/commands/login.rb
105
106
  - ./lib/mesmerize/commands/logout.rb
@@ -126,7 +127,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
126
127
  version: '0'
127
128
  segments:
128
129
  - 0
129
- hash: -3606515878359033241
130
+ hash: -3338072577465810837
130
131
  required_rubygems_version: !ruby/object:Gem::Requirement
131
132
  none: false
132
133
  requirements:
@@ -135,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
136
  version: '0'
136
137
  segments:
137
138
  - 0
138
- hash: -3606515878359033241
139
+ hash: -3338072577465810837
139
140
  requirements: []
140
141
  rubyforge_project:
141
142
  rubygems_version: 1.8.15