xbean 0.0.1

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: d7d8f1096ca9658b373dc9b9031fc9c0824fa78f
4
+ data.tar.gz: 1ee4822c0cfe159e32ec339387905d275629e232
5
+ SHA512:
6
+ metadata.gz: 3f4fd03c2eb9d1c3b81f6d6e5ca7ba48591ca7de16e5ee73c0942db19704f053123a8c381e76f39a9bb60cd94cdb89f9b9e2c425c4de496797f061501231c21f
7
+ data.tar.gz: 1cf7a15409c6225579128eccbdd7c8ab561cd5d4032b410f6fd3aef7690d9d9815503d3f01b0260397bd74bc225e38cf735b0802a861bf16ffc79ef5261834c9
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # bean
2
+ iOS 自动打包工具
data/bin/xbean ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby -W
2
+ # encoding: utf-8
3
+
4
+ require 'xbean'
5
+
6
+ if ARGV.length > 0
7
+ action = ARGV.first
8
+ # file = File.join(Dir.pwd, 'aFile')
9
+ # puts file
10
+
11
+ Bean::Runner.new.exec(action)
12
+
13
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ module Action
4
+
5
+ class BeanAction
6
+ def initialize(bean_file)
7
+ @bean_file = bean_file
8
+ @configs = {}
9
+ define_bean_action
10
+ end
11
+
12
+ # Run the action with action name.
13
+
14
+ # def run(name)
15
+ # puts "action name: #{name}"
16
+ # return puts "The action `#{name}` does not exist" unless config = @configs[name.to_sym]
17
+ # puts "archive info:"
18
+ # XcodeBuilder::Archiver.new(config)
19
+ # end
20
+
21
+
22
+ private
23
+
24
+ def define_bean_action
25
+ configs = {}
26
+ Kernel.send :define_method, :bean do |name, &block|
27
+ # yield add_config(Workspace::Config.new(name)) if block
28
+ config = Workspace::Config.new(name)
29
+ block.call(config)
30
+ configs[config.name.to_sym] = config
31
+ end
32
+
33
+ load @bean_file
34
+
35
+ BeanAction.send :define_method, :run do |name|
36
+ # puts "action name: #{name}"
37
+ return puts "The action `#{name}` does not exist" unless config = configs[name.to_sym]
38
+ # puts "archive info:"
39
+ XcodeBuilder::Archiver.archive(config)
40
+ end
41
+
42
+ end
43
+
44
+ def add_config(config)
45
+ @configs[config.name.to_sym] = archiver
46
+ end
47
+ end
48
+
49
+
50
+ end
51
+
52
+ # module Kernel
53
+ # def bean(name, )
54
+ # end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ class String
4
+ def method_missing(m, *args)
5
+ color(m)
6
+ end
7
+
8
+ private
9
+
10
+ def color(key)
11
+ color_map = {
12
+ black: "\033[30m#{self}\033[0m",
13
+ red: "\033[31m#{self}\033[0m",
14
+ green: "\033[32m#{self}\033[0m",
15
+ yellow: "\033[33m#{self}\033[0m",
16
+ blue: "\033[34m#{self}\033[0m",
17
+ purple: "\033[35m#{self}\033[0m",
18
+ darkgreen: "\033[36m#{self}\033[0m",
19
+ white: "\033[37m#{self}\033[0m",
20
+ }
21
+ color_map[key]
22
+ end
23
+
24
+ end
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ require_relative 'table'
4
+ require_relative 'colored'
5
+
6
+ module Workspace
7
+ class Config
8
+ attr_reader :name
9
+
10
+ def initialize(name)
11
+ @name = name.to_s
12
+ @configs = {}
13
+ end
14
+
15
+ def method_missing(m, *args)
16
+ # puts "config ---- method: #{m.to_s}, args: #{args}"
17
+ name = m.to_s
18
+ name = m.to_s.delete('=') if m.to_s =~ /=$/
19
+ return unless %w(workspace scheme output_name compile_bitcode method signing_style team_id thinning).include? name
20
+ if m.to_s =~ /=$/
21
+ add_configuration(m.to_s.delete('='), args.first)
22
+ else
23
+ @configs[m.to_sym]
24
+ end
25
+ end
26
+
27
+ # The ExportOptions Plist object.
28
+
29
+ def export_options_plist
30
+ get_team_identifier
31
+
32
+ plist = ExportOptions::Plist.new(@name)
33
+ @configs.each do | key, value |
34
+ # puts "========= key: #{key}"
35
+ # if ExportOptions::Plist.exist?(key)
36
+ # puts "call #{key.to_s}(#{value})"
37
+ plist.send key.to_sym, value
38
+ # end
39
+ end
40
+ return plist
41
+ end
42
+
43
+ def export_path
44
+ File.join(Dir.pwd, "#{self.scheme}")
45
+ if self.output_name
46
+ return File.join(Dir.pwd, "#{self.output_name}")
47
+ end
48
+ end
49
+
50
+ def to_s
51
+ Table.new(@configs).table
52
+ end
53
+
54
+ private
55
+
56
+ def get_team_identifier
57
+ mobileprovision = File.join(File.expand_path("#{scheme}.xcarchive", Workspace::TMP_DIR), "Products/Applications/#{scheme}.app/embedded.mobileprovision")
58
+ return unless File.exist?(mobileprovision)
59
+ # puts "mobileprovision: #{mobileprovision}"
60
+ team_id = XcodeTool::Mobileprovision.new(mobileprovision).team_identifier
61
+ if team_id != ""
62
+ @configs = {teamID: team_id.chomp}
63
+ end
64
+ end
65
+
66
+ def add_configuration(key, value)
67
+ key = key.sub(/_\w/) { |e| e.delete('_').upcase } if key.index('_')
68
+ key = key.gsub(/id|Id/, 'ID') if key =~ /id|Id/
69
+ @configs[key.to_sym] = value
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ module ExportOptions
4
+ class Plist
5
+ ALL_KEYS = %w(compileBitcode method signingStyle teamID thinning)
6
+
7
+ # The ExportOptions plist file
8
+ attr_reader :export_options_plist_file
9
+
10
+ def initialize(name)
11
+ @export_options_plist_file = File.join(Workspace::TMP_DIR, "#{name.to_s.capitalize}-ExportOptions.plist")
12
+
13
+ Dir.mkdir(Workspace::TMP_DIR) unless Dir.exist?(Workspace::TMP_DIR)
14
+ File.open(@export_options_plist_file, 'w') do |f|
15
+ f.write <<-"..."
16
+ <?xml version="1.0" encoding="UTF-8"?>
17
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
18
+ <plist version="1.0">
19
+ <dict>
20
+ <key>compileBitcode</key>
21
+ <true/>
22
+ <key>method</key>
23
+ <string>ad-hoc</string>
24
+ <key>signingStyle</key>
25
+ <string>automatic</string>
26
+ <key>stripSwiftSymbols</key>
27
+ <true/>
28
+ <key>thinning</key>
29
+ <string>&lt;none&gt;</string>
30
+ </dict>
31
+ </plist>
32
+ ...
33
+ end
34
+ end
35
+
36
+ instance_methods.each do |m|
37
+ undef_method m unless m.to_s =~ /^__|send|method_missing|export_options_plist_file|object_id|response_to?/
38
+ end
39
+
40
+ def self.exist?(name)
41
+ ALL_KEYS.include?(name.to_s)
42
+ # puts ALL_KEYS.include?(name.to_s)
43
+ end
44
+
45
+ def method_missing(m, *args)
46
+ # puts "Plist call #{m.to_s}(#{args.join(',')})"
47
+ return unless ALL_KEYS.include? m.to_s
48
+
49
+ plist_buddy = XcodeTool::PlistBuddy.new(@export_options_plist_file)
50
+ plist_buddy.send m.to_sym, args.join(', ')
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ module Workspace
4
+ TMP_DIR = File.join(Dir.pwd, '.Tmp')
5
+
6
+ # The bean file where your actin defined.
7
+ # Default is /your/project/root/Beanfile.
8
+ BEAN_FILE = File.join(Dir.pwd, 'Beanfile')
9
+
10
+ module_function
11
+
12
+ def bean?
13
+ File.exist?(Workspace::BEAN_FILE)
14
+ end
15
+
16
+ def clear
17
+ `rm -rf #{TMP_DIR}` if Dir.exist?(TMP_DIR)
18
+ # Dir.delete(TMP_DIR) if Dir.exist?(TMP_DIR)
19
+ end
20
+
21
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ require_relative 'colored'
4
+
5
+ # include Action
6
+
7
+ module Bean
8
+ class Runner
9
+ def exec(name)
10
+ bean_file = Workspace::BEAN_FILE
11
+ puts "Beanfile: #{bean_file}"
12
+
13
+ unless Workspace.bean?
14
+ puts "BeanFile does not exist.".red
15
+ return
16
+ end
17
+
18
+ Action::BeanAction.new(bean_file).run(name)
19
+ end
20
+ end
21
+ end
22
+
data/lib/bean/table.rb ADDED
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/ruby -W
2
+ # encoding: utf-8
3
+
4
+ class Table
5
+
6
+ def initialize(map)
7
+ @map = map
8
+ @left_dash = 10
9
+ @right_dash = 20
10
+ end
11
+
12
+ def table
13
+ r = header
14
+ for (key, value) in @map
15
+ left = @left_dash - key.to_s.length
16
+ right = @right_dash - value.to_s.length
17
+ r << "| #{key}#{indent(left)} | #{value}#{indent(right)} |\n"
18
+ end
19
+ r << line
20
+ end
21
+
22
+ private
23
+
24
+ def header
25
+ max
26
+ left = @left_dash - 3
27
+ right = @right_dash - 5
28
+
29
+ r = line
30
+ r << "| Key#{indent(left)} | Value#{indent(right)} |\n"
31
+ r << line
32
+ end
33
+
34
+ def max()
35
+ keys = @map.keys.flat_map { |e| e.to_s.length }
36
+ values = @map.values.flat_map { |e| e.to_s.length }
37
+
38
+ @left_dash = find_largest(keys, @left_dash)
39
+ @right_dash = find_largest(values, @right_dash)
40
+ end
41
+
42
+ def find_largest(arr, target)
43
+ largest = target
44
+ for item in arr
45
+ if item > largest
46
+ largest = item
47
+ end
48
+ end
49
+ largest
50
+ end
51
+
52
+ def indent(n)
53
+ " " * n if n > 0
54
+ end
55
+
56
+ def line
57
+ "+" + "-" * (@left_dash + @right_dash + 5) + "+\n"
58
+ end
59
+ end
60
+
61
+
@@ -0,0 +1,126 @@
1
+ #!/usr/bin/env ruby -W
2
+ # encoding: utf-8
3
+
4
+ module XcodeTool
5
+ class PlistBuddy
6
+ def initialize(file)
7
+ @plist_file = file
8
+ end
9
+
10
+ instance_methods.each do |m|
11
+ undef_method m unless m.to_s =~ /^__|send|method_missing|object_id|response_to?/
12
+ end
13
+
14
+ def method_missing(m, *args)
15
+ # puts "PlistBuddy call #{m.to_s}, args: #{args}"
16
+ # return unless m.to_s.include?('=')
17
+
18
+ key = m.to_s
19
+ format_plist(key, args)
20
+ end
21
+
22
+ def exit?(key)
23
+ system "/usr/libexec/PlistBuddy -c 'Print :#{key}' #{@plist_file} > /dev/null 2>&1"
24
+ end
25
+
26
+ private
27
+
28
+ # Format the PlistBuddy commad.
29
+ # Set <Entry> <Value> - Sets the value at Entry to Value
30
+ # Add <Entry> <Type> [<Value>] - Adds Entry to the plist, with value Value
31
+ def format_plist(key, *args)
32
+ # Example:
33
+ # team_id => teamID
34
+
35
+ # Replace the `_` with upcase letter.
36
+ key = key.sub(/_\w/) { |e| e.delete('_').upcase } if key.index('_')
37
+
38
+ # If key contain `id` or `Id`, replace it with `ID`
39
+ key = key.gsub(/id|Id/, 'ID') if key =~ /id|Id/
40
+
41
+ puts "#{key} #{args}"
42
+
43
+ _args = args.join().split(", ")
44
+ key = key.delete('=') if key.index('=')
45
+ name = exit?(key) ? 'Set' : 'Add'
46
+ # type = _args.length > 1 ? _args[1] : 'string'
47
+ case _args.first
48
+ when String
49
+ type = 'string'
50
+ when Numeric
51
+ type = 'integer'
52
+ when Array
53
+ type = 'array'
54
+ when Hash
55
+ type = 'dict'
56
+ when TrueClass
57
+ type = 'bool'
58
+ when FalseClass
59
+ type = 'bool'
60
+ else
61
+ type = 'string'
62
+ end
63
+ command(name, key, _args.first, type)
64
+ end
65
+
66
+ # execute the PlistBuddy command.
67
+ # Set <Entry> <Value> - Sets the value at Entry to Value
68
+ # Add <Entry> <Type> [<Value>] - Adds Entry to the plist, with value Value
69
+ #
70
+ # Types:
71
+ # string
72
+ # array
73
+ # dict
74
+ # bool
75
+ # real
76
+ # integer
77
+ # date
78
+ # data
79
+ #
80
+ # Examples:
81
+ # Set :CFBundleIdentifier com.apple.plistbuddy
82
+ # Sets the CFBundleIdentifier property to com.apple.plistbuddy
83
+ # Add :CFBundleGetInfoString string "App version 1.0.1"
84
+ # Adds the CFBundleGetInfoString property to the plist
85
+ # Add :CFBundleDocumentTypes: dict
86
+ # Adds a new item of type dict to the CFBundleDocumentTypes array
87
+ # Add :CFBundleDocumentTypes:0 dict
88
+ # Adds the new item to the beginning of the array
89
+ #
90
+ def command(name, key, value, type)
91
+ return unless %w(Add Set).include?(name)
92
+ type = name == 'Add' ? " #{type}" : ''
93
+ # cmd = "/usr/libexec/PlistBuddy -c '#{name} :#{key}#{type} #{value}' #{@plist_file}"
94
+ # puts cmd.red
95
+ system "/usr/libexec/PlistBuddy -c '#{name} :#{key}#{type} #{value}' #{@plist_file}"
96
+ end
97
+
98
+ end
99
+
100
+ class Mobileprovision
101
+ def initialize(file)
102
+ @mobileprovision_file = file
103
+ end
104
+
105
+ def method_missing(m, *args)
106
+ return if m.to_s =~ /=$/
107
+ key = m.to_s.split(/_/).map { |e| e.capitalize }.join('')
108
+ value_from_plist(key)
109
+ end
110
+
111
+ def info
112
+ system "security cms -D -i #{@mobileprovision_file}"
113
+ end
114
+
115
+ def team_identifier
116
+ value_from_plist('Entitlements:com.apple.developer.team-identifier')
117
+ end
118
+
119
+ # Get value form Mobileprovision file.
120
+ def value_from_plist(key)
121
+ `/usr/libexec/PlistBuddy -c 'Print :#{key}' /dev/stdin <<< $(security cms -D -i #{@mobileprovision_file})`
122
+ end
123
+
124
+ end
125
+ end
126
+
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ require_relative 'colored'
4
+
5
+ module XcodeBuilder
6
+ class Archiver
7
+ def self.archive(config)
8
+ puts config
9
+ workspace = config.workspace
10
+ scheme = config.scheme
11
+ export_path = config.export_path
12
+ tmp_dir = Workspace::TMP_DIR
13
+ Dir.mkdir(tmp_dir) unless Dir.exist?(tmp_dir)
14
+
15
+ # The archivePath is /your/project/root/.Tmp/scheme.xcarchive
16
+
17
+ archive_path = File.expand_path("#{scheme}.xcarchive", tmp_dir)
18
+ archive_command = "xcodebuild -workspace #{workspace} -scheme #{scheme} clean archive -archivePath #{archive_path}"
19
+ # puts archive_command.red
20
+ export_option_plist = config.export_options_plist.export_options_plist_file
21
+ export_command = "xcodebuild -exportArchive -archivePath #{archive_path} -exportPath #{export_path} -exportOptionsPlist #{export_option_plist}"
22
+ # puts export_command.red
23
+
24
+ system archive_command
25
+ system export_command
26
+
27
+ Workspace.clear
28
+ end
29
+
30
+ end
31
+ end
data/lib/test.rb ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ require_relative 'bean'
4
+
5
+ # plist = ExportOptions::Plist.new
6
+ # plist.team_id = 'TeamIDDDD'
7
+ # plist.user_id = 'user', 'string'
8
+ # plist.compile_bitcode = 'true', 'bool'
9
+
10
+ # path = "/Users/huluobo/Developer/xiaoDian/Example/xiaoDian-Example.xcarchive/Products/Applications/xiaoDian_Example.app/embedded.mobileprovision"
11
+ # m = XcodeTool::Mobileprovision.new(path)
12
+ # puts m.team_identifier
13
+ # m.team_name
14
+ # m.info
15
+ # # m.value_from_plist('com.apple.developer.team-identifier')
16
+ # m.value_from_plist('Entitlements:com.apple.developer.team-identifier')
17
+
18
+
19
+ # Workspace.bean?
20
+ # Workspace.clear
21
+
22
+ # config = Workspace::Config.new('dev')
23
+ # config.workspace = 'Demo-workspace'
24
+ # config.scheme = 'Demo-scheme'
25
+ # config.compile_bitcode = true
26
+ # config.team_id = 'DHF3334HH'
27
+ # puts config
28
+
29
+ Bean::Runner.new.exec('dev')
data/lib/xbean.rb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby -W
2
+
3
+ require_relative 'bean/project'
4
+ require_relative 'bean/table'
5
+ require_relative 'bean/xcode_tool'
6
+ require_relative 'bean/export_options_plist'
7
+ require_relative 'bean/config'
8
+ require_relative 'bean/xcodebuild'
9
+ require_relative 'bean/action'
10
+ require_relative 'bean/runner'
11
+
12
+
13
+
14
+
data/xbean.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'xbean'
3
+ s.version = '0.0.1'
4
+ s.date = '2018-07-16'
5
+ s.summary = "Archiver for iOS."
6
+ s.description = "An Arciver tool for iOS."
7
+ s.authors = ["jewelz"]
8
+ s.email = 'hujewelz@163.com'
9
+ s.files = `git ls-files -z`.split("\x0").reject do |f|
10
+ f.match(%r{^(test|bin)})
11
+ end
12
+ s.executables << 'xbean'
13
+ s.homepage =
14
+ 'https://github.com/hujewelz/bean.git'
15
+ s.license = 'MIT'
16
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xbean
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - jewelz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-07-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: An Arciver tool for iOS.
14
+ email: hujewelz@163.com
15
+ executables:
16
+ - xbean
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - bin/xbean
22
+ - lib/bean/action.rb
23
+ - lib/bean/colored.rb
24
+ - lib/bean/config.rb
25
+ - lib/bean/export_options_plist.rb
26
+ - lib/bean/project.rb
27
+ - lib/bean/runner.rb
28
+ - lib/bean/table.rb
29
+ - lib/bean/xcode_tool.rb
30
+ - lib/bean/xcodebuild.rb
31
+ - lib/test.rb
32
+ - lib/xbean.rb
33
+ - xbean.gemspec
34
+ homepage: https://github.com/hujewelz/bean.git
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.5.2
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: Archiver for iOS.
58
+ test_files: []