class Courseware::Manager
Attributes
coursename[R]
errors[R]
prefix[R]
warnings[R]
Public Class Methods
new(config, repository=nil, generator=nil, printer=nil)
click to toggle source
# File lib/courseware/manager.rb, line 11 def initialize(config, repository=nil, generator=nil, printer=nil) @config = config @repository = repository || Courseware::Repository.new(config) @generator = generator || Courseware::Generator.new(config) @warnings = 0 @errors = 0 return if @config[:presfile] == :none showoff = Courseware.parse_showoff(@config[:presfile]) @coursename = showoff['name'] @prefix = showoff['name'].gsub(' ', '_') @password = showoff['key'] end
Public Instance Methods
lint()
click to toggle source
# File lib/courseware/manager/validators.rb, line 94 def lint courselevel! puts "Checking Markdown style:" style = File.join(@config[:cachedir], 'templates', 'markdown_style.rb') style = File.exists?(style) ? style : 'all' issues = 0 unless system('mdl', '--version') puts ' * Markdown linter not found: gem install mdl' puts @warnings += 1 return end Dir.glob('**/*.md') do |file| next if File.symlink? file next if File.directory? file next if file =~ /^_.*$|^[^\/]*$/ issues += 1 unless system('mdl', '-s', style, file) end if issues > 0 puts puts 'Rule explanations can be found at:' puts ' * https://github.com/mivok/markdownlint/blob/master/docs/RULES.md' puts @warnings += issues end end
missing()
click to toggle source
# File lib/courseware/manager/validators.rb, line 64 def missing courselevel! filename = @config[:presfile] content = JSON.parse(`showoff info -jf #{filename}`) sections = content['files'] images = content['images'] # This seems backwards, but we do it this way to get a case sensitive match on a case-insensitive-preserving filesystem # http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob -- Baby jesus is crying. Dir.glob("**{,/*/**}/*.md") do |file| sections.delete(file) end Dir.glob("_images/**{,/*/**}/*") do |file| images.delete(file) end puts "Missing slides:" unless sections.empty? sections.each do |slide| puts " * #{slide}" @errors += 1 end puts "Missing images:" unless images.empty? images.each do |slide| puts " * #{slide}" @errors += 1 end end
obsolete()
click to toggle source
# File lib/courseware/manager/validators.rb, line 3 def obsolete toplevel! allslides = Dir.glob('_content/**/*.md') allimages = Dir.glob('_images/**/*').reject {|path| path.include? '_images/src' } slides = [] images = [] Dir.glob('*').each do |path| next if path == 'spec' next if path.start_with? '_' next unless File.directory? path print "Validating #{path}." # stuff presentation local slides & images into the collections of available content allslides.concat Dir.glob("#{path}/**/*.md").reject {|file| file.include?('README.md') || file.include?('_notes') || File.dirname(file) == path } allimages.concat Dir.glob("#{path}/_images/**/*").reject {|file| file.include?('README.md') || file.include?('src/') || File.directory?(file) } Dir.chdir(path) do Dir.glob('*.json').each do |filename| # determine which slides and images are actually used content = JSON.parse(`showoff info -jf #{filename}`) lslides = content['files'].map do |slide| slide.start_with?('_') ? slide.sub('_shared', '_content') : "#{path}/#{slide}" end limages = content['images'].map do |image| image.start_with?('_images/shared') ? image.sub('_images/shared', '_images') : "#{path}/#{image}" end slides.concat(lslides) images.concat(limages) print '.' end puts end end # remove the intersection, and what's left over is obsolete obs_slides = (allslides - slides.uniq!) obs_images = (allimages - images.uniq!) puts "Obsolete slides:" unless obs_slides.empty? obs_slides.each do |slide| puts " * #{slide}" @warnings += 1 end puts "Obsolete images:" unless obs_images.empty? obs_images.each do |image| puts " * #{image}" @warnings += 1 end end
release(type)
click to toggle source
# File lib/courseware/manager.rb, line 50 def release(type) courselevel! master! clean! @repository.update version = Courseware.increment(@repository.current(@coursename), type) Courseware.bailout?("Building a release for #{@coursename} version #{version}.") raise "Release notes not updated for #{version}" if Dir.glob('Release-Notes*').select { |path| Courseware.grep(version, path) }.empty? Courseware.dialog('Last Repository Commit', @repository.last_commit) Courseware.bailout?('Abort now if the commit message displayed is not what you expected.') build_pdfs(version) point_of_no_return Courseware.bailout?('Please inspect the generated PDF files and abort if corrections must be made.', true) do @repository.discard(@config[:stylesheet]) end @repository.commit(@config[:stylesheet], "Updating for #{@coursename} release #{version}") @repository.tag("#{@prefix}-#{version}", "Releasing #{@coursename} version #{version}") # places the PDF files should be uploaded to @config[:release][:links].each do |link| system("open #{link}") end puts "Release shipped. Please upload PDF files to printer and break out the bubbly." end
releasenotes()
click to toggle source
# File lib/courseware/manager.rb, line 26 def releasenotes courselevel! master! clean! @repository.update current = @repository.current(@coursename) version = Courseware.increment(current) tag = "#{@coursename}-#{current}" notes = @repository.releasenotes(tag, version) # print to screen puts notes # and copy if on OS X begin IO.popen('pbcopy', 'w') { |f| f.puts notes } puts puts "{{ Copied to clipboard }}" rescue end end
wordcount(subject)
click to toggle source
# File lib/courseware/manager.rb, line 80 def wordcount(subject) $logger.debug "Counting words for #{subject}" opts = print_opts(@repository.current(prefix)) puts "Words longer than a single character:" Courseware::Printer.new(@config, opts) do |printer| subject.each do |item| printer.generate_html(item) doc = Nokogiri::HTML(File.read('static/index.html')) count = doc.css('body').text.split.select {|w| w.size > 1 }.count puts " * #{item}: #{count}" FileUtils.rm_rf('static') end end end
Private Instance Methods
build_pdfs(version)
click to toggle source
# File lib/courseware/manager.rb, line 118 def build_pdfs(version) @generator.styles(@coursename, version) Courseware::Printer.new(@config, print_opts(version)) do |printer| printer.print end system("open #{@config[:output]} >/dev/null 2>&1") end
clean!()
click to toggle source
# File lib/courseware/manager.rb, line 110 def clean! raise 'Your working directory has local modifications' unless @repository.clean? end
courselevel!()
click to toggle source
# File lib/courseware/manager.rb, line 102 def courselevel! raise 'This task must be run from within a course directory' unless @repository.courselevel? end
master!()
click to toggle source
# File lib/courseware/manager.rb, line 106 def master! raise 'You should release from the master branch' unless @repository.on_branch? 'master' end
point_of_no_return()
click to toggle source
# File lib/courseware/manager.rb, line 114 def point_of_no_return Courseware.dialog('Point of No Return', 'Proceeding past this point will result in permanent repository changes.') end
print_opts(version)
click to toggle source
# File lib/courseware/manager.rb, line 126 def print_opts(version) { :course => @coursename, :prefix => @prefix, :version => version, } end
toplevel!()
click to toggle source
# File lib/courseware/manager.rb, line 98 def toplevel! raise 'This task must be run from the repository root.' unless @repository.toplevel? end