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