firim 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.
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: []