Module: XcodePages

Defined in:
lib/XcodePages.rb,
lib/XcodePages/version.rb

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.build_versionObject

Answers the project build version using Apple’s agvtool. This is the real version number, equating to CURRENT_PROJECT_VERSION.



58
59
60
61
# File 'lib/XcodePages.rb', line 58

def self.build_version
  vers = %x(agvtool vers -terse).chomp
  vers =~ /\$\{(\w+)\}/ ? ENV[$1] : vers
end

.doxygenObject

Launches Doxygen.

The implementation derives the Doxygen project name from the environment PROJECT_NAME variable. Xcode passes this variable. Typically, it is a camel-cased name. Using ActiveSupport (part of the Rails framework) the implementation below derives a humanised title; effectively puts spaces in-between the camels!



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/XcodePages.rb', line 95

def self.doxygen
  IO.popen('doxygen -', 'r+') do |doxygen|
    doxygen.puts "      PROJECT_NAME           = \#{ENV['PROJECT_NAME'].titleize}\n      PROJECT_NUMBER         = \#{project_number}\n      OUTPUT_DIRECTORY       = \#{output_directory}\n      TAB_SIZE               = 4\n      EXTENSION_MAPPING      = h=Objective-C\n      INPUT                  = \#{input}\n      SOURCE_BROWSER         = YES\n      HTML_TIMESTAMP         = NO\n      GENERATE_LATEX         = NO\n    EOF\n\n    # Let the user override the previous defaults by loading up the Doxyfile\n    # if one exists. This should appear in the source root folder.\n    if File.exists?('Doxyfile')\n      doxygen.write File.read('Doxyfile')\n    end\n\n    # Close the write-end of the pipe.\n    doxygen.close_write\n\n    # Read the read-end of the pipe and send the lines to standard output.\n    puts doxygen.readlines\n  end\nend\n"

.doxygen_docsetObject

Launches Doxygen and builds the Apple DocSet. It does not install the DocSet. The compiled documentation set remains in the html sub-folder.



125
126
127
128
129
# File 'lib/XcodePages.rb', line 125

def self.doxygen_docset
  doxygen
  # Assume that doxygen succeeds. But what happens when it does not?
  %x(cd #{html_output_directory} ; make)
end

.doxygen_docset_installObject

Runs Doxygen and installs the Apple DocSet in the current user’s shared documentation folder. Finally, as a courtesy, it tells Xcode about the change; signalling an update in your running Xcode IDE. Documentation updates immediately.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/XcodePages.rb', line 135

def self.doxygen_docset_install
  doxygen
  %x(cd #{html_output_directory} ; make install)

  script = Tempfile.open(['XcodePages', '.scpt']) do |script|
    script.puts "      tell application \"Xcode\"\n    EOF\n    Dir.glob(File.join(html_output_directory, '*.docset')).each do |docset_path|\n      script.puts <<-EOF\n        load documentation set with path \"\#{ENV['HOME']}/Library/Developer/Shared/Documentation/DocSets/\#{File.basename(docset_path)}\"\n      EOF\n    end\n    script.puts <<-EOF\n      end tell\n    EOF\n    script.close\n    %x(osascript \#{script.path})\n  end\nend\n"

.html_output_directoryObject

Answers the path to the html output sub-folder where Doxygen writes the HTML web pages and the DocSet Makefile when GENERATE_DOCSET equals YES.



84
85
86
# File 'lib/XcodePages.rb', line 84

def self.html_output_directory
  File.join(output_directory, 'html')
end

.inputObject

Searches for all the available source files (files with h, m or mm extension) in the current working directory or below. Pulls out their directory names and answers an array of unique space-delimited relative folder paths. These directory names will become Doxygen input folders.

The implementation assumes that the current working directory equals the Xcode source root. It also makes some simplifying assumptions about spaces in the paths: that there are no spaces. Doxygen uses spaces to delimit the files and directories listed for input. But what if the paths themselves contain spaces?

Note that this method works correctly when the source root itself contains headers or sources. In this case, the answer will contain the “.” directory.



35
36
37
# File 'lib/XcodePages.rb', line 35

def self.input
  Dir.glob('**/*.{h,m,mm}').map { |relative_path| File.dirname(relative_path) }.uniq.join(' ')
end

.marketing_versionObject

Answers the project “marketing version” using Apple’s agvtool. The marketing version is the “bundle short version string” appearing in the bundle’s Info.plist. Cocoa only uses this for display in the standard About panel.

If the current marketing version is symbolic, answers the value of the symbol by looking up the value in the Unix environment. This assumes that Xcode provides the variable; and also assumes that Xcode addresses any nested substitution issues in scenarious where symbols comprise other symbols. Hence if agvtool reports a marketing version equal to ${CURRENT_PROJECT_VERSION}, the reply equals the value of CURRENT_PROJECT_VERSION found in the environment.



51
52
53
54
# File 'lib/XcodePages.rb', line 51

def self.marketing_version
  mvers = %x(agvtool mvers -terse1).chomp
  mvers =~ /\$\{(\w+)\}/ ? ENV[$1] : mvers
end

.output_directoryObject

Answers the path of the output directory. Doxygen outputs to this folder. HTML web pages appear in the html sub-folder.



77
78
79
# File 'lib/XcodePages.rb', line 77

def self.output_directory
  "#{ENV['PROJECT_NAME']}Pages"
end

Prints the environment. Xcode passes many useful pieces of information via the Unix environment.

This can be useful for testing. Add an external build target to Xcode. Make the Build Tool equal to /bin/sh and make the arguments equal to:

-c "$HOME/.rvm/bin/rvm-auto-ruby -r XcodePages -e XcodePages.print_env"

and you will see all the Unix environment variables. This assumes that you are using RVM in your local account to manage Ruby.



18
19
20
# File 'lib/XcodePages.rb', line 18

def self.print_env
  ENV.each { |key, value| puts "#{key}=#{value}" }
end

.project_numberObject

Answers what Doxygen calls the ‘project number.’ This is the revision number appearing beside the project name in the documentation title. Uses the marketing and build version numbers in the format vMV (BV) where MV stands for marketing version and BV stands for build version. Omits the build version if the project matches marketing and build version. No sense repeating the same number if they are the same.



69
70
71
72
73
# File 'lib/XcodePages.rb', line 69

def self.project_number
  project_number = "v#{marketing_version}"
  project_number << "&nbsp;(#{build_version})" if build_version != marketing_version
  project_number
end