From 59e7ef15507de48f6504ef21a8e0e775104961c6 Mon Sep 17 00:00:00 2001 From: Daniel Pittman Date: Tue, 26 Apr 2011 23:30:08 -0700 Subject: (#6962) Move documentation support into a module. Given that we have identical documentation behaviour in the face and action code, it should properly be written once. So, move it into a module, extend the other classes with it, and have done. --- lib/puppet/interface/documentation.rb | 168 ++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 lib/puppet/interface/documentation.rb (limited to 'lib/puppet/interface/documentation.rb') diff --git a/lib/puppet/interface/documentation.rb b/lib/puppet/interface/documentation.rb new file mode 100644 index 000000000..f3bf33da5 --- /dev/null +++ b/lib/puppet/interface/documentation.rb @@ -0,0 +1,168 @@ +class Puppet::Interface + module DocSupport + attr_accessor :summary + def summary(value = nil) + self.summary = value unless value.nil? + @summary + end + def summary=(value) + value = value.to_s + value =~ /\n/ and + raise ArgumentError, "Face summary should be a single line; put the long text in 'description' instead." + + @summary = value + end + + attr_accessor :description + def description(value = nil) + self.description = value unless value.nil? + @description + end + + attr_accessor :examples + def examples(value = nil) + self.examples = value unless value.nil? + @examples + end + + attr_accessor :short_description + def short_description(value = nil) + self.short_description = value unless value.nil? + if @short_description.nil? then + return nil if @description.nil? + lines = @description.split("\n") + grab = [5, lines.index('') || 5].min + @short_description = lines[0, grab].join("\n") + end + @short_description + end + + def author(value = nil) + unless value.nil? then + unless value.is_a? String + raise ArgumentError, 'author must be a string; use multiple statements for multiple authors' + end + + if value =~ /\n/ then + raise ArgumentError, 'author should be a single line; use multiple statements for multiple authors' + end + @authors.push(value) + end + @authors.empty? ? nil : @authors.join("\n") + end + def author=(value) + if Array(value).any? {|x| x =~ /\n/ } then + raise ArgumentError, 'author should be a single line; use multiple statements' + end + @authors = Array(value) + end + def authors + @authors + end + def authors=(value) + if Array(value).any? {|x| x =~ /\n/ } then + raise ArgumentError, 'author should be a single line; use multiple statements' + end + @authors = Array(value) + end + + attr_accessor :notes + def notes(value = nil) + @notes = value unless value.nil? + @notes + end + + attr_accessor :license + def license(value = nil) + @license = value unless value.nil? + @license + end + + def copyright(owner = nil, years = nil) + if years.nil? and not owner.nil? then + raise ArgumentError, 'copyright takes the owners names, then the years covered' + end + self.copyright_owner = owner unless owner.nil? + self.copyright_years = years unless years.nil? + + if self.copyright_years or self.copyright_owner then + "Copyright #{self.copyright_years} by #{self.copyright_owner}" + else + "Unknown copyright owner and years." + end + end + + attr_accessor :copyright_owner + def copyright_owner=(value) + case value + when String then @copyright_owner = value + when Array then @copyright_owner = value.join(", ") + else + raise ArgumentError, "copyright owner must be a string or an array of strings" + end + @copyright_owner + end + + attr_accessor :copyright_years + def copyright_years=(value) + years = munge_copyright_year value + years = (years.is_a?(Array) ? years : [years]). + sort_by do |x| x.is_a?(Range) ? x.first : x end + + @copyright_years = years.map do |year| + if year.is_a? Range then + "#{year.first}-#{year.last}" + else + year + end + end.join(", ") + end + + def munge_copyright_year(input) + case input + when Range then input + when Integer then + if input < 1970 then + fault = "before 1970" + elsif input > (future = Time.now.year + 2) then + fault = "after #{future}" + end + if fault then + raise ArgumentError, "copyright with a year #{fault} is very strange; did you accidentally add or subtract two years?" + end + + input + + when String then + input.strip.split(/,/).map do |part| + part = part.strip + if part =~ /^\d+$/ then + part.to_i + elsif found = part.split(/-/) then + unless found.length == 2 and found.all? {|x| x.strip =~ /^\d+$/ } + raise ArgumentError, "#{part.inspect} is not a good copyright year or range" + end + Range.new(found[0].to_i, found[1].to_i) + else + raise ArgumentError, "#{part.inspect} is not a good copyright year or range" + end + end + + when Array then + result = [] + input.each do |item| + item = munge_copyright_year item + if item.is_a? Array + result.concat item + else + result << item + end + end + result + + else + raise ArgumentError, "#{input.inspect} is not a good copyright year, set, or range" + end + end + end +end -- cgit From e8eb290a1681baa19ef0b035af7cf17daadc6069 Mon Sep 17 00:00:00 2001 From: Daniel Pittman Date: Wed, 27 Apr 2011 10:05:48 -0700 Subject: (#6962) Finish documentation API on Face options. This extends the last of the documentation support, down into options, so they can be described as expected. In the process we split out the modular docs API into a full and short version options only want short docs, but the behaviours are identical to the full version. --- lib/puppet/interface/documentation.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/puppet/interface/documentation.rb') diff --git a/lib/puppet/interface/documentation.rb b/lib/puppet/interface/documentation.rb index f3bf33da5..d0bfbb261 100644 --- a/lib/puppet/interface/documentation.rb +++ b/lib/puppet/interface/documentation.rb @@ -1,5 +1,5 @@ class Puppet::Interface - module DocSupport + module TinyDocs attr_accessor :summary def summary(value = nil) self.summary = value unless value.nil? @@ -18,6 +18,10 @@ class Puppet::Interface self.description = value unless value.nil? @description end + end + + module FullDocs + include TinyDocs attr_accessor :examples def examples(value = nil) -- cgit From 65b9a3c4f4e6830ed094d46381050dfa72c7eccd Mon Sep 17 00:00:00 2001 From: Daniel Pittman Date: Fri, 29 Apr 2011 15:19:24 -0700 Subject: (#7221) Strip bad whitespace from face and action docs. We now strip whitespace in face (and related) documentation in two places: We strip any trailing whitespace on each line, just because. We strip any leading indent, but not all leading whitespace, from the text. That is, we strip the *minimum* amount of whitespace that we can take from every line in the documentation without changing the overall content. Reviewed-By: Pieter van de Bruggen --- lib/puppet/interface/documentation.rb | 104 ++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 41 deletions(-) (limited to 'lib/puppet/interface/documentation.rb') diff --git a/lib/puppet/interface/documentation.rb b/lib/puppet/interface/documentation.rb index d0bfbb261..91db0e074 100644 --- a/lib/puppet/interface/documentation.rb +++ b/lib/puppet/interface/documentation.rb @@ -1,35 +1,74 @@ +# This isn't usable outside Puppet::Interface; don't load it alone. class Puppet::Interface - module TinyDocs - attr_accessor :summary - def summary(value = nil) - self.summary = value unless value.nil? - @summary + module DocGen + def self.strip_whitespace(text) + text.gsub!(/[ \t\f]+$/, '') + + # We need to identify an indent: the minimum number of whitespace + # characters at the start of any line in the text. + indent = text.each_line.map {|x| x.index(/[^\s]/) }.compact.min + + if indent > 0 then + text.gsub!(/^[ \t\f]{0,#{indent}}/, '') + end + + return text end - def summary=(value) - value = value.to_s - value =~ /\n/ and - raise ArgumentError, "Face summary should be a single line; put the long text in 'description' instead." - @summary = value + # The documentation attributes all have some common behaviours; previously + # we open-coded them across the set of six things, but that seemed + # wasteful - especially given that they were literally the same, and had + # the same bug hidden in them. + # + # This feels a bit like overkill, but at least the common code is common + # now. --daniel 2011-04-29 + def attr_doc(name, &validate) + # Now, which form of the setter do we want, validated or not? + get_arg = "value.to_s" + if validate + define_method(:"_validate_#{name}", validate) + get_arg = "_validate_#{name}(#{get_arg})" + end + + # We use module_eval, which I don't like much, because we can't have an + # argument to a block with a default value in Ruby 1.8, and I don't like + # the side-effects (eg: no argument count validation) of using blocks + # without as metheds. When we are 1.9 only (hah!) you can totally + # replace this with some up-and-up define_method. --daniel 2011-04-29 + module_eval(<<-EOT, __FILE__, __LINE__ + 1) + def #{name}(value = nil) + self.#{name} = value unless value.nil? + @#{name} + end + + def #{name}=(value) + @#{name} = Puppet::Interface::DocGen.strip_whitespace(#{get_arg}) + end + EOT end + end + + module TinyDocs + extend Puppet::Interface::DocGen - attr_accessor :description - def description(value = nil) - self.description = value unless value.nil? - @description + attr_doc :summary do |value| + value =~ /\n/ and + raise ArgumentError, "Face summary should be a single line; put the long text in 'description' instead." + value end + + attr_doc :description end module FullDocs + extend Puppet::Interface::DocGen include TinyDocs - attr_accessor :examples - def examples(value = nil) - self.examples = value unless value.nil? - @examples - end + attr_doc :examples + attr_doc :notes + attr_doc :license - attr_accessor :short_description + attr_doc :short_description def short_description(value = nil) self.short_description = value unless value.nil? if @short_description.nil? then @@ -50,37 +89,20 @@ class Puppet::Interface if value =~ /\n/ then raise ArgumentError, 'author should be a single line; use multiple statements for multiple authors' end - @authors.push(value) + @authors.push(Puppet::Interface::DocGen.strip_whitespace(value)) end @authors.empty? ? nil : @authors.join("\n") end - def author=(value) - if Array(value).any? {|x| x =~ /\n/ } then - raise ArgumentError, 'author should be a single line; use multiple statements' - end - @authors = Array(value) - end def authors @authors end - def authors=(value) + def author=(value) if Array(value).any? {|x| x =~ /\n/ } then raise ArgumentError, 'author should be a single line; use multiple statements' end - @authors = Array(value) - end - - attr_accessor :notes - def notes(value = nil) - @notes = value unless value.nil? - @notes - end - - attr_accessor :license - def license(value = nil) - @license = value unless value.nil? - @license + @authors = Array(value).map{|x| Puppet::Interface::DocGen.strip_whitespace(x) } end + alias :authors= :author= def copyright(owner = nil, years = nil) if years.nil? and not owner.nil? then -- cgit From 8f81f56e8315a62e6c8ff8943c64df7594855359 Mon Sep 17 00:00:00 2001 From: Daniel Pittman Date: Tue, 3 May 2011 15:51:02 -0700 Subject: (#7326) Fix faces on Ruby 1.8.5 Turns out that String#each_line on Ruby 1.8.5 only takes a block, and will not return an enumerable. Rewrite to use split(/\n/) which has the same effect but works on all our platforms. --- lib/puppet/interface/documentation.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/puppet/interface/documentation.rb') diff --git a/lib/puppet/interface/documentation.rb b/lib/puppet/interface/documentation.rb index 91db0e074..48e9a8b1a 100644 --- a/lib/puppet/interface/documentation.rb +++ b/lib/puppet/interface/documentation.rb @@ -6,7 +6,10 @@ class Puppet::Interface # We need to identify an indent: the minimum number of whitespace # characters at the start of any line in the text. - indent = text.each_line.map {|x| x.index(/[^\s]/) }.compact.min + # + # Using split rather than each_line is because the later only takes a + # block on Ruby 1.8.5 / Centos, and we support that. --daniel 2011-05-03 + indent = text.split(/\n/).map {|x| x.index(/[^\s]/) }.compact.min if indent > 0 then text.gsub!(/^[ \t\f]{0,#{indent}}/, '') -- cgit