From 4b30306691c2c4c623871aa663a0e8083b4b11fc Mon Sep 17 00:00:00 2001 From: elijah Date: Sat, 23 Feb 2013 20:51:41 -0800 Subject: added `rake doc` command. --- Rakefile | 118 +++---------------------- lib/leap_cli.rb | 2 + lib/leap_cli/app.rb | 57 ------------ lib/leap_cli/markdown_document_listener.rb | 134 +++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 162 deletions(-) delete mode 100644 lib/leap_cli/app.rb create mode 100644 lib/leap_cli/markdown_document_listener.rb diff --git a/Rakefile b/Rakefile index 54ae637..e25ce30 100644 --- a/Rakefile +++ b/Rakefile @@ -27,8 +27,11 @@ $spec_path = 'leap_cli.gemspec' $base_dir = File.dirname(__FILE__) $spec = eval(File.read(File.join($base_dir, $spec_path))) $gem_path = File.join($base_dir, 'pkg', "#{$spec.name}-#{$spec.version}.gem") -$lib_dir = "#{$base_dir}/lib" -$LOAD_PATH.unshift $lib_dir +require File.join([$base_dir, 'lib','leap_cli','version.rb']) +LeapCli::REQUIRE_PATHS.each do |path| + path = File.expand_path(path, $base_dir) + $LOAD_PATH.unshift path unless $LOAD_PATH.include?(path) +end def built_gem_path Dir[File.join($base_dir, "#{$spec.name}-*.gem")].sort_by{|f| File.mtime(f)}.last @@ -125,108 +128,13 @@ end # rd.title = 'Your application title' # end -desc "Generate documentation" -task 'doc' do - require 'leap_cli' - require 'leap_cli/app' - - class DocMaker < GLI::Command - def initialize(app) - @app = app - @listener = GLI::Commands::RdocDocumentListener.new([],[],[]) - end - - def create - @listener.beginning - @listener.program_desc(@app.program_desc) unless @app.program_desc.nil? - @listener.program_long_desc(@app.program_long_desc) unless @app.program_long_desc.nil? - @listener.version(@app.version_string) - if any_options?(@app) - @listener.options - end - document_flags_and_switches(@listener, @app.flags.values.sort(&by_name), @app.switches.values.sort(&by_name)) - if any_options?(@app) - @listener.end_options - end - @listener.commands - document_commands(@listener, @app) - @listener.end_commands - @listener.ending - end - - private - - def document_commands(document_listener,context) - context.commands.values.reject {|_| _.nodoc }.sort(&by_name).each do |command| - call_command_method_being_backwards_compatible(document_listener,command) - document_listener.options if any_options?(command) - document_flags_and_switches(document_listener,command_flags(command),command_switches(command)) - document_listener.end_options if any_options?(command) - document_listener.commands if any_commands?(command) - document_commands(document_listener,command) - document_listener.end_commands if any_commands?(command) - document_listener.end_command(command.name) - end - document_listener.default_command(context.get_default_command) - end - - def call_command_method_being_backwards_compatible(document_listener,command) - command_args = [command.name, - Array(command.aliases), - command.description, - command.long_description, - command.arguments_description] - if document_listener.method(:command).arity == 6 - command_args << command.arguments_options - end - document_listener.command(*command_args) - end - - def by_name - lambda { |a,b| a.name.to_s <=> b.name.to_s } - end - - def command_flags(command) - command.topmost_ancestor.flags.values.select { |flag| flag.associated_command == command }.sort(&by_name) - end - - def command_switches(command) - command.topmost_ancestor.switches.values.select { |switch| switch.associated_command == command }.sort(&by_name) - end - - def document_flags_and_switches(document_listener,flags,switches) - flags.each do |flag| - document_listener.flag(flag.name, - Array(flag.aliases), - flag.description, - flag.long_description, - flag.safe_default_value, - flag.argument_name, - flag.must_match, - flag.type) - end - switches.each do |switch| - document_listener.switch(switch.name, - Array(switch.aliases), - switch.description, - switch.long_description, - switch.negatable) - end - end - - def any_options?(context) - options = if context.kind_of?(GLI::Command) - command_flags(context) + command_switches(context) - else - context.flags.values + context.switches.values - end - !options.empty? - end - - def any_commands?(command) - !command.commands.empty? +desc "Dumps all command line options to doc/leap.md" +task :doc do + Dir.chdir($base_dir + "/doc") do + if system('../bin/leap _doc --format=LeapCli::MarkdownDocumentListener') + puts "updated doc/leap.md" + else + puts "error" end end - - puts DocMaker.new(LeapCli::Commands).create -end +end \ No newline at end of file diff --git a/lib/leap_cli.rb b/lib/leap_cli.rb index 384a5f2..714211a 100644 --- a/lib/leap_cli.rb +++ b/lib/leap_cli.rb @@ -24,6 +24,8 @@ require 'leap_cli/config/secrets' require 'leap_cli/config/object_list' require 'leap_cli/config/manager' +require 'leap_cli/markdown_document_listener' + module LeapCli::Commands; end # diff --git a/lib/leap_cli/app.rb b/lib/leap_cli/app.rb deleted file mode 100644 index 90c4ae9..0000000 --- a/lib/leap_cli/app.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'gli' -require 'highline' -require 'forwardable' -require 'lib_ext/gli' # our custom extensions to gli - -# -# Typically, GLI and Highline methods are loaded into the global namespace. -# Instead, here we load these into the module LeapCli::Commands in order to -# ensure that the cli logic and code is kept isolated to leap_cli/commands/*.rb -# -# no cheating! -# -module LeapCli::Commands - extend GLI::App - extend Forwardable - - # - # delegate highline methods to make them available to sub-commands - # - @terminal = HighLine.new - def_delegator :@terminal, :ask, 'self.ask' - def_delegator :@terminal, :agree, 'self.agree' - def_delegator :@terminal, :choose, 'self.choose' - def_delegator :@terminal, :say, 'self.say' - def_delegator :@terminal, :color, 'self.color' - def_delegator :@terminal, :list, 'self.list' - - # - # make config manager available as 'manager' - # - def self.manager - @manager ||= begin - manager = LeapCli::Config::Manager.new - manager.load - manager - end - end - - # - # info about leap command line suite - # - program_desc LeapCli::SUMMARY - program_long_desc LeapCli::DESCRIPTION - - # - # handle --version ourselves - # - if ARGV.grep(/--version/).any? - puts "leap #{LeapCli::VERSION}, ruby #{RUBY_VERSION}" - exit(0) - end - - # - # load commands and run - # - commands_from('leap_cli/commands') -end diff --git a/lib/leap_cli/markdown_document_listener.rb b/lib/leap_cli/markdown_document_listener.rb new file mode 100644 index 0000000..60b012e --- /dev/null +++ b/lib/leap_cli/markdown_document_listener.rb @@ -0,0 +1,134 @@ +# +# A class to generate a markdown file with all the information available with the +# help subcommand. +# +# This is adapted from GLI::Commands::RdocDocumentListener +# + +require 'stringio' +require 'gli/commands/help_modules/arg_name_formatter' + +module LeapCli + class MarkdownDocumentListener + + def initialize(global_options,options,arguments) + @io = File.new(File.basename($0) + ".md",'w') + @nest = '' + @commands = [File.basename($0)] + @arg_name_formatter = GLI::Commands::HelpModules::ArgNameFormatter.new + end + + def beginning + end + + # Called when processing has completed + def ending + @io.close + end + + # Gives you the program description + def program_desc(desc) + @io.puts "@title = 'Command Line Reference'" + #@io.puts "# #{File.basename($0)} - #{desc}" + @io.puts + end + + def program_long_desc(desc) + @io.puts desc + @io.puts + end + + # Gives you the program version + def version(version) + #@io.puts "v#{version}" + #@io.puts + end + + def options + #@io.puts "
" + @io.puts + if @nest.size == 0 + @io.puts "# Global Options" + else + #@io.puts "#{@nest}# Options" + @io.puts "**Options**" + end + @io.puts + end + + # Gives you a flag in the current context + def flag(name,aliases,desc,long_desc,default_value,arg_name,must_match,type) + invocations = ([name] + Array(aliases)).map { |_| add_dashes(_) }.join('|') + usage = "#{invocations} #{arg_name || 'arg'}" + #@io.puts "#{@nest}## #{usage}" + @io.puts "* `#{usage}` " + @io.puts String(desc).strip + " " + @io.puts String(long_desc).strip + " " if long_desc + @io.puts "Default Value: #{default_value || 'None'} " + @io.puts "Must Match: #{must_match.to_s} " unless must_match.nil? + @io.puts + end + + # Gives you a switch in the current context + def switch(name,aliases,desc,long_desc,negetable) + if negetable + name = "[no-]#{name}" if name.to_s.length > 1 + aliases = aliases.map { |_| _.to_s.length > 1 ? "[no-]#{_}" : _ } + end + invocations = ([name] + aliases).map { |_| add_dashes(_) }.join('|') + #@io.puts "#{@nest}## #{invocations}" + @io.puts "* `#{invocations}` " + @io.puts String(desc).strip + " " + #@io.puts + #@io.puts String(long_desc).strip + @io.puts + end + + def end_options + #@io.puts "
" + end + + def commands + #@io.puts "#{@nest}## Commands" + #@nest = "#{@nest}#" + end + + # Gives you a command in the current context and creates a new context of this command + def command(name,aliases,desc,long_desc,arg_name,arg_options) + @commands.push(name) + #@io.puts "#{@nest}## Command: #{([name] + aliases).join('|')} #{@arg_name_formatter.format(arg_name,arg_options)}" + @io.puts + @io.puts "#{@nest}# #{@commands.join ' '} #{@arg_name_formatter.format(arg_name,arg_options)}" + @io.puts + @io.puts String(desc).strip + @io.puts + @io.puts String(long_desc).strip + @nest = "#{@nest}#" + end + + # Ends a command, and "pops" you back up one context + def end_command(name) + @nest.gsub!(/\#$/,'') + @commands.pop + end + + # Gives you the name of the current command in the current context + def default_command(name) + @io.puts "Default Command: #{name}" unless name.nil? + end + + def end_commands + @nest.gsub!(/\#$/,'') + end + + private + + def add_dashes(name) + name = "-#{name}" + name = "-#{name}" if name.length > 2 + name + end + + + end +end -- cgit v1.2.3