lib/pdd.rb in pdd-0.1 vs lib/pdd.rb in pdd-0.2

- old
+ new

@@ -21,34 +21,62 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. require 'pdd/sources' require 'nokogiri' +require 'logger' # PDD main module. # Author:: Yegor Bugayenko (yegor@teamed.io) # Copyright:: Copyright (c) 2014 Yegor Bugayenko # License:: MIT module PDD + # If it breaks. + class Error < StandardError + end + + # If it violates XSD schema. + class SchemaError < Error + end + + # Get logger. + def self.log + @log ||= Logger.new(STDOUT) + end + + class << self + attr_writer :log + end + # Code base abstraction class Base # Ctor. - # +dir+:: Directory with source code - def initialize(dir) - @dir = dir + # +opts+:: Options + def initialize(opts) + @opts = opts + PDD.log = Logger.new(File::NULL) unless @opts.verbose? end # Generate XML. def xml - Nokogiri::XML::Builder.new do |xml| - xml << '<?xml-stylesheet type="text/xsl" href="puzzles.xsl"?>' - xml.puzzles do - Sources.new(@dir).fetch.each do |source| - source.puzzles.each { |puzzle| render puzzle, xml } + dir = @opts.source? ? @opts[:source] : Dir.pwd + PDD.log.info "reading #{dir}" + sanitize( + Nokogiri::XML::Builder.new do |xml| + xml << '<?xml-stylesheet type="text/xsl" href="puzzles.xsl"?>' + xml.puzzles do + Sources.new(dir).fetch.each do |source| + source.puzzles.each do |puzzle| + PDD.log.info "puzzle #{puzzle.props[:ticket]}:" \ + "#{puzzle.props[:estimate]}/#{puzzle.props[:role]}" \ + " at #{puzzle.props[:file]}" + render puzzle, xml + end + end end - end - end.to_xml + end.to_xml + ) end private def render(puzzle, xml) @@ -56,8 +84,18 @@ xml.puzzle do props.map do |k, v| xml.send(:"#{k}", v) end end + end + + def sanitize(xml) + xsd = Nokogiri::XML::Schema( + File.read(File.join(File.dirname(__FILE__), '../asserts/puzzles.xsd')) + ) + errors = xsd.validate(Nokogiri::XML(xml)).map { |error| error.message } + errors.each { |e| PDD.log.error e } + fail SchemaError, errors.join('; ') unless errors.empty? + xml end end end