Skip to content

Instantly share code, notes, and snippets.

@smileyborg
Last active June 26, 2017 11:10
Show Gist options
  • Save smileyborg/cda66d542f304b14d5e2 to your computer and use it in GitHub Desktop.
Save smileyborg/cda66d542f304b14d5e2 to your computer and use it in GitHub Desktop.
A script to convert textual imports to framework imports. Useful when converting static libraries to dynamic frameworks.
#!/usr/bin/env ruby
require 'set'
UMBRELLA_HEADER_PATH = ARGV[0] # The path to the umbrella header containing all the headers
SOURCE_ROOT_PATH = ARGV[1] # The path containing the source files to convert (will be recursively searched)
FRAMEWORK_NAME = File.basename(UMBRELLA_HEADER_PATH, ".*") # Assumes that the framework name is the same as the umbrella header filename (e.g. "MyFramework" for "MyFramework.h")
UMBRELLA_IMPORT_REGEX = /#import\s+<#{FRAMEWORK_NAME}\/.+\.h>/ # Matches "#import <FrameworkName/Header.h>"
FRAMEWORK_HEADER_REGEX = /(?<=<#{FRAMEWORK_NAME}\/).+\.h(?=>)/ # Matches "Header.h" in "<FrameworkName/Header.h>"
# Read all of the headers in the framework umbrella header into the umbrella_headers Set,
# which will look something like: { "HeaderOne.h", "HeaderTwo.h", "HeaderThree.h", ... }
umbrella_headers = Set.new()
File.readlines(UMBRELLA_HEADER_PATH).each do |line|
if UMBRELLA_IMPORT_REGEX.match(line)
header = FRAMEWORK_HEADER_REGEX.match(line)[0]
umbrella_headers.add(header)
end
end
HEADER_IMPORT_REGEX = /#import\s+".+\.h"/
HEADER_REGEX = /(?<=").+\.h(?=")/
# Recurse through the source root, and for each file, look at all the #import "..." lines, then
# extract out the header file name from that and check if that header is included in the
# umbrella_headers Set. If so, replace that header's textual import with a framework style import.
Dir.glob("#{SOURCE_ROOT_PATH}/**/*.{h,m}") do |source_file|
# Read the lines of this file, replacing any textual imports for headers in the umbrella header with framework imports
modified_lines = File.readlines(source_file).map do |line|
if HEADER_IMPORT_REGEX.match(line)
header = HEADER_REGEX.match(line)[0]
if umbrella_headers.include?(header)
next "#import <#{FRAMEWORK_NAME}/#{header}>"
end
end
line
end
# Write this file back out to the filesystem
File.open(source_file, 'w') do |file|
file.puts modified_lines
end
end
@antongaenko
Copy link

Thank you a lot!
Consider several changes

Dir.glob("#{SOURCE_ROOT_PATH}/**/*.{h,m,mm,pch}") do |source_file| # find also mm & pch

next "#import <#{FRAMEWORK_NAME}/#{header}>\n" # add newline to changed string 

file.write modified_lines.join("") # instead of puts as it add newline to the end that could lead to changes for git

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment