umbrellify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f55f86b5b1597988ecca1f8c5b89b54565c2a9ac6355f47ea6db9edf5b7aa704
4
+ data.tar.gz: c9af5475f9d35679c0a64e5b51422bf128c67b9cc62e25549b90570f554e1604
5
+ SHA512:
6
+ metadata.gz: 1da8d184478c21df717721568723144386c2174bdbc219b88e50f025f39a5ddd379efe34aada536ee92db3f9090db40ec7aabdfa781d34085102022a04b95392
7
+ data.tar.gz: ae2006f56b4e640dc64216135d1110aa50fd7367386f1e83197dc7cac1c22f87ed325884aeafc027cc969c4c3aa87b9c72ae0b4e6c2145e3d49eead457cd4c0b
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'umbrellify'
4
+
5
+ config_default_name = 'Umbrellifile'
6
+ working_directory = Dir.pwd
7
+
8
+ # Parse Umbrellifile in current directory
9
+ config_path = "#{working_directory}/#{config_default_name}"
10
+ abort "Could not find Umbrellifile in current directory!" unless File.exists? config_path
11
+ configuration = Umbrellify::Configuration.new(config_path)
12
+
13
+ # Find xcodeproj file
14
+ project_path = configuration.project_path
15
+ abort "Could not find Xcode project file!" unless File.exists? project_path
16
+
17
+ # Find path for source code operations
18
+ source_path = ARGV[0] || configuration.source_path || working_directory
19
+
20
+ # Perform actions
21
+ puts "Performing modifications to source code..."
22
+ imports_manager = Umbrellify::ImportsManager.new(configuration)
23
+ imports_manager.process_directory("#{source_path}/**/*.swift")
24
+
25
+ puts "Performing modifications to Xcode project..."
26
+ project_manager = Umbrellify::ProjectManager.new(project_path, configuration)
27
+ project_manager.apply
28
+
29
+ puts "Done successfully!"
@@ -0,0 +1,5 @@
1
+ module Umbrellify
2
+ require "umbrellify/configuration"
3
+ require "umbrellify/managers/imports_manager"
4
+ require "umbrellify/managers/project_manager"
5
+ end
@@ -0,0 +1,42 @@
1
+ require "yaml"
2
+
3
+ module Umbrellify
4
+ class Configuration
5
+ def initialize(config_path)
6
+ configuration = YAML.load_file(config_path)
7
+
8
+ @umbrella_name = configuration["umbrella_target_name"]
9
+ @main_target_name = configuration["main_target_name"]
10
+ @managed_imports = configuration["managed_targets"]
11
+ @project_path = configuration["project_path"]
12
+ @source_path = configuration["source_path"]
13
+ @substitute_managed_imports_only = configuration["substitute_managed_imports_only"]
14
+ end
15
+
16
+ # Getters
17
+
18
+ def umbrella_name
19
+ @umbrella_name
20
+ end
21
+
22
+ def main_target_name
23
+ @main_target_name
24
+ end
25
+
26
+ def managed_imports
27
+ @managed_imports
28
+ end
29
+
30
+ def project_path
31
+ @project_path
32
+ end
33
+
34
+ def source_path
35
+ @source_path
36
+ end
37
+
38
+ def substitute_managed_imports_only
39
+ @substitute_managed_imports_only
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ require "umbrellify/configuration"
2
+ require "umbrellify/models/swift_source_file"
3
+
4
+ module Umbrellify
5
+ class ImportsManager
6
+ def initialize(configuration)
7
+ @configuration = configuration
8
+ end
9
+
10
+ def process_directory(source_path)
11
+ files = Dir[source_path]
12
+ files.each do |file|
13
+ source_file = SwiftSourceFile.new(file)
14
+ source_file.substitute_imports_if_needed!(@configuration)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,136 @@
1
+ require "xcodeproj"
2
+
3
+ module Umbrellify
4
+ class ProjectManager
5
+ def initialize(project_path, configuration)
6
+ @project_path = project_path
7
+ @configuration = configuration
8
+ end
9
+
10
+ # =-=-=-=-=-=-=-=-=-=-=-=- Public Interface =-=-=-=-=-=-=-=-=-=-=-=-
11
+
12
+ def apply
13
+ open_project
14
+
15
+ umbrella_target = add_umbrella_target_if_needed
16
+ umbrella_files_path = create_umbrella_files
17
+ add_umbrella_files_to_target(umbrella_files_path, umbrella_target)
18
+ add_dependency_to_main_target(umbrella_target)
19
+
20
+ @project.save
21
+ end
22
+
23
+ # =-=-=-=-=-=-=-=-=-=-=-=- Private =-=-=-=-=-=-=-=-=-=-=-=-
24
+
25
+ def open_project
26
+ @project = Xcodeproj::Project.open(@project_path)
27
+ end
28
+
29
+ private :open_project
30
+
31
+ def add_umbrella_target_if_needed
32
+ existing_umbrella_targets = @project.targets.select { |t| t.name == umbrella_name }
33
+
34
+ umbrella_target = existing_umbrella_targets.first
35
+
36
+ if umbrella_target.nil?
37
+ umbrella_target = @project.new_target(:framework, umbrella_name, :ios, "10.0")
38
+ @project.save
39
+ end
40
+
41
+ return umbrella_target
42
+ end
43
+
44
+ private :add_umbrella_target_if_needed
45
+
46
+ def create_umbrella_files
47
+ project_dir_path = File.dirname(@project_path)
48
+ work_path = "#{project_dir_path}/#{umbrella_name}"
49
+
50
+ umbrella_source_path = "#{work_path}/#{umbrella_name}-combined.swift"
51
+
52
+ Dir.mkdir(work_path) unless Dir.exist?(work_path)
53
+ File.write(umbrella_source_path, umbrella_source(@configuration.managed_imports))
54
+
55
+ return work_path
56
+ end
57
+
58
+ private :create_umbrella_files
59
+
60
+ def add_umbrella_files_to_target(path, target)
61
+ work_group = @project.main_group
62
+
63
+ work_group.children.select { |child| child.name == umbrella_name }.each do |child|
64
+ remove_files(child)
65
+ end
66
+
67
+ add_files(path, work_group, target)
68
+ end
69
+
70
+ private :add_umbrella_files_to_target
71
+
72
+ def add_dependency_to_main_target(target)
73
+ main_target.add_dependency(target)
74
+ end
75
+
76
+ private :add_dependency_to_main_target
77
+
78
+ # =-=-=-=-=-=-=-=-=-=-=-=- Helpers =-=-=-=-=-=-=-=-=-=-=-=-
79
+
80
+ def umbrella_name
81
+ @configuration.umbrella_name
82
+ end
83
+
84
+ private :umbrella_name
85
+
86
+ def main_target
87
+ @project.targets.select { |t|
88
+ t.name == @configuration.main_target_name
89
+ }.first
90
+ end
91
+
92
+ private :main_target
93
+
94
+ def umbrella_source(managed_frameworks)
95
+ exported_imports = managed_frameworks.map { |f| "@_exported import #{f}" }.join("\n")
96
+
97
+ source = <<SOURCE
98
+ // This file is generated automatically by Umbrellify.
99
+ // Do not edit contents of this file!
100
+
101
+ #{exported_imports}
102
+ SOURCE
103
+ end
104
+
105
+ private :umbrella_source
106
+
107
+ def add_files(directory, group, target)
108
+ Dir.glob(directory) do |item|
109
+ next if item == "." or item == ".DS_Store"
110
+
111
+ if File.directory?(item)
112
+ new_folder = File.basename(item)
113
+ created_group = group.new_group(new_folder)
114
+ add_files("#{item}/*", created_group, target)
115
+ else
116
+ file_reference = group.new_file(item)
117
+ target.add_file_references([file_reference])
118
+ end
119
+ end
120
+ end
121
+
122
+ private :add_files
123
+
124
+ def remove_files(object)
125
+ if object.isa == "PBXGroup"
126
+ object.children.each do |child|
127
+ remove_files(child)
128
+ end
129
+ end
130
+
131
+ object.remove_from_project
132
+ end
133
+
134
+ private :remove_files
135
+ end
136
+ end
@@ -0,0 +1,77 @@
1
+ module Umbrellify
2
+ class SwiftSourceFile
3
+ def initialize(file_path)
4
+ @file_path = file_path
5
+ end
6
+
7
+ def get_file_text
8
+ File.readlines(@file_path).join
9
+ end
10
+
11
+ private :get_file_text
12
+
13
+ def strip_comments(file_text)
14
+ comment_types = [
15
+ /\/\/.*$/, # one-line
16
+ /\/\*.*\*\//m, # multiline
17
+ ]
18
+
19
+ result = file_text
20
+ comment_types.each do |regexp|
21
+ result = result.gsub regexp, ""
22
+ end
23
+ result
24
+ end
25
+
26
+ private :strip_comments
27
+
28
+ def imports_list(file_text)
29
+ import_search_regexp = /^import\s*(\w*).*$/
30
+ file_text.scan(import_search_regexp).flatten
31
+ end
32
+
33
+ private :imports_list
34
+
35
+ def needs_to_substitute_imports?(imports, managed_imports, configuration)
36
+ return true unless configuration.substitute_managed_imports_only
37
+ return true if imports.include? configuration.umbrella_name
38
+
39
+ (managed_imports - imports).empty?
40
+ end
41
+
42
+ private :needs_to_substitute_imports?
43
+
44
+ def override_file!(file_text)
45
+ File.write(@file_path, file_text)
46
+ end
47
+
48
+ private :override_file!
49
+
50
+ def substitute_imports_if_needed(configuration)
51
+ umbrella_name = configuration.umbrella_name
52
+ file_text = get_file_text()
53
+ imports = imports_list(strip_comments(file_text))
54
+ managed_imports = configuration.managed_imports
55
+
56
+ if needs_to_substitute_imports?(imports, managed_imports, configuration)
57
+ managed_imports_copy = managed_imports + [umbrella_name]
58
+ umbrella_import = "import #{umbrella_name}"
59
+
60
+ imports_list = imports.select { |value| managed_imports.include?(value) }
61
+
62
+ imports_list.each_with_index do |value, index|
63
+ regexp = /^import\s{1,}\b#{value}\b[^\n]*\n/
64
+ substitution = index == imports_list.count - 1 ? "#{umbrella_import}\n" : ""
65
+
66
+ file_text = file_text.gsub regexp, substitution
67
+ end
68
+ end
69
+
70
+ return file_text
71
+ end
72
+
73
+ def substitute_imports_if_needed!(configuration)
74
+ override_file! substitute_imports_if_needed(configuration)
75
+ end
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: umbrellify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vitaliy Salnikov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-03-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xcodeproj
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ description: Umbrellify is a tool that combines frameworks into an alias. It uses
28
+ [@_exported] annotation to provide a single import declaration, which exports multiple
29
+ other imports. The only supported language is Swift.
30
+ email: mrtokii@outlook.com
31
+ executables:
32
+ - umbrellify
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - bin/umbrellify
37
+ - lib/umbrellify.rb
38
+ - lib/umbrellify/configuration.rb
39
+ - lib/umbrellify/managers/imports_manager.rb
40
+ - lib/umbrellify/managers/project_manager.rb
41
+ - lib/umbrellify/models/swift_source_file.rb
42
+ homepage: https://github.com/mrtokii/umbrellify
43
+ licenses:
44
+ - MIT
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.0.1
62
+ signing_key:
63
+ specification_version: 4
64
+ summary: Create alias for multiple Swift frameworks
65
+ test_files: []