xbean 0.0.1

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