# Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com> # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA require "optparse" require "etc" module ChupaText module Command class ChupaTextGenerateDecomposer class << self def run(*arguments) command = new command.run(*arguments) end end def initialize @name = nil @extensions = nil @mime_types = nil @author = guess_author @email = guess_email @license = lgplv2_1_or_later_license @parser = create_option_parser end def run(*arguments) begin @parser.parse!(arguments) rescue OptionParser::ParseError puts($!.message) return false end read_missing_parameters generate true end private def guess_author author = guess_author_from_password_entry author ||= ENV["USERNAME"] author end def guess_author_from_password_entry password_entry = find_password_entry return nil if password_entry.nil? author = password_entry.gecos.split(/,/).first.strip author = nil if author.empty? author end def find_password_entry Etc.getpwuid rescue ArgumentError nil end def guess_email ENV["EMAIL"] end def lgplv2_1_or_later_license "LGPLv2.1 or later" end def create_option_parser parser = OptionParser.new parser.version = VERSION parser.on("--name=NAME", "Decomposer name", "(e.g.: html)") do |name| @name = name end parser.on("--extensions=EXTENSION1,EXTENSION2,...", Array, "Target file extensions", "(e.g.: htm,html,xhtml)") do |extensions| @extensions = extensions end parser.on("--mime-types=TYPE1,TYPE2,...", Array, "Target MIME types", "(e.g.: text/html,application/xhtml+xml)") do |mime_types| @mime_types = mime_types end parser.on("--author=AUTHOR", "Author", "(e.g.: 'Your Name')", "(default: #{@author})") do |author| @author = author end parser.on("--email=EMAIL", "Author E-mail", "(e.g.: your@email.address)", "(default: #{@email})") do |email| @email = email end parser.on("--license=LICENSE", "License", "(e.g.: MIT)", "(default: #{@license})") do |license| @license = license end parser end def read_missing_parameters @name ||= read_parameter("--name") @extensions ||= read_parameter("--extensions") @mime_types ||= read_parameter("--mime-types") @author ||= read_parameter("--author") @email ||= read_parameter("--email") @license ||= read_parameter("--license") end def read_parameter(long_option_name) target_option = @parser.top.list.find do |option| option.long.include?(long_option_name) end prompt = target_option.desc.join(" ") + ": " print(prompt) target_option.conv.call($stdin.gets.chomp) end def gem_name "chupa-text-decomposer-#{@name}" end def generate generate_gemspec generate_gemfile generate_rakefile generate_license generate_decomposer generate_test generate_test_helper generate_test_runner end def generate_gemspec create_file("#{gem_name}.gemspec") do |file| file.puts(<<-GEMSPEC) # -*- mode: ruby; coding: utf-8 -*- Gem::Specification.new do |spec| spec.name = "#{gem_name}" spec.version = "1.0.0" spec.author = "#{@author}" spec.email = "#{@email}" spec.summary = "ChupaText decomposer for #{@mime_types.join(' ')}." spec.description = spec.summary spec.license = "#{@license}" spec.files = ["\#{spec.name}.gemspec"] spec.files += Dir.glob("{README*,LICENSE*,Rakefile,Gemfile}") spec.files += Dir.glob("lib/**/*.rb") spec.files += Dir.glob("test/fixture/**/*") spec.files += Dir.glob("test/**/*.rb") spec.add_runtime_dependency("chupa-text") spec.add_development_dependency("bundler") spec.add_development_dependency("rake") spec.add_development_dependency("test-unit") end GEMSPEC end end def generate_gemfile create_file("Gemfile") do |file| file.puts(<<-Gemfile) # -*- mode: ruby; coding: utf-8 -*- source "https://rubygems.org/" gemspec Gemfile end end def generate_rakefile create_file("Rakefile") do |file| file.puts(<<-RAKEFILE) # -*- mode: ruby; coding: utf-8 -*- require "bundler/gem_tasks" task :default => :test desc "Run tests" task :test do ruby("test/run-test.rb") end RAKEFILE end end def generate_license return unless @license == lgplv2_1_or_later_license base_dir = File.join(File.dirname(__FILE__), "..", "..", "..") lgpl2_1_license_file = File.join(base_dir, "LICENSE.txt") create_file("LICENSE.txt") do |file| file.puts(File.read(lgpl2_1_license_file)) end end def generate_decomposer create_file("lib/chupa-text/decomposers/#{@name}.rb") do |file| file.puts(<<-RUBY) module ChupaText module Decomposers class #{@name.capitalize} < Decomposer def target?(data) #{@extensions.inspect}.include?(data.extension) or #{@mime_types.inspect}.include?(data.mime_type) end def decompose(data) raise NotImplementedError, "\#{self.class}\#\#{__method__} isn't implemented yet." text = "IMPLEMENTED ME" text_data = TextData.new(text) yield(text_data) end end end end RUBY end end def generate_test create_file("test/test-#{@name}.rb") do |file| file.puts(<<-RUBY) class Test#{@name.capitalize} < Test::Unit::TestCase include Helper def setup @decomposer = ChupaText::Decomposers::#{@name.capitalize}.new({}) end sub_test_case("decompose") do def decompose(input_body) data = ChupaText::Data.new data.mime_type = #{@mime_types.first.dump} data.body = input_body decomposed = [] @decomposer.decompose(data) do |decomposed_data| decomposed << decomposed_data end decomposed end def test_body input_body = "TODO (input)" expected_text = "TODO (extracted)" assert_equal([expected_text], decompose(input_body).collect(&:body)) end end end RUBY end end def generate_test_helper create_file("test/helper.rb") do |file| file.puts(<<-RUBY) module Helper def fixture_path(*components) base_dir = File.expand_path(File.dirname(__FILE__)) File.join(base_dir, "fixture", *components) end end RUBY end end def generate_test_runner create_file("test/run-test.rb") do |file| file.puts(<<-RUBY) #!/usr/bin/env ruby require "bundler/setup" require "test-unit" require "chupa-text" ChupaText::Decomposers.load require_relative "helper" exit(Test::Unit::AutoRunner.run(true)) RUBY end end def create_file(path, &block) real_path = File.join(gem_name, path) directory = File.dirname(real_path) unless File.exist?(directory) puts("Creating directory: #{directory}") FileUtils.mkdir_p(directory) end puts("Creating file: #{real_path}") File.open(real_path, "w", &block) end end end end