Skip to content

Instantly share code, notes, and snippets.

@zubko
Created February 1, 2014 09:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zubko/8750079 to your computer and use it in GitHub Desktop.
Save zubko/8750079 to your computer and use it in GitHub Desktop.
Xcode build script. Generates JSONs with property description for Spark Inspector.
#!/usr/bin/ruby
# generate-spark-info.rb
#
# Generate JSONs with property description for Spark Inspector
# for the direct subclasses of UI.. classes in the project
# TODO
# - need:
# -- add detection of `typedef NS_ENUM()`s if they are declared in the same file
# -- speacial case for readonly properties
#
# - maybe:
# -- do not update JSONs if props structure wasnt changed
#
# - not so important:
# -- better detection of subclasses of CocoaTouch UI classes
# -- multiple classes can be declared in one file
# CONSTS
PropertyTypes = {
['int', 'NSInteger'] => 'INT',
['float', 'CGFloat', 'NSTimeInterval'] => 'FLOAT',
['BOOL'] => 'BOOL',
['UIColor'] => 'COLOR',
['NSString'] => 'STRING',
['UIFont'] => 'FONT',
['UIImage'] => 'IMAGE',
}
def spark_type_for_property_type(type)
PropertyTypes.each { |objc_types, spark_type| return spark_type if (objc_types.include? type) }
return nil
end
PropertyRE = /@property\s*[\(\s\w,\)]*?\s*?([\w\d]*?)[\s\*]*?([\w\d]*?);/
ClassInterfaceRE = /@interface\s+([\w\d]+)\s+:\s+([\w\d]+)/
GroupFormat = %@
{
"title": "%{name}",
"items": [
{
"keyPath": "%{name}",
"title": "%{name}",
"type": "%{type}"
}
]
}
@
FileFomat = %@
[
{
"title": "%{class}",
"groups": [
%{groups}
]
}
]
@
ProjectPath = "#{ENV['PROJECT_DIR']}"
AllHeaders = Dir.glob(ProjectPath + "/**/*.h")
SparkAttributesDir = "/Applications/Spark Inspector.app/Contents/Resources/InspectorConfigurations/Attributes"
SparkInfoPath = "#{SparkAttributesDir}/%s.json"
# CODE
# this script is needed only on dev machines
spark_config_ok = File.exists?(SparkAttributesDir) and File.directory?(SparkAttributesDir)
debug_build = ENV['CONFIGURATION'] == 'Debug'
exit if !spark_config_ok || !debug_build
# first collecting info about all props in the project
found_files = []
AllHeaders.each do |header_path|
contents = IO.read(header_path, encoding: "utf-8")
# check that parent class has UI prefix
classes_found = contents.scan(ClassInterfaceRE)
next if classes_found.length == 0
parent = classes_found[0][1]
next if parent[0..1] != "UI"
# get props info
properties = []
contents.scan(PropertyRE) do |type, name|
spark_type = spark_type_for_property_type type
properties << {:type=>spark_type, :name=>name} if (spark_type != nil)
end
if !properties.empty? then
class_name = File.basename(header_path, ".h")
found_files << {:class=>class_name, :props=>properties}
end
end
# creating files for found props
found_files.each do |info|
path = SparkInfoPath % info[:class]
info[:groups] = (info[:props].map { |prop_info| GroupFormat % prop_info }).join(",\n");
data = FileFomat % info
File.open(path, 'w') { |f| f.write(data) }
end
# say a word
puts "Generated Spark Inspector JSONs for %d classes." % found_files.length
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment