umbrellify 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 +7 -0
- data/bin/umbrellify +29 -0
- data/lib/umbrellify.rb +5 -0
- data/lib/umbrellify/configuration.rb +42 -0
- data/lib/umbrellify/managers/imports_manager.rb +18 -0
- data/lib/umbrellify/managers/project_manager.rb +136 -0
- data/lib/umbrellify/models/swift_source_file.rb +77 -0
- metadata +65 -0
checksums.yaml
ADDED
@@ -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
|
data/bin/umbrellify
ADDED
@@ -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!"
|
data/lib/umbrellify.rb
ADDED
@@ -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: []
|