firim 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 71ce22fb2fae197455cca05de2c9e26dea236a89
4
+ data.tar.gz: 4fb4e7dbfd738e0c2b61c2e5b47c84f2c55a06d7
5
+ SHA512:
6
+ metadata.gz: f5349626a9c64773773b7dd094e315ce5f6f06ca7f11dccdafeb38a8551769fcafa5d054d2737c41784854c1e1b958b58f55a148d743022242a158497f7f00be
7
+ data.tar.gz: e1c696a1ff9b3e678a106f712a0c921b4cdb2db20cdbb3bf0a2680854de1a75c97f3ddd5bb78f77f618b221444f971977cc517e1d95fb62f8cba9e8ac446aaf2
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Firim
2
+
3
+ Firim is a command tool to directly upload ipa and change app infomation on fir.im. fir.im is a Beta APP host website, you can upload ipa for AdHoc or InHouse distribution for testing.
4
+
5
+ ## Getting Started
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'firim'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install firim
20
+
21
+ ## Quick Start
22
+
23
+ * `cd [your_project_folder]`
24
+ * `firim init`
25
+ * Enter your fir.im API Token (From [Fir.im](http://fir.im/apps))
26
+ * `firim -i [your_ipa_path]`
27
+
28
+ # Usage
29
+
30
+ Use with fastlane [fastlane-plugin-firim](fastlane-plugin-firim/)
31
+
32
+ You can specify the app infomations in `Firimfile`, To get a list of available options run
33
+
34
+ firim --help
35
+
36
+ Upload with icon ***NOTICE: Icon must be jpg format***
37
+
38
+ firim -i [your_ipa_path] -l [your_icon_path]
39
+
40
+ # Need help?
41
+
42
+ Please submit an issue on GitHub and provide information about your setup
43
+
44
+
45
+ ## Contributing
46
+
47
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/whlsxl/firim](https://github.com/whlsxl/firim). This project is intended to be a safe, welcoming space for collaboration.
48
+
49
+
50
+ ## License
51
+
52
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
53
+
54
+ # TODO
55
+
56
+ * Export all app infomation to a file
57
+ * Generate a web page show all the app's link and infomations
58
+ * Show the app list, and export all app infomations to a file
data/bin/firim ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $:.push File.expand_path("../../lib", __FILE__)
3
+
4
+ require 'firim'
5
+ Firim::CommandsGenerator.start
@@ -0,0 +1,5 @@
1
+ ###################### More Options ######################
2
+ # If you want to have even more control, check out the documentation
3
+ # https://github.com/fastlane/fastlane/blob/master/deliver/Deliverfile.md
4
+
5
+ firim_api_token "[[FIRIM_API_TOKEN]]" # The fir.im api token
data/lib/firim.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'firim/commands_generator'
2
+ require 'firim/detect_values'
3
+ require 'firim/options'
4
+ require 'firim/runner'
5
+ require 'firim/setup'
6
+ require "firim/version"
7
+
8
+ require 'fastlane_core'
9
+
10
+ module Firim
11
+ class << self
12
+ end
13
+
14
+ Helper = FastlaneCore::Helper # you gotta love Ruby: Helper.* should use the Helper class contained in FastlaneCore
15
+ UI = FastlaneCore::UI
16
+
17
+ # Constant that captures the root Pathname for the project. Should be used for building paths to assets or other
18
+ # resources that code needs to locate locally
19
+ ROOT = Pathname.new(File.expand_path('../..', __FILE__))
20
+ end
@@ -0,0 +1,68 @@
1
+ require 'commander'
2
+
3
+ module Firim
4
+ class CommandsGenerator
5
+ include Commander::Methods
6
+
7
+ # def self.start
8
+ # FastlaneCore::UpdateChecker.start_looking_for_update('deliver')
9
+ # self.new.run
10
+ # ensure
11
+ # FastlaneCore::UpdateChecker.show_update_status('deliver', Deliver::VERSION)
12
+ # end
13
+
14
+ def self.start
15
+ self.new.run
16
+ end
17
+
18
+ def run
19
+ program :version, Firim::VERSION
20
+ program :description, 'fir.im command tool'
21
+ program :help, 'Author', 'Hailong Wang <whlsxl+g@gmail.com>'
22
+ program :help, 'GitHub', 'https://github.com/fastlane/fastlane/tree/master/deliver'
23
+ program :help_formatter, :compact
24
+
25
+ FastlaneCore::CommanderGenerator.new.generate(Firim::Options.available_options)
26
+ global_option('--verbose') { $verbose = true }
27
+
28
+ always_trace!
29
+
30
+ command :run do |c|
31
+ c.syntax = 'firim'
32
+ c.description = 'Upload binary and infomations to Fir.im'
33
+ c.action do |args, options|
34
+ options = FastlaneCore::Configuration.create(Firim::Options.available_options, options.__hash__)
35
+ loaded = options.load_configuration_file("Firimfile")
36
+ loaded = true if options[:firim_api_token]
37
+ unless loaded
38
+ if UI.confirm("No firim configuration found in the current directory. Do you want to setup firim?")
39
+ require 'deliver/setup'
40
+ Firim::Setup.new.run(options)
41
+ return 0
42
+ end
43
+ end
44
+ Firim::Runner.new(options).run
45
+ end
46
+ end
47
+
48
+ command :init do |c|
49
+ c.syntax = 'firim init'
50
+ c.description = 'Create the initial `Firimfile` configuration'
51
+ c.action do |args, options|
52
+ if File.exist?("Firimfile") or File.exist?("fastlane/Firimfile")
53
+ UI.important("You already got a running firim setup in this directory")
54
+ return 0
55
+ end
56
+
57
+ require 'firim/setup'
58
+ options = FastlaneCore::Configuration.create(Firim::Options.available_options, options.__hash__)
59
+ Firim::Setup.new.run(options)
60
+ end
61
+ end
62
+
63
+ default_command :run
64
+
65
+ run!
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,41 @@
1
+ module Firim
2
+ class DetectValues
3
+ def run!(options)
4
+ find_firim_api_token(options)
5
+ find_app_identifier(options)
6
+ find_app_name(options)
7
+ find_version(options)
8
+ find_build_version(options)
9
+ end
10
+
11
+ def find_app_identifier(options)
12
+ identifier = FastlaneCore::IpaFileAnalyser.fetch_app_identifier(options[:ipa])
13
+ if identifier.to_s.length != 0
14
+ options[:app_identifier] = identifier
15
+ else
16
+ UI.user_error!("Could not find ipa with app identifier '#{options[:app_identifier]}' in your iTunes Connect account (#{options[:username]} - Team: #{Spaceship::Tunes.client.team_id})")
17
+ end
18
+ end
19
+
20
+ def find_app_name(options)
21
+ return if options[:app_name]
22
+ plist = FastlaneCore::IpaFileAnalyser.fetch_info_plist_file(options[:ipa])
23
+ options[:app_name] ||= plist['CFBundleDisplayName']
24
+ options[:app_name] ||= plist['CFBundleName']
25
+ end
26
+
27
+ def find_version(options)
28
+ options[:app_version] ||= FastlaneCore::IpaFileAnalyser.fetch_app_version(options[:ipa])
29
+ end
30
+
31
+ def find_build_version(options)
32
+ plist = FastlaneCore::IpaFileAnalyser.fetch_info_plist_file(options[:ipa])
33
+ options[:app_build_version] = plist['CFBundleVersion']
34
+ end
35
+
36
+ def find_firim_api_token(options)
37
+ return if options[:firim_api_token]
38
+ options[:firim_api_token] ||= UI.input("The API Token of fir.im: ")
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,78 @@
1
+ require 'fastlane_core'
2
+ require 'credentials_manager'
3
+
4
+ module Firim
5
+ class Options
6
+ def self.available_options
7
+ [
8
+ # firim info
9
+ FastlaneCore::ConfigItem.new(key: :firim_api_token,
10
+ short_option: "-a",
11
+ description: "fir.im user api token"),
12
+
13
+ # Content path
14
+ FastlaneCore::ConfigItem.new(key: :ipa,
15
+ short_option: "-i",
16
+ env_name: "DELIVER_IPA_PATH",
17
+ description: "Path to your ipa file",
18
+ default_value: Dir["*.ipa"].first,
19
+ verify_block: proc do |value|
20
+ UI.user_error!("Could not find ipa file at path '#{value}'") unless File.exist?(value)
21
+ UI.user_error!("'#{value}' doesn't seem to be an ipa file") unless value.end_with?(".ipa")
22
+ end,
23
+ conflicting_options: [:pkg],
24
+ conflict_block: proc do |value|
25
+ UI.user_error!("You can't use 'ipa' and '#{value.key}' options in one run.")
26
+ end),
27
+ FastlaneCore::ConfigItem.new(key: :icon,
28
+ description: "Path to the app icon, MUST BE jpg",
29
+ optional: true,
30
+ short_option: "-l",
31
+ verify_block: proc do |value|
32
+ UI.user_error!("Could not find png file at path '#{value}'") unless File.exist?(value)
33
+ UI.user_error!("'#{value}' doesn't seem to be a png file") unless value.end_with?(".jpg")
34
+ end),
35
+ # APP info
36
+ FastlaneCore::ConfigItem.new(key: :app_identifier,
37
+ description: "The app's identifier",
38
+ optional: true),
39
+ FastlaneCore::ConfigItem.new(key: :app_name,
40
+ description: "The app's name",
41
+ optional: true),
42
+ FastlaneCore::ConfigItem.new(key: :app_desc,
43
+ description: "The app's desc",
44
+ optional: true),
45
+ FastlaneCore::ConfigItem.new(key: :app_short,
46
+ description: "The app's short URL",
47
+ optional: true),
48
+ FastlaneCore::ConfigItem.new(key: :app_is_opened,
49
+ description: "APP's download link whether opened",
50
+ is_string: false,
51
+ optional: true),
52
+ FastlaneCore::ConfigItem.new(key: :app_is_show_plaza,
53
+ description: "Whether the app show in plaza",
54
+ is_string: false,
55
+ optional: true),
56
+ FastlaneCore::ConfigItem.new(key: :app_passwd,
57
+ description: "The app's download page password",
58
+ optional: true),
59
+ FastlaneCore::ConfigItem.new(key: :app_store_link_visible,
60
+ description: "Whether show store link in download page",
61
+ is_string: false,
62
+ optional: true),
63
+ FastlaneCore::ConfigItem.new(key: :app_version,
64
+ description: "The app's version",
65
+ optional: true),
66
+ FastlaneCore::ConfigItem.new(key: :app_build_version,
67
+ description: "The app's build version",
68
+ optional: true),
69
+ FastlaneCore::ConfigItem.new(key: :app_release_type,
70
+ description: "The app's release type (Adhoc, Inhouse)",
71
+ optional: true),
72
+ FastlaneCore::ConfigItem.new(key: :app_changelog,
73
+ description: "The app's changelog",
74
+ optional: true)
75
+ ]
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,145 @@
1
+ require 'faraday' # HTTP Client
2
+ require 'faraday_middleware'
3
+ # require 'logger'
4
+
5
+ module Firim
6
+ class Runner
7
+ attr_accessor :options
8
+ attr_reader :firim_client
9
+
10
+ def self.firim_hostname
11
+ return "http://api.fir.im/"
12
+ end
13
+
14
+ def initialize(options)
15
+ self.options = options
16
+ @app_info = {}
17
+
18
+ conn_options = {
19
+ request: {
20
+ timeout: 300,
21
+ open_timeout: 300
22
+ }
23
+ }
24
+
25
+ @firim_client = Faraday.new(self.class.firim_hostname, conn_options) do |c|
26
+ c.request :url_encoded # form-encode POST params
27
+ c.adapter :net_http
28
+ c.response :json, :content_type => /\bjson$/
29
+ end
30
+
31
+ Firim::DetectValues.new.run!(self.options)
32
+ FastlaneCore::PrintTable.print_values(config: options, title: "firim #{Firim::VERSION} Summary")
33
+ end
34
+
35
+ def run
36
+ # FastlaneCore::PrintTable.print_values(config: get_app_info, title: "Current online infomation")
37
+ @app_info.merge( upload_binary_and_icon )
38
+
39
+ end
40
+
41
+ def validation_response response_data
42
+ error_code = response_data['errors']['code'].to_int rescue 0
43
+ if error_code == 100020
44
+ UI.user_error!("Firim API Token(#{options[:firim_api_token]}) not correct")
45
+ end
46
+ end
47
+
48
+ def get_app_info
49
+ app_info_path = "apps/latest/" + options[:app_identifier]
50
+ response = self.firim_client.get app_info_path, { :api_token => options[:firim_api_token], :type => "ios" }
51
+ info = response.body == nil ? {} : response.body
52
+ validation_response info
53
+ info
54
+ end
55
+
56
+ def upload_binary_and_icon
57
+ upload_publish_path = "apps/"
58
+ response = self.firim_client.post do |req|
59
+ req.url upload_publish_path
60
+ req.body = { :type => 'ios', :bundle_id => options[:app_identifier], :api_token => options[:firim_api_token] }
61
+ end
62
+ info = response.body
63
+ validation_response info
64
+ begin
65
+ upload_binary info['cert']['binary']
66
+ upload_icon info['cert']['icon']
67
+ rescue Exception => e
68
+ # raise UI.user_error!("Firim Server error #{e}\n #{info}")
69
+ raise e
70
+ end
71
+ info.select { |k, v| ["id", "type", "short"].include?(k) }
72
+ end
73
+
74
+ def get_upload_conn
75
+ conn_options = {
76
+ request: {
77
+ timeout: 1000,
78
+ open_timeout: 300
79
+ }
80
+ }
81
+ Faraday.new(nil, conn_options) do |c|
82
+ c.request :multipart
83
+ c.request :url_encoded
84
+ c.response :json, content_type: /\bjson$/
85
+ c.adapter :net_http
86
+ end
87
+ end
88
+
89
+ def upload_binary binary_info
90
+ params = {
91
+ 'key' => binary_info['key'],
92
+ 'token' => binary_info['token'],
93
+ 'file' => Faraday::UploadIO.new(self.options[:ipa], 'application/octet-stream'),
94
+ 'x:name' => self.options[:app_name],
95
+ 'x:version' => self.options[:app_version],
96
+ 'x:build' => self.options[:app_build_version]
97
+ }
98
+ params['x:release_type'] = self.options[:app_release_type] if self.options[:app_release_type]
99
+ params['x:changelog'] = self.options[:app_changelog] if self.options[:app_changelog]
100
+ binary_conn = get_upload_conn
101
+ UI.message "Start upload #{self.options[:app_name]} binary..."
102
+ response = binary_conn.post binary_info['upload_url'], params
103
+ unless response.body['is_completed']
104
+ raise UI.user_error!("Upload binary to Qiniu error #{response.body}")
105
+ end
106
+ UI.success 'Upload binary successed!'
107
+ end
108
+
109
+ def upload_icon icon_info
110
+ return unless self.options[:icon]
111
+ binary_conn = get_upload_conn
112
+ params = {
113
+ 'key' => icon_info['key'],
114
+ 'token' => icon_info['token'],
115
+ 'file' => Faraday::UploadIO.new(self.options[:icon], 'image/jpeg'),
116
+ }
117
+ UI.message "Start upload #{self.options[:app_name]} icon..."
118
+ response = binary_conn.post icon_info['upload_url'], params
119
+ unless response.body['is_completed']
120
+ raise UI.user_error!("Upload icon to Qiniu error #{response.body}")
121
+ end
122
+ UI.success 'Upload icon successed!'
123
+ end
124
+
125
+ def update_app_info id
126
+ params = {
127
+ :api_token => options[:firim_api_token]
128
+ }
129
+ ["name", "desc", "short", "is_opened", "is_show_plaza", "passwd", "store_link_visible"].each do |k|
130
+ key = :"app_#{k}"
131
+ params[k] = options[key] if options[key] != nil
132
+ end
133
+
134
+ update_app_info_path = "apps/#{id}"
135
+ response = self.firim_client.put do |req|
136
+ req.url update_app_info_path
137
+ req.body = params
138
+ end
139
+ info = response.body
140
+ validation_response info
141
+ UI.success "Update app info successed!"
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,25 @@
1
+
2
+ module Firim
3
+ class Setup
4
+ def run(options)
5
+ containing = (File.directory?("fastlane") ? 'fastlane' : '.')
6
+ file_path = File.join(containing, 'Firimfile')
7
+ data = generate_firim_file(containing, options)
8
+ setup_firim(file_path, data, containing, options)
9
+ end
10
+
11
+ def generate_firim_file(firim_path, options)
12
+ # Generate the final Firimfile here
13
+ firim = File.read("#{Firim::ROOT}/lib/assets/FirimfileDefault")
14
+ firim.gsub!("[[FIRIM_API_TOKEN]]", options[:firim_api_token])
15
+ return firim
16
+ end
17
+
18
+ def setup_firim(file_path, data, firim_path, options)
19
+ File.write(file_path, data)
20
+
21
+ UI.success("Successfully created new Firimfile at path '#{file_path}'")
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Firim
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,167 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: firim
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - whlsxl
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fastlane_core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.52.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 1.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.52.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 1.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: credentials_manager
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 0.16.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 1.0.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 0.16.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 1.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: faraday
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.9'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '0.9'
67
+ - !ruby/object:Gem::Dependency
68
+ name: faraday_middleware
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '0.9'
74
+ type: :runtime
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '0.9'
81
+ - !ruby/object:Gem::Dependency
82
+ name: bundler
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '1.12'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '1.12'
95
+ - !ruby/object:Gem::Dependency
96
+ name: rake
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '10.0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '10.0'
109
+ - !ruby/object:Gem::Dependency
110
+ name: minitest
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '5.0'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '5.0'
123
+ description: |-
124
+ fir.im command tool,
125
+ Upload ipa to fir.im
126
+ email:
127
+ - whlsxl+g@gmail.com
128
+ executables:
129
+ - firim
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - README.md
134
+ - bin/firim
135
+ - lib/assets/FirimfileDefault
136
+ - lib/firim.rb
137
+ - lib/firim/commands_generator.rb
138
+ - lib/firim/detect_values.rb
139
+ - lib/firim/options.rb
140
+ - lib/firim/runner.rb
141
+ - lib/firim/setup.rb
142
+ - lib/firim/version.rb
143
+ homepage: https://github.com/whlsxl/firim
144
+ licenses:
145
+ - MIT
146
+ metadata: {}
147
+ post_install_message:
148
+ rdoc_options: []
149
+ require_paths:
150
+ - lib
151
+ required_ruby_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ requirements: []
162
+ rubyforge_project:
163
+ rubygems_version: 2.5.1
164
+ signing_key:
165
+ specification_version: 4
166
+ summary: fir.im command tool
167
+ test_files: []