├── Rakefile ├── .gitignore ├── lib ├── vendor │ ├── version.rb │ ├── libraries │ │ └── three20.rb │ ├── source.rb │ ├── class_property.rb │ ├── helpers.rb │ ├── dependency_file.rb │ ├── lock_file.rb │ ├── cli.rb │ ├── library.rb │ ├── manager.rb │ └── xcode_handler.rb └── vendor.rb ├── Gemfile ├── bin └── vendor ├── example ├── Vendors └── Vendors.lock ├── vendor.gemspec └── README.md /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | .bundle 3 | Gemfile.lock 4 | pkg/* 5 | -------------------------------------------------------------------------------- /lib/vendor/version.rb: -------------------------------------------------------------------------------- 1 | module Vendor 2 | VERSION = "0.0.1" unless defined?(Vendor::VERSION) 3 | end 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | # Specify your gem's dependencies in vendor.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /bin/vendor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'rubygems' 3 | require 'thor' 4 | require 'grit' 5 | require File.expand_path(File.dirname(__FILE__) + "/../lib/vendor.rb") 6 | 7 | Vendor::Cli.start(ARGV) -------------------------------------------------------------------------------- /example/Vendors: -------------------------------------------------------------------------------- 1 | source "https://github.com/bazaarlabs/vendor.git" 2 | # lib "facebook-ios-sdk" # Formula specified at source above 3 | lib "three20" 4 | lib "asi-http-request", :git => "https://github.com/pokeb/asi-http-request.git" 5 | lib "JSONKit", :git => "https://github.com/johnezang/JSONKit.git" -------------------------------------------------------------------------------- /example/Vendors.lock: -------------------------------------------------------------------------------- 1 | three20 | https://github.com/facebook/three20.git | 0e27b65cb219744383181c19ac24d24ce312269e 2 | asi-http-request | https://github.com/pokeb/asi-http-request.git | 90e5fbce17d66e5341f105c1eb26133a01686838 3 | JSONKit | https://github.com/johnezang/JSONKit.git | c2146ffeb10d92bfa1537d2033a3235825d1b261 4 | -------------------------------------------------------------------------------- /lib/vendor/libraries/three20.rb: -------------------------------------------------------------------------------- 1 | require 'vendor/library' unless defined?(Vendor::Library) 2 | 3 | class Three20 < Vendor::Library 4 | source "https://github.com/facebook/three20.git" 5 | libraries 'libThree20.a' 6 | frameworks "CoreAnimation" 7 | header_path "three20/Build/Products/three20" 8 | linker_flags "ObjC", "all_load" 9 | vendors "JSONKit" 10 | end 11 | -------------------------------------------------------------------------------- /lib/vendor/source.rb: -------------------------------------------------------------------------------- 1 | # Represents a source from which fetch and load libraries 2 | 3 | module Vendor 4 | class Source 5 | attr_reader :path 6 | 7 | # Vendor::Source.new("https://github.com/bazaarlabs/vendor") 8 | # Vendor::Source.new("./formulae") 9 | def initialize(path) 10 | @path = path 11 | end 12 | 13 | # Returns enhanced string representation 14 | # @source.to_s = " @path="http://path/to/remote/source/repo.git"" 15 | def to_s 16 | "#{super} @path=#{self.path}" 17 | end # to_s 18 | 19 | # Fetch source and require files locally 20 | # @source.fetch 21 | def fetch 22 | if @path =~ /.git$/ 23 | puts "[source] fetching source path from #{self.path}" 24 | # TODO actually fetch source and load formula 25 | end 26 | end # fetch 27 | end 28 | end -------------------------------------------------------------------------------- /vendor.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "vendor/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "vendor" 7 | s.version = Vendor::VERSION 8 | s.authors = ["Nathan Esquenazi"] 9 | s.email = ["nesquena@gmail.com"] 10 | s.homepage = "" 11 | s.summary = %q{iOS library management system} 12 | s.description = %q{iOS library management system} 13 | 14 | s.rubyforge_project = "vendor" 15 | 16 | s.files = `git ls-files`.split("\n") 17 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 18 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 19 | s.require_paths = ["lib"] 20 | 21 | s.add_dependency 'grit' 22 | s.add_dependency 'thor' 23 | s.add_dependency 'rb-appscript' 24 | end 25 | -------------------------------------------------------------------------------- /lib/vendor.rb: -------------------------------------------------------------------------------- 1 | require 'grit' 2 | require File.expand_path(File.dirname(__FILE__) + '/vendor/version') 3 | require File.expand_path(File.dirname(__FILE__) + '/vendor/helpers') 4 | require File.expand_path(File.dirname(__FILE__) + '/vendor/class_property') 5 | require File.expand_path(File.dirname(__FILE__) + '/vendor/xcode_handler') 6 | require File.expand_path(File.dirname(__FILE__) + '/vendor/library') 7 | require File.expand_path(File.dirname(__FILE__) + '/vendor/source') 8 | require File.expand_path(File.dirname(__FILE__) + '/vendor/dependency_file') 9 | require File.expand_path(File.dirname(__FILE__) + '/vendor/lock_file') 10 | require File.expand_path(File.dirname(__FILE__) + '/vendor/manager') 11 | require File.expand_path(File.dirname(__FILE__) + '/vendor/cli') 12 | Dir[File.expand_path(File.dirname(__FILE__) + '/vendor/libraries/*.rb')].each do |lib| 13 | require lib 14 | end 15 | 16 | module Vendor 17 | # Nothing here yet 18 | end -------------------------------------------------------------------------------- /lib/vendor/class_property.rb: -------------------------------------------------------------------------------- 1 | =begin 2 | 3 | Used to define getter/setter properties at the class level 4 | 5 | class Example 6 | include Vendor::ClassProperty 7 | 8 | class_property :name 9 | # Example.name("foo", "bar") 10 | # Example.name => ["foo", "bar"] 11 | # @example.name => ["foo", "bar"] 12 | end 13 | 14 | Used primarily for simple DSLs when defining class values 15 | 16 | =end 17 | 18 | module Vendor 19 | module ClassProperty 20 | 21 | # Define getter/setter properties at the class level 22 | def class_property(name) 23 | self.metaclass.instance_eval do 24 | define_method(name) do |*args| 25 | if args.any? && args.length == 1 26 | self.instance_variable_set(:"@#{name}", args.first) 27 | elsif args.any? && args.length > 1 28 | self.instance_variable_set(:"@#{name}", args) 29 | else # retrieve 30 | self.instance_variable_get(:"@#{name}") 31 | end 32 | end 33 | end 34 | 35 | # Creates instance level method returning same value 36 | define_method(name) do 37 | self.class.send(name) 38 | end 39 | end # class_property 40 | end # ClassProperty 41 | end # Vendor 42 | -------------------------------------------------------------------------------- /lib/vendor/helpers.rb: -------------------------------------------------------------------------------- 1 | # Vendor helpers for the different library functions 2 | 3 | module Vendor 4 | module Helpers 5 | # resolve_library(:name => "foo", :git => "http://path/to/repo.git") => 6 | # resolve_library(:name => "baz", :class => "BazLib") => 7 | def resolve_library(lib_data) 8 | lib_data = lib_data.dup 9 | if lib_data[:git] # simple git library 10 | Vendor::Library.new(lib_data.delete(:name), lib_data) 11 | else # defined library 12 | klazz_name = lib_data[:class] || camelize_word(lib_data[:name].gsub(/-/, '_')) 13 | klazz = eval(klazz_name) rescue nil 14 | raise "Cannot find formula #{klazz_name.inspect}" unless klazz 15 | klazz.new(lib_data[:name], lib_data) 16 | end # find library instance 17 | end 18 | 19 | # camelize_word("lower_case_lib") => "LowerCaseLib" 20 | def camelize_word(lower_case_and_underscored_word) 21 | lower_case_and_underscored_word.to_s.gsub(/\/(.?)/) { 22 | "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase } 23 | end 24 | end 25 | end 26 | 27 | class Object 28 | def metaclass 29 | class << self; self; end 30 | end unless Object.method_defined?(:metaclass) 31 | end -------------------------------------------------------------------------------- /lib/vendor/dependency_file.rb: -------------------------------------------------------------------------------- 1 | # Represents the dependency "Vendors" file declaring required libraries 2 | 3 | module Vendor 4 | class DependencyFile 5 | include Vendor::Helpers 6 | 7 | attr_reader :sources 8 | 9 | # Vendor::DependencyFile.new("path/to/project/Vendors") 10 | def initialize(file_path) 11 | @file_path = file_path 12 | @text = File.read(file_path) 13 | @sources, @libs = [], [] 14 | self.instance_eval(@text) 15 | end 16 | 17 | # source "https://github.com/bazaarlabs/vendor" 18 | def source(path=nil) 19 | @sources << Vendor::Source.new(path) if path 20 | end 21 | 22 | # lib "three20", :class => 'Three20' 23 | # lib "asi-http-request", :git => "https://github.com/pokeb/asi-http-request.git" 24 | # lib "asi-http-request", :git => "https://github.com/pokeb/asi-http-request.git", :branch => "foobar" 25 | def lib(name, options={}) 26 | @libs << options.merge(:name => name) 27 | end 28 | 29 | # Returns library instances based on specified Vendors information 30 | # @depfile.libraries => [, ] 31 | def libraries 32 | @_libraries ||= @libs.map do |lib_data| 33 | resolve_library(lib_data) 34 | end 35 | end # libraries 36 | end # DependencyFile 37 | end # Vendor -------------------------------------------------------------------------------- /lib/vendor/lock_file.rb: -------------------------------------------------------------------------------- 1 | # Represents a Vendor.lock file detailing the locked libraries and versions 2 | 3 | module Vendor 4 | class LockFile 5 | include Vendor::Helpers 6 | 7 | # Construct a lockfile representation 8 | # Vendor::LockFile.new("/path/to/project/Vendor.lock", , ...) 9 | def initialize(lock_path, depfile, options={}) 10 | @path = lock_path 11 | @depfile = depfile 12 | end 13 | 14 | # Returns if the file exists 15 | # @lockfile.exists? => true 16 | def exists? 17 | File.exist?(@path) 18 | end 19 | 20 | # Returns libraries specified in Vendor.lock 21 | # @lockfile.libraries => [, ] 22 | def libraries 23 | File.read(@path).split("\n").map do |file_data| 24 | split_data = file_data.split(" | ") 25 | lib_data = { :name => split_data.first, :git => split_data[1], :revision => split_data.last } 26 | resolve_library(lib_data) 27 | end 28 | end # locked_libraries 29 | 30 | # Outputs a lock file with specific versions 31 | # @lockfile.generate! => ...writes lock file... 32 | def generate! 33 | f = File.new(@path, 'w') 34 | @depfile.libraries.each do |library| 35 | f.puts "#{library.name} | #{library.source} | #{library.revision}" 36 | end 37 | f.close 38 | end 39 | end # LockFile 40 | end # Vendor -------------------------------------------------------------------------------- /lib/vendor/cli.rb: -------------------------------------------------------------------------------- 1 | # Thor CLI running `vendor` binary 2 | module Vendor 3 | class Cli < Thor 4 | include Thor::Actions 5 | 6 | # vendor install --path . --file Vendors 7 | desc "install", "Installs the dependencies specified in the Vendors file" 8 | method_option :file, :default => "./Vendors", :aliases => "-f" 9 | method_option :path, :default => ".", :aliases => "-p" 10 | def install 11 | manager = Vendor::Manager.new(options[:path], :vendors_file_path => options[:file]) 12 | manager.install! 13 | say "Vendored libraries have been installed", :green 14 | end # install 15 | 16 | # vendor update 17 | # vendor update facebook-ios-sdk 18 | desc "update LIB_NAME", "Updates the dependency specified in the Vendors file" 19 | def update(lib_name=nil) 20 | manager = Vendor::Manager.new(Dir.pwd) 21 | manager.update!(lib_name) 22 | end # update 23 | 24 | # vendor list 25 | desc "list", "Lists the dependencies specified for this project" 26 | def list 27 | manager = Vendor::Manager.new(Dir.pwd) 28 | say "Dependencies:\n" 29 | manager.libraries.each do |lib| 30 | say " #{lib}", :yellow 31 | end 32 | end 33 | 34 | # vendor check 35 | desc "check", "Checks which dependencies are satisfied" 36 | def check 37 | manager = Vendor::Manager.new(Dir.pwd) 38 | missing = manager.missing_libraries 39 | if missing.any? 40 | puts "Missing:\n" 41 | missing.each { |lib| say lib, :yellow } 42 | else # all met 43 | say "All dependencies have been satisfied", :green 44 | end 45 | end # check 46 | end # CLI 47 | end -------------------------------------------------------------------------------- /lib/vendor/library.rb: -------------------------------------------------------------------------------- 1 | module Vendor 2 | class Library 3 | extend Vendor::ClassProperty 4 | 5 | class_property :source 6 | class_property :header_path 7 | class_property :libraries 8 | class_property :frameworks 9 | class_property :linker_flags 10 | class_property :vendors 11 | 12 | attr_reader :name, :source, :local_path 13 | 14 | # Vendor::Library.new("three20", [, ], { }) 15 | # Construct new instance of a library 16 | def initialize(name, options={}) 17 | @name = name 18 | @options = options 19 | @source = @options[:git] || self.class.source 20 | @revision = @options[:revision] 21 | end 22 | 23 | # Downloads remote library to vendored path 24 | # @library.fetch("/path/to/project/vendored") 25 | def fetch(vendored_path) 26 | if @source && @source =~ /\.git$/ 27 | self.fetch_git(vendored_path) 28 | end # fetch_git 29 | end # fetch 30 | 31 | # Retrieves the revision number for this library 32 | # @library.revision => "c1b3hg7" 33 | def revision(library_path = self.local_path) 34 | @revision ||= begin 35 | missing_git_repo = !File.exist?(library_path.to_s + "/.git") 36 | return if library_path.nil? || missing_git_repo 37 | grit = Grit::Repo.new(library_path) 38 | grit.commits('master', 1).first.sha 39 | end 40 | end 41 | 42 | # Returns enhanced to_s string representation 43 | def to_s 44 | "Library: #{self.name} (#{self.source}) [#{self.revision}]" 45 | end 46 | 47 | protected 48 | 49 | # Downloads remote library to vendored path from git repo (if needed) 50 | # @library_path.fetch_git("/path/to/project/vendored") 51 | def fetch_git(vendored_path) 52 | @local_path = File.join(vendored_path, @name) 53 | if self.revision.nil? # no local copy 54 | FileUtils.mkdir_p(vendored_path) 55 | puts "fetching #{self.name} from #{self.source}" 56 | puts `git clone #{self.source} #{@local_path}` 57 | end 58 | end # fetch_git 59 | end # Library 60 | end # Vendor -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vendor – an iOS library management system # 2 | 3 | Vendor makes the process of using and managing libraries in iOS easy. Vendor leverages the XCode Workspaces feature introduced with XCode 4 and is modeled after Bundler. Vendor streamlines the installation and update process for dependent libraries. It also tracks versions and manages dependencies between libraries. 4 | 5 | ## Step 1) Specify dependencies ## 6 | 7 | Specify your dependencies in a Vendors file in your project’s root. 8 | 9 | ```ruby 10 | source "https://github.com/bazaarlabs/vendor" 11 | 12 | lib "facebook-ios-sdk" # Formula specified at source above 13 | lib "three20" 14 | lib "asi-http-request", :git => "https://github.com/pokeb/asi-http-request.git" 15 | lib "JSONKit", :git => "https://github.com/johnezang/JSONKit.git" 16 | ``` 17 | 18 | ## Step 2) Install dependencies ## 19 | 20 | ```ruby 21 | vendor install 22 | git add Vendors.lock 23 | ``` 24 | 25 | Installing a vendor library gets the latest version of the code, and adds the XCode project to the workspace. As part of the installation process, the library is set up as a dependency of the main project, header search paths are modified, and required frameworks are added. The installed version of the library is captured in the Vendors.lock file. 26 | 27 | After a fresh check out of a project from source control, the XCode workspace may contain links to projects that don’t exist in the file system because vendor projects are not checked into source control. Run `vendor install` to restore the vendor projects. 28 | 29 | ## Other commands ## 30 | 31 | Updating all dependencies will update all libraries to their latest versions: 32 | 33 | ```bash 34 | vendor update 35 | ``` 36 | 37 | Specifying the dependency will cause only the single library to be updated: 38 | 39 | ```bash 40 | vendor update facebook-ios-sdk 41 | ``` 42 | 43 | ## Adding a library formula ## 44 | 45 | If a library has no framework dependencies, has no required additional compiler/linker flags, and has an XCode project, it doesn’t require a Vendor formula. An example is JSONKit, which may be specified as below. However, if another Vendor library requires JSONKit, JSONKit must have a Vendor formula. 46 | 47 | ```ruby 48 | lib "JSONKit", :git => "https://github.com/johnezang/JSONKit.git" 49 | ``` 50 | 51 | However, if the library requires frameworks or has dependencies on other Vendor libraries, it must have a Vendor formula. As with Brew, a Vendor formula is some declarative Ruby code that is open source and centrally managed. 52 | 53 | An example Vendor formula might look like: 54 | 55 | ```ruby 56 | require 'vendor/library' 57 | 58 | class Three20 < Vendor::Library 59 | source "https://github.com/facebook/three20" 60 | libraries libThree20.a 61 | frameworks "CoreAnimation" 62 | header_path "three20/Build/Products/three20" 63 | linker_flags "ObjC", "all_load" 64 | vendors "JSONKit" 65 | end 66 | ``` -------------------------------------------------------------------------------- /lib/vendor/manager.rb: -------------------------------------------------------------------------------- 1 | # Manager that handles all essential vendoring functionality 2 | 3 | module Vendor 4 | class Manager 5 | # Vendor::Manager.new("/path/to/project", :vendored_path => "path/to/project/vendored") 6 | # options = { :vendors_file => "/path/to/project/Vendors" } 7 | def initialize(current_path, options={}) 8 | @folder = current_path 9 | @vendored_path = options.delete(:vendored_path) || File.join(@folder, "vendored") 10 | @vendors_file_path = options.delete(:vendors_file) || File.join(@folder, "Vendors") 11 | @lock_file_path = options.delete(:lock_file) || File.join(@folder, "Vendors.lock") 12 | @depfile = DependencyFile.new(@vendors_file_path) 13 | @lockfile = LockFile.new(@lock_file_path, @depfile) 14 | @xcode_handler = XcodeHandler.new(@folder) 15 | end 16 | 17 | # Installs all deps to vendored path and generates a lockfile 18 | # @manager.install! => ...vendor to local path and generate lock file... 19 | def install! 20 | self.vendor! 21 | @lockfile.generate! 22 | end 23 | 24 | # Updates the deps from Vendors, recreates Vendors.lock 25 | # Only for library_name if specified 26 | # @manager.update 27 | # @manager.update("three20") 28 | def update!(library_name=nil) 29 | if library_name # only library 30 | local_path = File.join(@vendored_path, library_name) 31 | FileUtils.rm_rf(local_path) 32 | library = @depfile.libraries.find { |l| l.name == library_name } 33 | library.fetch(@vendored_path) 34 | else # update all libs 35 | FileUtils.rm_rf(@vendored_path) 36 | self.install! 37 | end 38 | end 39 | 40 | # Returns the most accurate library list possible 41 | # @manager.libraries => [, ...] 42 | def libraries 43 | self.locked_libraries || self.required_libraries 44 | end 45 | 46 | # Returns the libraries required by Vendors file 47 | # @manager.required_libraries => [, ...] 48 | def required_libraries 49 | @depfile.libraries 50 | end 51 | 52 | # Returns libraries that are locked as dependencies in Vendors.lock 53 | # @manager.locked_libraries => [, ...] 54 | def locked_libraries 55 | @lockfile.libraries if @lockfile.exists? 56 | end 57 | 58 | # Returns libraries that are missing from local installation 59 | # @manager.locked_libraries => [, ...] 60 | def missing_libraries 61 | return self.required_libraries unless @lockfile.exists? 62 | self.locked_libraries.select do |lib| 63 | local_path = File.join(@vendored_path, lib.name) 64 | installed = @depfile.libraries.find { |l| l.name == lib.name } 65 | installed.nil? || installed.revision(local_path) != lib.revision 66 | end 67 | end # missing_libraries 68 | 69 | protected 70 | 71 | # Vendors the various libraries to the specified "vendored" path 72 | # @manager.vendor! 73 | def vendor! 74 | @depfile.sources.each { |source| source.fetch } 75 | self.required_libraries.each { |library| library.fetch(@vendored_path) } 76 | end 77 | end 78 | end -------------------------------------------------------------------------------- /lib/vendor/xcode_handler.rb: -------------------------------------------------------------------------------- 1 | # Manages XCode interactions using AppleScript 2 | 3 | require 'appscript' 4 | 5 | module Vendor 6 | class XcodeHandler 7 | # Vendor::XcodeHandler.new 8 | def initialize(project_path) 9 | @app = Appscript.app('Xcode') 10 | end 11 | 12 | # @xcode.version => 4 13 | def version 14 | @version = @app.version.get.split('.')[0].to_i 15 | end 16 | 17 | # @xcode.open_project("path/to/project") 18 | def open_project(project_path) 19 | @app.open(project_path) 20 | end 21 | end # XcodeHandler 22 | end # Vendor 23 | 24 | =begin 25 | 26 | Check: https://github.com/gonzoua/xcs/blob/master/xcs.thor 27 | # TODO Remove this printout 28 | @app.methods => 29 | ["bounds", "target_type", "link_binary_with_libraries_phases", "minimum_count", 30 | "source_directories", "product_directory", "startup_directory", "real_path", 31 | "build_messages", "starting_page", "project_documents", "project_relative_path", 32 | "show_document_with_UUID", "frontmost", "schemes", "build_file", "Xcode_3_file_references", 33 | "build_java_resources_phase", "documents", "document", "abstract", "build_settings", 34 | "build_java_resources_phases", "active", "project_file_reference", "move", "workspace_documents", 35 | "contents", "id_", "condition", "delete", "closeable", "product_reference", "copy_headers_phases", 36 | "reopen", "maximum_count", "environment_variables", "indent_width", "select", "build_configuration_types", 37 | "launchable", "file_name", "root_group", "clean", "model_documents", "path_type", "size", 38 | "destination_directory", "scm_update", "active_workspace_document", "location", "text", "project_items", 39 | "kind", "build_styles", "color", "active_build_style", "user_info", "project_roots", "attribute_runs", 40 | "target_printer", "tag", "build", "enabled", "file_documents", "miniaturizable", 41 | "copy_bundle_resources_phases", "value", "native", "make", "relationships", "file_kind", 42 | "inverse_relationship", "comments", "breakpoints", "superclasses", "close", "upgrade_project_file", 43 | "run_only_when_installing", "class_model_documents", "localized", "show_document_with_apple_ref", 44 | "count", "active_blueprint_document", "full_path", "file_breakpoints", "add", "exists", 45 | "active_executable", "font", "text_bookmarks", "path_for_apple_ref", "path", "transient", 46 | "item_references", "character_range", "fax_number", "user_file_reference", "paragraphs", 47 | "load_documentation_set_with_path", "open_location", "build_configuration_type", "target_dependencies", 48 | "miniaturized", "compile_applescripts_phases", "executables", "link_binary_with_libraries_phase", 49 | "author", "fetch_requests", "head_revision_number", "document_or_list_of_document", "destination_entity", 50 | "project", "output_paths", "implementation_language", "debug", "run_script_phase", "blueprint_documents", 51 | "line_ending", "path_for_document_with_UUID", "active_project_document", "containers", "container", 52 | "selected_paragraph_range", "scm_revisions", "active_SDK", "message", "ending_page", "optional", 53 | "symbolic_breakpoints", "revision", "set", "windows", "error_handling", "Xcode_3_groups", 54 | "active_architecture", "scm_clear_sticky_tags", "flattened_build_settings", "rich_text", 55 | "configuration_settings_file", "executable", "version", "copy_headers_phase", "attributes", 56 | "build_phases", "resizable", "scm_compare", "file_or_list_of_file", "destination", 57 | "data_model_documents", "revision_number", "properties_", "remove", "input_paths", "hide_action", 58 | "line_number", "save", "launch_arguments", "leaf", "activate", "shell_path", "modified", 59 | "selected_character_range", "build_files", "collating", "operations", "active_target", 60 | "project_templates", "commit_message", "attribute_type", "active_build_configuration_type", "applications", 61 | "requested_print_time", "scm_commit", "build_phase", "base_build_settings", "open", "visible", "target", 62 | "group", "copy_bundle_resources_phase", "attachments", "build_products_relative_path", "items", 63 | "list_of_file_or_specifier", "predicate", "description", "source_documents", "groups", 64 | "default_build_configuration_type", "copy_files_phases", "hidden_per_filter", "shell_script", 65 | "print_settingss", "symbol_name", "launch", "active_arguments", "notifies_when_closing", 66 | "build_configurations", "index", "status", "RGB_color", "copies", "code_classes", "currently_building", 67 | "hack", "projects", "scm_transcript", "class_", "breakpoints_enabled", "variables", "uses_tabs", 68 | "text_documents", "pages_down", "urlstring_for_document_with_apple_ref", "compiled_code_size", "print", 69 | "words", "zoomable", "compile_sources_phase", "insertion_points", "get", "parent", "organization_name", 70 | "quit", "compile_sources_phases", "hidden_in_diagram", "urlstring_for_document_with_UUID", 71 | "show_environment_variables", "fetched_properties", "file_encoding", "run_script_phases", "project_member", 72 | "run", "editor_settings", "default_value", "documentation_configuration_changed", "bookmarks", 73 | "intermediates_directory", "to_many", "duplicate", "selection", "container_items", "availability", 74 | "upgrade", "pages_across", "target_templates", "tab_width", "scm_refresh", "file", 75 | "file_references", "timestamp", "file_reference", "build_resource_manager_resources_phase", 76 | "characters", "zoomed", "launch_", "object_class", "targets", "category", "project_directory", 77 | "read_only", "build_resource_manager_resources_phases", "entire_contents", "automatically_continue", 78 | "entities"] 79 | =end --------------------------------------------------------------------------------