pod-builder 0.1.8.beta → 0.2.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.
@@ -46,14 +46,14 @@ module PodBuilder
46
46
  end
47
47
 
48
48
  Dir.chdir(repo_dir)
49
- puts "Checking out #{spec.podspec_name}".blue
49
+ puts "Checking out #{spec.podspec_name}".yellow
50
50
  raise "Failed cheking out #{spec.name}" if !system(spec.git_hard_checkout)
51
51
 
52
52
  Dir.chdir(current_dir)
53
53
  end
54
54
 
55
55
  def self.rewrite_lldinit
56
- puts "Writing ~/.lldbinit-Xcode".blue
56
+ puts "Writing ~/.lldbinit-Xcode".yellow
57
57
 
58
58
  lldbinit_path = File.expand_path('~/.lldbinit-Xcode')
59
59
  FileUtils.touch(lldbinit_path)
@@ -0,0 +1,165 @@
1
+ require 'pod_builder/core'
2
+
3
+ module PodBuilder
4
+ module Command
5
+ class Switch
6
+ def self.call(options)
7
+ Configuration.check_inited
8
+ PodBuilder::prepare_basepath
9
+
10
+ argument_pods = ARGV.dup
11
+
12
+ unless argument_pods.count > 0
13
+ return false
14
+ end
15
+ unless argument_pods.count == 1
16
+ raise "\n\nSpecify a single pod to switch\n\n".red
17
+ return false
18
+ end
19
+
20
+ pod_name_to_switch = argument_pods.first
21
+
22
+ check_not_building_subspec(pod_name_to_switch)
23
+
24
+ installer, analyzer = Analyze.installer_at(PodBuilder::basepath, false)
25
+ all_buildable_items = Analyze.podfile_items(installer, analyzer)
26
+
27
+ raise "\n\nPod `#{pod_name_to_switch}` wasn't found in Podfile" unless all_buildable_items.map(&:root_name).include?(pod_name_to_switch)
28
+
29
+ unless options.has_key?(:switch_mode)
30
+ podfile_item = all_buildable_items.detect { |x| x.root_name == pod_name_to_switch }
31
+ options[:switch_mode] = request_switch_mode(pod_name_to_switch, podfile_item)
32
+
33
+ if options[:switch_mode].nil?
34
+ return true
35
+ end
36
+ end
37
+
38
+ if options[:switch_mode] == "prebuilt"
39
+ check_prebuilded(pod_name_to_switch)
40
+ end
41
+
42
+ podfile_path = PodBuilder::project_path("Podfile")
43
+ podfile_content = File.read(podfile_path)
44
+
45
+ pod_lines = []
46
+ podfile_content.each_line do |line|
47
+ if pod_name = Podfile.pod_definition_in(line, false)
48
+ if pod_name.start_with?("PodBuilder/")
49
+ pod_name = pod_name.split("PodBuilder/").last.gsub("_", "/")
50
+ end
51
+
52
+ unless pod_name.split("/").first == pod_name_to_switch
53
+ pod_lines.push(line)
54
+ next
55
+ end
56
+
57
+ if pod_name.include?("/")
58
+ podfile_items = all_buildable_items.select { |x| x.name == pod_name }
59
+ else
60
+ podfile_items = all_buildable_items.select { |x| x.root_name == pod_name }
61
+ end
62
+
63
+ unless podfile_items.count > 0
64
+ raise "\n\nPod `#{pod_name_to_switch}` wasn't found in Podfile\n".red
65
+ end
66
+
67
+ matches = line.match(/(#\s*pb<)(.*?)(>)/)
68
+ if matches&.size == 4
69
+ default_pod_name = matches[2]
70
+ else
71
+ puts "⚠️ Did not found pb<> entry, assigning default pod name #{pod_name}"
72
+ default_pod_name = pod_name
73
+ end
74
+
75
+ unless podfile_item = all_buildable_items.detect { |x| x.name == default_pod_name }
76
+ raise "\n\nPod `#{default_pod_name}` wasn't found in Podfile\n".red
77
+ end
78
+ podfile_item = podfile_item.dup
79
+
80
+ indentation = line.detect_indentation
81
+
82
+ case options[:switch_mode]
83
+ when "prebuilt"
84
+ line = indentation + podfile_item.prebuilt_entry + "\n"
85
+ when "development"
86
+ podfile_item.path = find_podspec(podfile_item)
87
+
88
+ line = indentation + podfile_item.entry + "\n"
89
+ when "default"
90
+ line = indentation + podfile_item.entry + "\n"
91
+ else
92
+ break
93
+ end
94
+ end
95
+
96
+ pod_lines.push(line)
97
+ end
98
+
99
+ File.write(podfile_path, pod_lines.join)
100
+
101
+ Dir.chdir(PodBuilder::project_path)
102
+ system("pod install")
103
+ end
104
+
105
+ private
106
+
107
+ def self.find_podspec(podfile_item)
108
+ unless Configuration.development_pods_paths.count > 0
109
+ raise "\n\nPlease add the `development_pods_paths` in #{Configuration.dev_pods_configuration_filename} as per documentation\n".red
110
+ end
111
+
112
+ podspec_path = nil
113
+ Configuration.development_pods_paths.each do |path|
114
+ podspec = Dir.glob(File.expand_path("#{path}/**/#{podfile_item.root_name}*.podspec*"))
115
+ podspec.select! { |x| !x.include?("/Local Podspecs/") }
116
+ if podspec.count > 0
117
+ podspec_path = Pathname.new(podspec.first).dirname.to_s
118
+ break
119
+ end
120
+ end
121
+
122
+ if podspec_path.nil?
123
+ raise "\n\nCouln't find `#{pod_name}` sources in the following specified development pod paths: #{Configuration.development_pods_paths.join("\n")}\n".red
124
+ end
125
+
126
+ return podspec_path
127
+ end
128
+
129
+ def self.request_switch_mode(pod_name, podfile_item)
130
+ matches = podfile_item.entry.match(/(pod '.*?',)(.*)/)
131
+ unless matches&.size == 3
132
+ raise "\n\nFailed matching pod name\n".red
133
+ end
134
+
135
+ default_entry = matches[2].strip
136
+
137
+ modes = ["prebuilt", "development", "default"]
138
+ mode_indx = ask("\n\nSwitch #{pod_name} to:\n1) Prebuilt\n2) Development pod\n3) Default (#{default_entry})\n\n") { |x| x.limit = 1, x.validate = /[1-3]/ }
139
+
140
+ return modes[mode_indx.to_i - 1]
141
+ end
142
+
143
+ def self.check_not_building_subspec(pod_to_switch)
144
+ if pod_to_switch.include?("/")
145
+ raise "\n\nCan't switch subspec #{pod_to_switch} refer to podspec name.\n\nUse `pod_builder switch #{pod_to_switch.split("/").first}` instead\n\n".red
146
+ end
147
+ end
148
+
149
+ private
150
+
151
+ def self.check_prebuilded(pod_name)
152
+ podspec_path = PodBuilder::basepath("PodBuilder.podspec")
153
+ unless File.exist?(podspec_path)
154
+ raise "Prebuilt podspec not found!".red
155
+ end
156
+
157
+ prebuilt_podspec = File.read(podspec_path)
158
+
159
+ if !prebuilt_podspec.include?("s.subspec '#{pod_name}' do |p|")
160
+ raise "\n\n#{pod_name} is not prebuilt.\n\nRun 'pod_builder build #{pod_name}'\n".red
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,30 @@
1
+ require 'pod_builder/core'
2
+
3
+ module PodBuilder
4
+ module Command
5
+ class SynchPodfile
6
+ def self.call(options)
7
+ Configuration.check_inited
8
+ PodBuilder::prepare_basepath
9
+
10
+ update_repo = options[:update_repos] || false
11
+ installer, analyzer = Analyze.installer_at(PodBuilder::basepath, update_repo)
12
+
13
+ all_buildable_items = Analyze.podfile_items(installer, analyzer)
14
+
15
+ Dir.chdir(PodBuilder::project_path)
16
+
17
+ previous_podfile_content = File.read("Podfile")
18
+ Podfile::write_prebuilt(all_buildable_items, analyzer)
19
+ updated_podfile_content = File.read("Podfile")
20
+
21
+ if previous_podfile_content != updated_podfile_content
22
+ system("pod install")
23
+ end
24
+
25
+ return true
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -1,96 +1,178 @@
1
1
  require 'json'
2
2
 
3
3
  module PodBuilder
4
- class Configuration
5
- class <<self
4
+ class Configuration
5
+ # Remember to update README.md accordingly
6
+ DEFAULT_BUILD_SETTINGS = {
7
+ "ENABLE_BITCODE" => "NO",
8
+ "GCC_OPTIMIZATION_LEVEL" => "s",
9
+ "SWIFT_OPTIMIZATION_LEVEL" => "-Osize",
10
+ "SWIFT_COMPILATION_MODE" => "singlefile",
11
+ }.freeze
12
+ DEFAULT_SPEC_OVERRIDE = {
13
+ "Google-Mobile-Ads-SDK" => {
14
+ "module_name": "GoogleMobileAds"
15
+ }
16
+ }.freeze
17
+ DEFAULT_BUILD_SYSTEM = "Legacy".freeze # either Latest (New build system) or Legacy (Standard build system)
18
+ MIN_LFS_SIZE_KB = 256.freeze
19
+
20
+ private_constant :DEFAULT_BUILD_SETTINGS
21
+ private_constant :DEFAULT_BUILD_SYSTEM
22
+ private_constant :MIN_LFS_SIZE_KB
23
+
24
+ class <<self
6
25
  attr_accessor :build_settings
7
26
  attr_accessor :build_settings_overrides
8
27
  attr_accessor :build_system
9
- attr_accessor :config_file
10
28
  attr_accessor :base_path
11
- attr_accessor :build_path
12
29
  attr_accessor :spec_overrides
13
30
  attr_accessor :skip_licenses
14
- attr_accessor :license_file_name
31
+ attr_accessor :skip_pods
32
+ attr_accessor :license_filename
33
+ attr_accessor :subspecs_to_split
34
+ attr_accessor :development_pods_paths
35
+ attr_accessor :build_path
36
+ attr_accessor :configuration_filename
37
+ attr_accessor :dev_pods_configuration_filename
38
+ attr_accessor :lfs_min_file_size
39
+ attr_accessor :update_lfs_gitattributes
15
40
  end
16
-
17
- # Remember to update README.md
18
- @build_settings = {
19
- "ONLY_ACTIVE_ARCH" => "NO",
20
- "ENABLE_BITCODE" => "NO",
21
- "CLANG_ENABLE_MODULE_DEBUGGING" => "NO",
22
- "GCC_OPTIMIZATION_LEVEL" => "s",
23
- "SWIFT_OPTIMIZATION_LEVEL" => "-Osize",
24
- "SWIFT_COMPILATION_MODE" => "singlefile",
25
- }
41
+
42
+ @build_settings = DEFAULT_BUILD_SETTINGS
26
43
  @build_settings_overrides = {}
27
- @build_system = "Legacy" # either Latest (New build system) or Legacy (Standard build system)
28
- @config_file = "PodBuilder.json"
44
+ @build_system = DEFAULT_BUILD_SYSTEM
29
45
  @base_path = "Frameworks" # Not nice. This value is used only for initial initization. Once config is loaded it will be an absolute path. FIXME
30
- @build_path = "/tmp/pod_builder"
31
- @spec_overrides = {}
46
+ @spec_overrides = DEFAULT_SPEC_OVERRIDE
32
47
  @skip_licenses = []
33
- @license_file_name = "Pods-acknowledgements"
34
-
48
+ @skip_pods = []
49
+ @license_filename = "Pods-acknowledgements"
50
+ @subspecs_to_split = []
51
+ @development_pods_paths = []
52
+ @build_path = "/tmp/pod_builder".freeze
53
+ @configuration_filename = "PodBuilder.json".freeze
54
+ @dev_pods_configuration_filename = "PodBuilderDevPodsPaths.json".freeze
55
+ @lfs_min_file_size = MIN_LFS_SIZE_KB
56
+ @update_lfs_gitattributes = false
57
+
35
58
  def self.check_inited
36
- count = Dir.glob("#{PodBuilder::home}/**/.pod_builder").count
37
- raise "\n\nNot inited, run `pod_builder init`\n".red if count == 0
38
- raise "\n\nToo many .pod_builder found `#{count}`\n".red if count > 1
59
+ raise "\n\nNot inited, run `pod_builder init`\n".red if podbuilder_path.nil?
39
60
  end
40
61
 
41
62
  def self.exists
42
- return config_path ? File.exist?(config_path) : false
63
+ return !config_path.nil? && File.exist?(config_path)
43
64
  end
44
65
 
45
66
  def self.load
46
- unless config_path
67
+ unless podbuilder_path
47
68
  return
48
69
  end
49
-
50
- Configuration.base_path = File.dirname(config_path)
51
-
70
+
71
+ Configuration.base_path = podbuilder_path
72
+
52
73
  if exists
53
- config = JSON.parse(File.read(config_path))
54
- if config.has_key?("spec_overrides")
55
- Configuration.spec_overrides = config["spec_overrides"]
74
+ json = JSON.parse(File.read(config_path))
75
+ if value = json["spec_overrides"]
76
+ if value.is_a?(Hash) && value.keys.count > 0
77
+ Configuration.spec_overrides = value
78
+ end
79
+ end
80
+ if value = json["skip_licenses"]
81
+ if value.is_a?(Array) && value.count > 0
82
+ Configuration.skip_licenses = value
83
+ end
84
+ end
85
+ if value = json["skip_pods"]
86
+ if value.is_a?(Array) && value.count > 0
87
+ Configuration.skip_pods = value
88
+ end
89
+ end
90
+ if value = json["build_settings"]
91
+ if value.is_a?(Hash) && value.keys.count > 0
92
+ Configuration.build_settings = value
93
+ end
94
+ end
95
+ if value = json["build_settings_overrides"]
96
+ if value.is_a?(Hash) && value.keys.count > 0
97
+ Configuration.build_settings_overrides = value
98
+ end
56
99
  end
57
- if config.has_key?("skip_licenses")
58
- Configuration.skip_licenses = config["skip_licenses"]
100
+ if value = json["build_system"]
101
+ if value.is_a?(String) && ["Latest", "Legacy"].include?(value)
102
+ Configuration.build_system = value
103
+ end
59
104
  end
60
- if config.has_key?("build_settings")
61
- Configuration.build_settings = config["build_settings"]
105
+ if value = json["license_filename"]
106
+ if value.is_a?(String) && value.length > 0
107
+ Configuration.license_filename = value
108
+ end
62
109
  end
63
- if config.has_key?("build_settings_overrides")
64
- Configuration.build_settings_overrides = config["build_settings_overrides"]
110
+ if value = json["subspecs_to_split"]
111
+ if value.is_a?(Array) && value.count > 0
112
+ Configuration.subspecs_to_split = value
113
+ end
65
114
  end
66
- if config.has_key?("build_system")
67
- Configuration.build_system = config["build_system"]
115
+ if value = json["update_lfs_gitattributes"]
116
+ if [TrueClass, FalseClass].include?(value.class)
117
+ Configuration.update_lfs_gitattributes = value
118
+ end
68
119
  end
69
- if config.has_key?("license_file_name")
70
- Configuration.license_file_name = config["license_file_name"]
120
+ if value = json["lfs_min_file_size_kb"]
121
+ if value.is_a?(Integer)
122
+ if value > 50
123
+ Configuration.lfs_min_file_size = value
124
+ else
125
+ puts "\n\n⚠️ Skipping `lfs_min_file_size` value too small".yellow
126
+ end
127
+ end
71
128
  end
129
+
130
+ Configuration.build_settings.freeze
131
+ else
132
+ write
133
+ end
134
+
135
+ dev_pods_configuration_path = File.join(Configuration.base_path, Configuration.dev_pods_configuration_filename)
136
+
137
+ if File.exist?(dev_pods_configuration_path)
138
+ json = JSON.parse(File.read(dev_pods_configuration_path))
139
+ Configuration.development_pods_paths = json || []
140
+ Configuration.development_pods_paths.freeze
72
141
  end
73
142
  end
74
143
 
75
144
  def self.write
76
- config = {
77
- # nothing here yet
78
- }
79
- File.write(config_path, config.to_json)
145
+ config = {}
146
+
147
+ config["spec_overrides"] = Configuration.spec_overrides
148
+ config["skip_licenses"] = Configuration.skip_licenses
149
+ config["skip_pods"] = Configuration.skip_pods
150
+ config["build_settings"] = Configuration.build_settings
151
+ config["build_settings_overrides"] = Configuration.build_settings_overrides
152
+ config["build_system"] = Configuration.build_system
153
+ config["license_filename"] = Configuration.license_filename
154
+ config["subspecs_to_split"] = Configuration.subspecs_to_split
155
+ config["update_lfs_gitattributes"] = Configuration.update_lfs_gitattributes
156
+ config["lfs_min_file_size_kb"] = Configuration.lfs_min_file_size
157
+
158
+ File.write(config_path, JSON.pretty_generate(config))
80
159
  end
81
-
160
+
82
161
  private
83
-
162
+
84
163
  def self.config_path
85
- unless PodBuilder::xcodepath
86
- return
164
+ unless path = podbuilder_path
165
+ return nil
87
166
  end
88
-
89
- project_path = "#{PodBuilder::xcodepath}/#{base_path}/.pod_builder"
90
- config_path = Dir.glob("#{PodBuilder::home}/**/.pod_builder").first
91
167
 
92
- path = File.dirname(config_path || project_path)
93
- return File.join(path, config_file)
168
+ return File.join(path, Configuration.configuration_filename)
169
+ end
170
+
171
+ def self.podbuilder_path
172
+ paths = Dir.glob("#{PodBuilder::home}/**/.pod_builder")
173
+ raise "\n\nToo many .pod_builder found `#{paths.join("\n")}`\n".red if paths.count > 1
174
+
175
+ return paths.count > 0 ? File.dirname(paths.first) : nil
94
176
  end
95
177
  end
96
178
  end
@@ -9,6 +9,8 @@ require 'pod_builder/install'
9
9
  require 'pod_builder/configuration'
10
10
  require 'pod_builder/podspec'
11
11
 
12
+ require 'core_ext/string'
13
+
12
14
  module PodBuilder
13
15
  def self.safe_rm_rf(path)
14
16
  unless File.exist?(path)
@@ -30,45 +32,62 @@ module PodBuilder
30
32
  Dir.chdir(basepath)
31
33
  end
32
34
  end
33
-
34
- def self.home
35
- h = `git rev-parse --show-toplevel`.strip()
36
- raise "\n\nNo git repository found in current folder `#{Dir.pwd}`!\n".red if h.empty?
37
- return h
38
- end
39
35
 
40
36
  def self.basepath(child = "")
41
37
  return "#{Configuration.base_path}/#{child}".gsub("//", "/").gsub(/\/$/, '')
42
38
  end
43
39
 
44
- def self.xcodepath(child = "")
45
- project = PodBuilder::find_xcodeproject
40
+ def self.project_path(child = "")
41
+ project = PodBuilder::find_xcodeworkspace
46
42
 
47
43
  return project ? "#{File.dirname(project)}/#{child}".gsub("//", "/").gsub(/\/$/, '') : nil
48
44
  end
49
45
 
50
- def self.find_xcodeproject
51
- return Dir.glob("#{home}/**/*.xcodeproj").detect { |x| !x.include?("/Pods/") && !x.include?(basepath) }
46
+ def self.find_xcodeproj
47
+ project_name = File.basename(find_xcodeworkspace, ".*")
48
+
49
+ xcodeprojects = Dir.glob("#{home}/**/#{project_name}.xcodeproj").select { |x| !x.include?("/Pods/") && !x.include?("/Sources/") && !x.include?(basepath) }
50
+ raise "xcodeproj not found!".red if xcodeprojects.count == 0
51
+ raise "Found multiple xcodeproj:\n#{xcodeprojects.join("\n")}".red if xcodeprojects.count > 1
52
+
53
+ return xcodeprojects.first
52
54
  end
53
55
 
54
56
  def self.find_xcodeworkspace
55
- return Dir.glob("#{home}/**/*.xcworkspace").detect { |x| !x.include?("/Pods/") && !x.include?(basepath) }
57
+ xcworkspaces = Dir.glob("#{home}/**/*.xcworkspace").select { |x| !x.include?("/Pods/") && !x.include?("/Sources/") && !x.include?(basepath) && !x.include?(".xcodeproj/") }
58
+ raise "xcworkspace not found!".red if xcworkspaces.count == 0
59
+ raise "Found multiple xcworkspaces:\n#{xcworkspaces.join("\n")}".red if xcworkspaces.count > 1
60
+
61
+ return xcworkspaces.first
56
62
  end
57
63
 
58
64
  def self.prepare_basepath
59
- project = PodBuilder::find_xcodeproject
60
- if project
65
+ workspace_path = PodBuilder::find_xcodeworkspace
66
+ project_path = PodBuilder::find_xcodeproj
67
+ if workspace_path && project_path
61
68
  FileUtils.mkdir_p(basepath("Pods/Target Support Files"))
62
- FileUtils.cp_r(project, basepath)
69
+ FileUtils.cp_r(workspace_path, basepath)
70
+ FileUtils.cp_r(project_path, basepath)
63
71
  FileUtils.rm_f(basepath("Podfile.lock"))
64
72
  end
65
73
  end
66
74
 
67
75
  def self.clean_basepath
68
- project = PodBuilder::find_xcodeproject
69
- if project
70
- PodBuilder::safe_rm_rf(basepath(File.basename(project)))
71
- PodBuilder::safe_rm_rf(basepath("Pods"))
76
+ if path = PodBuilder::find_xcodeproj
77
+ PodBuilder::safe_rm_rf(basepath(File.basename(path)))
72
78
  end
79
+ if path = PodBuilder::find_xcodeworkspace
80
+ PodBuilder::safe_rm_rf(basepath(File.basename(path)))
81
+ end
82
+
83
+ PodBuilder::safe_rm_rf(basepath("Pods"))
84
+ end
85
+
86
+ private
87
+
88
+ def self.home
89
+ h = `git rev-parse --show-toplevel`.strip()
90
+ raise "\n\nNo git repository found in current folder `#{Dir.pwd}`!\n".red if h.empty?
91
+ return h
73
92
  end
74
93
  end