saag 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +24 -0
- data/README.rdoc +70 -0
- data/TODO +4 -0
- data/VERSION +1 -0
- data/bin/saag +17 -0
- data/lib/saag.rb +453 -0
- data/spec/saag_spec.rb +10 -0
- data/spec/spec_helper.rb +11 -0
- metadata +95 -0
    
        data/ChangeLog
    ADDED
    
    | @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            2009-08-08  sugamasao@gmail.com
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            	* Version 0.3.5 : add option "-x"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            2009-07-06  sugamasao@gmail.com
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            	* Version 0.3.4 : modified ends at the [Sass Syntax Error] or [File I/O
         | 
| 8 | 
            +
            	Error]. endless loop for file search.
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            2009-07-05  sugamasao@gmail.com
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            	* Version 0.3.2 : moved README to README.rdoc
         | 
| 13 | 
            +
            	* Version 0.3.0 : added to rdoc comments
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            2009-06-25  sugamasao@gmail.com
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            	* Version 0.2.4 : change to this file.
         | 
| 18 | 
            +
            	* Version 0.2.3 : change to Version Number
         | 
| 19 | 
            +
            	* Version 0.2.2 : Bug Fix to issue 1
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            2009-06-21  sugamasao@gmail.com
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            	* Version 0.1.0 : 1st Release
         | 
| 24 | 
            +
             | 
    
        data/README.rdoc
    ADDED
    
    | @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            = saag
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            == Description
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            SASS automatic monitor and generate CSS file.
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            SASS ファイルを監視し、変更があれば即座に CSS ファイルへ変換します。
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            手動で以下のコマンドを行うのと同等です。
         | 
| 10 | 
            +
              % sass hoge.sass hoge.css 
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            == Gem Installation
         | 
| 13 | 
            +
             | 
| 14 | 
            +
             gem install sugamasao-saag --source http://gems.github.com
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            == Features/Problems
         | 
| 17 | 
            +
             
         | 
| 18 | 
            +
            * Ruby 1.8.6 及び、 1.8.7 で、動作確認を行っています
         | 
| 19 | 
            +
            * Windows XP 及び、 Mac OSX で動作確認を行っています
         | 
| 20 | 
            +
            * 事前にSass(HAML)のインストールが必要になります(未インストール時は本gemと一緒にインストールされます)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            == Synopsis
         | 
| 23 | 
            +
             
         | 
| 24 | 
            +
            使用例:
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            === オプション無し
         | 
| 27 | 
            +
              % saag
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            引数を使用しない場合、コマンド実行者のカレントディレクトリを基点とし、*.sass ファイルを探し、対象ファイルとします。
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            また、出力される CSS ファイルは sass ファイルと同じ階層になります。
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            (Version 0.3.5以降) saag を実行するよりも以前のタイムスタンプのファイルは対象ファイルに含まれません 。
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            古いタイムスタンプも変換したい場合は -x オプションを使用してください
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            === オプション -i
         | 
| 38 | 
            +
             % saag -i /path/to/sass
         | 
| 39 | 
            +
             | 
| 40 | 
            +
            -i オプションを使用することで、sass ファイルのあるディレクトリ(ファイル名でも可)を指定する事が可能です。
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            出力先は、変更対象の sass ファイルのあるディレクトリと同じディレクトリになります。
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            === オプション -o
         | 
| 45 | 
            +
             % saag -i /path/to/sass -o /path/to/css
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            -o オプションを使用することで、css の出力先ファイルを指定することができます。-o オプション単独での使用も可能です。
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            出力先ファイルのディレクトリ構成は、-i オプションに依存します。
         | 
| 50 | 
            +
             | 
| 51 | 
            +
            上記のオプションを指定、/path/to/sass/sub_dir/hoge.sass があった場合、出力先ディレクトリは
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            /path/to/css/sub_dir/hoge.css となります。
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            -o 単独で使用した場合、実行時のカレントディレクトリ配下から *.sass ファイルを探し、 -o で指定したディレクトリに *.css を出力します。
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            === オプション -x
         | 
| 58 | 
            +
             % saag -x
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            -x オプションを使用する事で、本プロセスを起動するよりも前に編集された sass ファイルを変更対象に含めます。
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            逆に言うと、 -x を使用しない場合は、saag 起動後に編集したファイルしか変更対象になりません。
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            このオプションは Version 0.3.5 以降で実装されました。
         | 
| 65 | 
            +
             | 
| 66 | 
            +
            == Copyright
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            Author:: sugamasao <sugamasao@gmail.com>
         | 
| 69 | 
            +
            License:: Ruby's
         | 
| 70 | 
            +
             | 
    
        data/VERSION
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            0.3.5
         | 
    
        data/bin/saag
    ADDED
    
    | @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            # $Id$
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # lib のパスを追加しておく
         | 
| 5 | 
            +
            $LOAD_PATH.unshift(File.expand_path("#{File.dirname(__FILE__)}/../lib/"))
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            begin
         | 
| 8 | 
            +
              require 'saag'
         | 
| 9 | 
            +
              require 'sass'
         | 
| 10 | 
            +
            rescue LoadError
         | 
| 11 | 
            +
              require 'rubygems'
         | 
| 12 | 
            +
              require 'saag'
         | 
| 13 | 
            +
              require 'sass'
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            Saag.new(ARGV).run
         | 
| 17 | 
            +
             | 
    
        data/lib/saag.rb
    ADDED
    
    | @@ -0,0 +1,453 @@ | |
| 1 | 
            +
            require 'optparse'
         | 
| 2 | 
            +
            require 'logger'
         | 
| 3 | 
            +
            require 'pp'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            #
         | 
| 6 | 
            +
            # Sass 補助ツール、saag クラスです
         | 
| 7 | 
            +
            #
         | 
| 8 | 
            +
            class Saag
         | 
| 9 | 
            +
              SASS_EXT = '.sass'
         | 
| 10 | 
            +
              CSS_EXT  = '.css'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              #== saag Constructor
         | 
| 13 | 
            +
              # 引数の解析、及び初期値の設定を行います
         | 
| 14 | 
            +
              #
         | 
| 15 | 
            +
              #=== 引数
         | 
| 16 | 
            +
              # 引数となる配列
         | 
| 17 | 
            +
              #
         | 
| 18 | 
            +
              #=== 例外
         | 
| 19 | 
            +
              # 特になし
         | 
| 20 | 
            +
              #
         | 
| 21 | 
            +
              def initialize(argv = [])
         | 
| 22 | 
            +
                # クラス共通の値
         | 
| 23 | 
            +
                @app_name = self.class
         | 
| 24 | 
            +
                begin
         | 
| 25 | 
            +
                  @version  = File.read("#{File.dirname(__FILE__)}/../VERSION").chomp
         | 
| 26 | 
            +
                rescue => e
         | 
| 27 | 
            +
                  @version = "0.0.0"
         | 
| 28 | 
            +
                end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                # 引数オプション格納用
         | 
| 31 | 
            +
                @conf = {}
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # シグナル受信用フラグ(シグナルを受けたら true にして終了する)
         | 
| 34 | 
            +
                @exit = false
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                # Loger の設定
         | 
| 37 | 
            +
                @logger = Logger.new(STDOUT)
         | 
| 38 | 
            +
                @logger.level = Logger::INFO # default Log Level
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                begin
         | 
| 41 | 
            +
                  OptionParser.new do |opt|
         | 
| 42 | 
            +
                    opt.on('-i', '--input_path=VAL',  'input file path(directory or filename)') do |v|
         | 
| 43 | 
            +
                      @conf[:in_path] = set_dir_path(v)
         | 
| 44 | 
            +
                    end
         | 
| 45 | 
            +
                    opt.on('-o', '--output_path=VAL', 'generated css file output path') do |v|
         | 
| 46 | 
            +
                      @conf[:out_path] = set_dir_path(v)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                    opt.on('-r', '--render_opt=VAL',  'sass render option [nested or expanded or compact or compressed]') do |v|
         | 
| 49 | 
            +
                      @conf[:render_opt] = set_render_opt(v)
         | 
| 50 | 
            +
                    end
         | 
| 51 | 
            +
                    opt.on('-v', '--version',         'show version' ) do
         | 
| 52 | 
            +
                      # TODO stderror print.
         | 
| 53 | 
            +
                      puts "#{@app_name} #{@version}";
         | 
| 54 | 
            +
                      exit 1
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                    opt.on('-d', '--debug',           'log level to debug') do |v|
         | 
| 57 | 
            +
                      @conf[:debug] = v
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                    opt.on('-x', '--exclude',         'exclude older Sass Script(target to "Time.now < Sass Script Modified Time")') do
         | 
| 60 | 
            +
                      @conf[:exclude] = true
         | 
| 61 | 
            +
                    end
         | 
| 62 | 
            +
                  end.parse!(argv)
         | 
| 63 | 
            +
                rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
         | 
| 64 | 
            +
                  @logger.error('invalid args...! looks for "-h" option')
         | 
| 65 | 
            +
                  exit 1
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                @logger.info("sass file watching start... [#{@app_name} = #{@version}]")
         | 
| 69 | 
            +
                @logger.level = Logger::DEBUG if @conf[:debug]
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                @logger.debug("args input_path  => #{@conf[:in_path]}")
         | 
| 72 | 
            +
                @logger.debug("args output_path => #{@conf[:out_path]}")
         | 
| 73 | 
            +
                @logger.debug("args render_opt  => #{@conf[:render_opt]}")
         | 
| 74 | 
            +
                @logger.debug("args -x?         => #{@conf[:exclude]}")
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                set_default_conf()
         | 
| 77 | 
            +
                set_signal()
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                @logger.info("watching directory => #{@conf[:in_path]}")
         | 
| 80 | 
            +
                @logger.info("output   directory => #{@conf[:out_path]}")
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              #== saag#run
         | 
| 84 | 
            +
              # saag によるファイル監視を実行します
         | 
| 85 | 
            +
              #
         | 
| 86 | 
            +
              #=== 引数
         | 
| 87 | 
            +
              # なし
         | 
| 88 | 
            +
              #
         | 
| 89 | 
            +
              #=== 戻り値
         | 
| 90 | 
            +
              # なし
         | 
| 91 | 
            +
              #
         | 
| 92 | 
            +
              #=== 例外
         | 
| 93 | 
            +
              # なし
         | 
| 94 | 
            +
              #
         | 
| 95 | 
            +
              def run
         | 
| 96 | 
            +
                old_list = []
         | 
| 97 | 
            +
                # メインループ
         | 
| 98 | 
            +
                begin
         | 
| 99 | 
            +
                  loop do 
         | 
| 100 | 
            +
                    old_list = main_loop(old_list)
         | 
| 101 | 
            +
                    break if @exit # SIGNAL を受けたりすると true
         | 
| 102 | 
            +
                    sleep 1
         | 
| 103 | 
            +
                  end
         | 
| 104 | 
            +
                rescue => e
         | 
| 105 | 
            +
                  @logger.error("FATLE Error! [#{e.message}]")
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                @logger.info("sass file watching exit...")
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              ############################
         | 
| 112 | 
            +
              # private methods
         | 
| 113 | 
            +
              ############################
         | 
| 114 | 
            +
              private
         | 
| 115 | 
            +
             | 
| 116 | 
            +
              #== saag#main_loop
         | 
| 117 | 
            +
              # saag の監視処理のメイン処理です。
         | 
| 118 | 
            +
              # このメソッドを繰り返し呼ぶ事で監視処理を実施しています。
         | 
| 119 | 
            +
              #
         | 
| 120 | 
            +
              #=== 引数
         | 
| 121 | 
            +
              # _old_list_::  Array オブジェクト 前回の main_loop メソッドで取得したファイルリストの一覧。
         | 
| 122 | 
            +
              #
         | 
| 123 | 
            +
              #=== 戻り値
         | 
| 124 | 
            +
              # Array:: main_loop内で取得したファイルリストの配列。
         | 
| 125 | 
            +
              #
         | 
| 126 | 
            +
              #=== 例外
         | 
| 127 | 
            +
              # なし
         | 
| 128 | 
            +
              # 
         | 
| 129 | 
            +
              def main_loop(old_list)
         | 
| 130 | 
            +
                return nil if @exit # SIGNAL を受けていたら処理を抜ける
         | 
| 131 | 
            +
                new_list = get_file_list(@conf[:in_path])
         | 
| 132 | 
            +
                
         | 
| 133 | 
            +
                return nil if @exit # SIGNAL を受けていたら処理を抜ける
         | 
| 134 | 
            +
                file_list = check_file_list(old_list, new_list)
         | 
| 135 | 
            +
             | 
| 136 | 
            +
                return nil if @exit # SIGNAL を受けていたら処理を抜ける
         | 
| 137 | 
            +
                file_list.each do |sass_file|
         | 
| 138 | 
            +
                  if sass_file[:change]
         | 
| 139 | 
            +
                    @logger.info("change file found. => #{sass_file[:path]}")
         | 
| 140 | 
            +
                    begin
         | 
| 141 | 
            +
                      # render to sass text
         | 
| 142 | 
            +
                      css_text = Sass::Engine.new(File.read(sass_file[:path]), {:style => @conf[:render_opt] }).render
         | 
| 143 | 
            +
                      write_css_file(sass_file, css_text)
         | 
| 144 | 
            +
                    rescue Sass::SyntaxError => e
         | 
| 145 | 
            +
                      @logger.error("Sass Syntax Error! file => [#{sass_file[:path]}] error message => [#{e.message}]")
         | 
| 146 | 
            +
                      new_list = set_default_time(new_list, sass_file[:path])
         | 
| 147 | 
            +
                    rescue SystemCallError => e
         | 
| 148 | 
            +
                      @logger.error("File I/O Error! file => [#{sass_file[:path]}] error message => [#{e.message}]")
         | 
| 149 | 
            +
                      new_list = set_default_time(new_list, sass_file[:path])
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                return new_list
         | 
| 155 | 
            +
              end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              #== saag#set_dir_path
         | 
| 158 | 
            +
              # 絶対パスにし、ディレクトリの場合は最後尾にスラッシュを付ける
         | 
| 159 | 
            +
              #
         | 
| 160 | 
            +
              #=== 引数
         | 
| 161 | 
            +
              # _path_:: ファイルパスの記載された String オブジェクト
         | 
| 162 | 
            +
              #
         | 
| 163 | 
            +
              #=== 戻り値
         | 
| 164 | 
            +
              # String:: ディレクトリであれば末尾に '/' を付加した、絶対パスのファイル名
         | 
| 165 | 
            +
              #
         | 
| 166 | 
            +
              #=== 例外
         | 
| 167 | 
            +
              # なし
         | 
| 168 | 
            +
              #
         | 
| 169 | 
            +
              def set_dir_path(path)
         | 
| 170 | 
            +
                path =  File.expand_path(path)
         | 
| 171 | 
            +
                path = path + '/' if File.directory?(path)
         | 
| 172 | 
            +
                return path
         | 
| 173 | 
            +
              end
         | 
| 174 | 
            +
             | 
| 175 | 
            +
              #== saag#set_signal
         | 
| 176 | 
            +
              # シグナルハンドラの設定
         | 
| 177 | 
            +
              # シグナルを受けると即死するのではなく、キリの良いところで終了するよう、
         | 
| 178 | 
            +
              # 終了フラグを true にするだけの処理を行う。
         | 
| 179 | 
            +
              #
         | 
| 180 | 
            +
              #=== 引数
         | 
| 181 | 
            +
              # なし
         | 
| 182 | 
            +
              #
         | 
| 183 | 
            +
              #=== 戻り値
         | 
| 184 | 
            +
              # なし
         | 
| 185 | 
            +
              #
         | 
| 186 | 
            +
              #=== 例外
         | 
| 187 | 
            +
              # なし
         | 
| 188 | 
            +
              # 
         | 
| 189 | 
            +
              def set_signal
         | 
| 190 | 
            +
                begin
         | 
| 191 | 
            +
                  Signal.trap(:INT){
         | 
| 192 | 
            +
                    @logger.debug("Signal Trapping [:INT]")
         | 
| 193 | 
            +
                    @exit = true
         | 
| 194 | 
            +
                  }
         | 
| 195 | 
            +
                rescue ArgumentError => e
         | 
| 196 | 
            +
                  @logger.debug("Signal Setting Error[#{e.message}]")
         | 
| 197 | 
            +
                end
         | 
| 198 | 
            +
             | 
| 199 | 
            +
                begin
         | 
| 200 | 
            +
                  Signal.trap(:TERM){
         | 
| 201 | 
            +
                    @logger.debug("Signal Trapping [:TERM]")
         | 
| 202 | 
            +
                    @exit = true
         | 
| 203 | 
            +
                  }
         | 
| 204 | 
            +
                rescue ArgumentError => e
         | 
| 205 | 
            +
                  @logger.debug("Signal Setting Error[#{e.message}]")
         | 
| 206 | 
            +
                end
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                begin
         | 
| 209 | 
            +
                  Signal.trap(:HUP){
         | 
| 210 | 
            +
                    @logger.debug("Signal Trapping [:HUP]")
         | 
| 211 | 
            +
                    @exit = true
         | 
| 212 | 
            +
                  }
         | 
| 213 | 
            +
                rescue ArgumentError => e
         | 
| 214 | 
            +
                  @logger.debug("Signal Setting Error[#{e.message}]")
         | 
| 215 | 
            +
                end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                begin
         | 
| 218 | 
            +
                  Signal.trap(:BREAK){
         | 
| 219 | 
            +
                    @logger.debug("Signal Trapping [:BREAK]")
         | 
| 220 | 
            +
                    @exit = true
         | 
| 221 | 
            +
                  }
         | 
| 222 | 
            +
                rescue ArgumentError => e
         | 
| 223 | 
            +
                  @logger.debug("Signal Setting Error[#{e.message}]")
         | 
| 224 | 
            +
                end
         | 
| 225 | 
            +
              end
         | 
| 226 | 
            +
             | 
| 227 | 
            +
              #== saag#set_render_opt
         | 
| 228 | 
            +
              # sass 実行時のオプション設定用メソッド
         | 
| 229 | 
            +
              # オプションで値が渡されていれば その値を、そうでなければでフォルト値のnestedを使う。
         | 
| 230 | 
            +
              #
         | 
| 231 | 
            +
              #=== 引数
         | 
| 232 | 
            +
              # _input_opt_:: 引数の -r で入力された文字列
         | 
| 233 | 
            +
              #
         | 
| 234 | 
            +
              #=== 戻り値
         | 
| 235 | 
            +
              # Symbol:: 入力された文字列に対応した Symbol
         | 
| 236 | 
            +
              #
         | 
| 237 | 
            +
              #=== 例外
         | 
| 238 | 
            +
              # なし
         | 
| 239 | 
            +
              #
         | 
| 240 | 
            +
              def set_render_opt(input_opt)
         | 
| 241 | 
            +
                opt = ""
         | 
| 242 | 
            +
                case input_opt.downcase
         | 
| 243 | 
            +
                when 'nested'
         | 
| 244 | 
            +
                  opt = :nested
         | 
| 245 | 
            +
                when 'expanded'
         | 
| 246 | 
            +
                  opt = :expanded
         | 
| 247 | 
            +
                when 'compact'
         | 
| 248 | 
            +
                  opt = :compact
         | 
| 249 | 
            +
                when 'compressed'
         | 
| 250 | 
            +
                  opt = :compressed
         | 
| 251 | 
            +
                else
         | 
| 252 | 
            +
                  opt = :nested
         | 
| 253 | 
            +
                end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                return opt
         | 
| 256 | 
            +
              end
         | 
| 257 | 
            +
             | 
| 258 | 
            +
              #== saag#set_default_conf
         | 
| 259 | 
            +
              # sass 実行時のオプション設定用メソッド。
         | 
| 260 | 
            +
              # 省略時の入力パスと出力パスを設定する。
         | 
| 261 | 
            +
              # ディレクトリの場合は '/' を付加する。
         | 
| 262 | 
            +
              #
         | 
| 263 | 
            +
              #=== 引数
         | 
| 264 | 
            +
              # なし
         | 
| 265 | 
            +
              #
         | 
| 266 | 
            +
              #=== 戻り値
         | 
| 267 | 
            +
              # なし
         | 
| 268 | 
            +
              #
         | 
| 269 | 
            +
              #=== 例外
         | 
| 270 | 
            +
              # なし
         | 
| 271 | 
            +
              # 
         | 
| 272 | 
            +
              def set_default_conf()
         | 
| 273 | 
            +
                unless @conf[:in_path]
         | 
| 274 | 
            +
                  @conf[:in_path] = Dir.pwd + '/'
         | 
| 275 | 
            +
                end
         | 
| 276 | 
            +
                unless @conf[:out_path]
         | 
| 277 | 
            +
                  if File.directory?(@conf[:in_path])
         | 
| 278 | 
            +
                    @conf[:out_path] = @conf[:in_path]
         | 
| 279 | 
            +
                  else
         | 
| 280 | 
            +
                    @conf[:out_path] =File.dirname( @conf[:in_path]) + '/'
         | 
| 281 | 
            +
                  end
         | 
| 282 | 
            +
                end
         | 
| 283 | 
            +
                unless @conf[:render_opt]
         | 
| 284 | 
            +
                  @conf[:render_opt] = :nested
         | 
| 285 | 
            +
                end
         | 
| 286 | 
            +
             | 
| 287 | 
            +
                # プロセス開始時刻
         | 
| 288 | 
            +
                @conf[:start_time] = Time.now
         | 
| 289 | 
            +
              end
         | 
| 290 | 
            +
             | 
| 291 | 
            +
              #== saag#get_file_list
         | 
| 292 | 
            +
              # ファイルのパスと時刻のリストを作成する
         | 
| 293 | 
            +
              #
         | 
| 294 | 
            +
              #=== 引数
         | 
| 295 | 
            +
              # _in_path_:: 引数の -i で入力されたパス
         | 
| 296 | 
            +
              #
         | 
| 297 | 
            +
              #=== 戻り値
         | 
| 298 | 
            +
              # Array:: 時刻とパスを保持したファイルリスト。
         | 
| 299 | 
            +
              #
         | 
| 300 | 
            +
              #=== 例外
         | 
| 301 | 
            +
              # なし
         | 
| 302 | 
            +
              #
         | 
| 303 | 
            +
              def get_file_list(in_path)
         | 
| 304 | 
            +
                list = []
         | 
| 305 | 
            +
                if File.file?(in_path)
         | 
| 306 | 
            +
                    list << create_file_data(in_path)
         | 
| 307 | 
            +
                else 
         | 
| 308 | 
            +
                  list = Dir.glob("#{in_path}**/*#{SASS_EXT}").map do |m|
         | 
| 309 | 
            +
                    if File.file?(m)
         | 
| 310 | 
            +
                      create_file_data(m)
         | 
| 311 | 
            +
                    end
         | 
| 312 | 
            +
                  end
         | 
| 313 | 
            +
                end
         | 
| 314 | 
            +
                
         | 
| 315 | 
            +
                return list.compact
         | 
| 316 | 
            +
              end
         | 
| 317 | 
            +
             | 
| 318 | 
            +
              #== saag#create_file_data
         | 
| 319 | 
            +
              # ファイルパスと時刻等を保持した HASH を生成する。
         | 
| 320 | 
            +
              # 生成する HASH の内容は以下の通り
         | 
| 321 | 
            +
              # * :path => ファイルの絶対パス
         | 
| 322 | 
            +
              # * :sub_path => 入力時に指定されたディレクトリ以降からのファイルパス
         | 
| 323 | 
            +
              # * :time => 対象ファイルの mtime
         | 
| 324 | 
            +
              # * :change => 前回との変更があったか?を現すフラグ(この時点では全て true)
         | 
| 325 | 
            +
              #
         | 
| 326 | 
            +
              #=== 引数
         | 
| 327 | 
            +
              # _path_:: ファイルパス
         | 
| 328 | 
            +
              #
         | 
| 329 | 
            +
              #=== 戻り値
         | 
| 330 | 
            +
              # Hash:: 時刻とパス等を保持した Hash データ。
         | 
| 331 | 
            +
              #
         | 
| 332 | 
            +
              #=== 例外
         | 
| 333 | 
            +
              # なし
         | 
| 334 | 
            +
              # 
         | 
| 335 | 
            +
              def create_file_data(path)
         | 
| 336 | 
            +
                # 入力パスと実ファイルのパスの差分を出す(この差分が出力ディレクトリの連結パスとなる)
         | 
| 337 | 
            +
                sub_path = ""
         | 
| 338 | 
            +
                @logger.debug("create_file_data@path    => [#{path}]")
         | 
| 339 | 
            +
                @logger.debug("create_file_data@in_path => [#{@conf[:in_path]}]")
         | 
| 340 | 
            +
                if path =~ /#{@conf[:in_path]}(.+)/
         | 
| 341 | 
            +
                  sub_path = $1
         | 
| 342 | 
            +
                end
         | 
| 343 | 
            +
             | 
| 344 | 
            +
                change = true
         | 
| 345 | 
            +
                file_time = File.mtime(path)
         | 
| 346 | 
            +
                # exclude オプションが無い(デフォルト時)はプロセスのスタート時刻よりも古い時刻のファイルは false にする
         | 
| 347 | 
            +
                unless @conf[:exclude]
         | 
| 348 | 
            +
                  @logger.debug("no exclude option.")
         | 
| 349 | 
            +
                  change = false if(file_time < @conf[:start_time]) 
         | 
| 350 | 
            +
                end
         | 
| 351 | 
            +
             | 
| 352 | 
            +
                data = {
         | 
| 353 | 
            +
                  :path => path, 
         | 
| 354 | 
            +
                  :sub_path => sub_path, 
         | 
| 355 | 
            +
                  :time => file_time, 
         | 
| 356 | 
            +
                  :change => change
         | 
| 357 | 
            +
                }
         | 
| 358 | 
            +
                @logger.debug("create_file_data@sub_path => #{sub_path}")
         | 
| 359 | 
            +
                return data
         | 
| 360 | 
            +
              end
         | 
| 361 | 
            +
             | 
| 362 | 
            +
              #== saag#check_file_list
         | 
| 363 | 
            +
              # 前回走査したファイルリストと、今回走査したファイルリストにおいて、
         | 
| 364 | 
            +
              # ファイルの更新や追加があったリストの :change を true にし、そうでなければ false にする。
         | 
| 365 | 
            +
              #
         | 
| 366 | 
            +
              #=== 引数
         | 
| 367 | 
            +
              # _old_list_:: 前回のループで取得したファイルリストの Array
         | 
| 368 | 
            +
              # _new_list_:: 今回のループで取得したファイルリストの Array
         | 
| 369 | 
            +
              #
         | 
| 370 | 
            +
              #=== 戻り値
         | 
| 371 | 
            +
              # Array:: change フラグの更新が終わった new_list
         | 
| 372 | 
            +
              #
         | 
| 373 | 
            +
              #=== 例外
         | 
| 374 | 
            +
              # なし
         | 
| 375 | 
            +
              #
         | 
| 376 | 
            +
              def check_file_list(old_list, new_list)
         | 
| 377 | 
            +
                return new_list if old_list.empty?
         | 
| 378 | 
            +
             | 
| 379 | 
            +
                new_list.each do |new|
         | 
| 380 | 
            +
                  old_list.each do |old|
         | 
| 381 | 
            +
                    if(new[:path] == old[:path]) # 前回と今回で同じファイルがあれば、時刻の比較を行う
         | 
| 382 | 
            +
                      if(new[:time] > old[:time]) # 時刻が更新されていれば true
         | 
| 383 | 
            +
                        new[:change] = true
         | 
| 384 | 
            +
                      else
         | 
| 385 | 
            +
                        new[:change] = false
         | 
| 386 | 
            +
                      end
         | 
| 387 | 
            +
                    end
         | 
| 388 | 
            +
                  end
         | 
| 389 | 
            +
                end
         | 
| 390 | 
            +
             | 
| 391 | 
            +
                return new_list
         | 
| 392 | 
            +
              end
         | 
| 393 | 
            +
             | 
| 394 | 
            +
              #== saag#write_css_file
         | 
| 395 | 
            +
              # 変換された CSS ファイルを出力する
         | 
| 396 | 
            +
              #
         | 
| 397 | 
            +
              #=== 引数
         | 
| 398 | 
            +
              # _sass_file:: 変換対象のファイルの Hash
         | 
| 399 | 
            +
              # _css_text_:: 変換された CSS テキストの String
         | 
| 400 | 
            +
              #
         | 
| 401 | 
            +
              #=== 戻り値
         | 
| 402 | 
            +
              # なし
         | 
| 403 | 
            +
              #
         | 
| 404 | 
            +
              #=== 例外
         | 
| 405 | 
            +
              # SystemCallError:: ファイル出力時の例外時に出力
         | 
| 406 | 
            +
              # 
         | 
| 407 | 
            +
              def write_css_file(sass_file, css_text)
         | 
| 408 | 
            +
                @logger.debug("@conf[:out_path] = #{@conf[:out_path]}, sass_file[:sub_path] = #{sass_file[:sub_path]}")
         | 
| 409 | 
            +
                out_dir = ""
         | 
| 410 | 
            +
                if sass_file[:sub_path].empty?
         | 
| 411 | 
            +
                  out_dir      = @conf[:out_path]
         | 
| 412 | 
            +
                else
         | 
| 413 | 
            +
                  out_dir      = File.dirname(@conf[:out_path] + sass_file[:sub_path]) + '/'
         | 
| 414 | 
            +
                end
         | 
| 415 | 
            +
                filename     = out_dir + File.basename(sass_file[:path], SASS_EXT) + CSS_EXT
         | 
| 416 | 
            +
                @logger.debug("out_dir => #{out_dir}")
         | 
| 417 | 
            +
             | 
| 418 | 
            +
                # ディレクトリが無ければ作成する
         | 
| 419 | 
            +
                unless File.directory?(out_dir)
         | 
| 420 | 
            +
                  FileUtils.mkdir_p(out_dir)
         | 
| 421 | 
            +
                  @logger.info("create output directory => #{out_dir}")
         | 
| 422 | 
            +
                end
         | 
| 423 | 
            +
                
         | 
| 424 | 
            +
                File.open(filename, 'w') do |f|
         | 
| 425 | 
            +
                  f.puts(css_text)
         | 
| 426 | 
            +
                end
         | 
| 427 | 
            +
                @logger.info("generate css file => #{filename}")
         | 
| 428 | 
            +
              end
         | 
| 429 | 
            +
             | 
| 430 | 
            +
              #== saag#set_default_time
         | 
| 431 | 
            +
              # 指定された path の :time 値をあり得ない値にして更新する。
         | 
| 432 | 
            +
              # 更新に失敗したデータは時刻を現在より過去のものにして、次回のループで変換対象となるようにする。
         | 
| 433 | 
            +
              #
         | 
| 434 | 
            +
              #=== 引数
         | 
| 435 | 
            +
              # _list_:: 走査対象のファイルリスト
         | 
| 436 | 
            +
              # _path_:: 更新に失敗したファイルのパス
         | 
| 437 | 
            +
              #
         | 
| 438 | 
            +
              #=== 戻り値
         | 
| 439 | 
            +
              # Array:: :time の更新が終わった new_list
         | 
| 440 | 
            +
              #
         | 
| 441 | 
            +
              #=== 例外
         | 
| 442 | 
            +
              # なし
         | 
| 443 | 
            +
              #
         | 
| 444 | 
            +
              def set_default_time(file_list, path)
         | 
| 445 | 
            +
                file_list.map do |list|
         | 
| 446 | 
            +
                  if list[:path] == path
         | 
| 447 | 
            +
                    list[:time] = Time.at(0) # 1970/1/1
         | 
| 448 | 
            +
                  end
         | 
| 449 | 
            +
                  list
         | 
| 450 | 
            +
                end
         | 
| 451 | 
            +
              end
         | 
| 452 | 
            +
            end
         | 
| 453 | 
            +
             | 
    
        data/spec/saag_spec.rb
    ADDED
    
    | @@ -0,0 +1,10 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
             | 
| 4 | 
            +
            class Saag
         | 
| 5 | 
            +
              # private methods to public
         | 
| 6 | 
            +
              public :main_loop, :set_dir_path, :set_signal, :set_render_opt, :set_default_conf, :get_file_list, :create_file_data, :write_css_file, :check_file_list, :set_default_time
         | 
| 7 | 
            +
            end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            describe Saag, "test" do
         | 
| 10 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | @@ -0,0 +1,95 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: saag
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              prerelease: false
         | 
| 5 | 
            +
              segments: 
         | 
| 6 | 
            +
              - 0
         | 
| 7 | 
            +
              - 3
         | 
| 8 | 
            +
              - 5
         | 
| 9 | 
            +
              version: 0.3.5
         | 
| 10 | 
            +
            platform: ruby
         | 
| 11 | 
            +
            authors: 
         | 
| 12 | 
            +
            - sugamasao
         | 
| 13 | 
            +
            autorequire: 
         | 
| 14 | 
            +
            bindir: bin
         | 
| 15 | 
            +
            cert_chain: []
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            date: 2009-08-09 00:00:00 +09:00
         | 
| 18 | 
            +
            default_executable: 
         | 
| 19 | 
            +
            - saag
         | 
| 20 | 
            +
            dependencies: 
         | 
| 21 | 
            +
            - !ruby/object:Gem::Dependency 
         | 
| 22 | 
            +
              name: haml
         | 
| 23 | 
            +
              prerelease: false
         | 
| 24 | 
            +
              requirement: &id001 !ruby/object:Gem::Requirement 
         | 
| 25 | 
            +
                requirements: 
         | 
| 26 | 
            +
                - - ">="
         | 
| 27 | 
            +
                  - !ruby/object:Gem::Version 
         | 
| 28 | 
            +
                    segments: 
         | 
| 29 | 
            +
                    - 0
         | 
| 30 | 
            +
                    version: "0"
         | 
| 31 | 
            +
              type: :runtime
         | 
| 32 | 
            +
              version_requirements: *id001
         | 
| 33 | 
            +
            description: SAss Automatic monitor and Generate css file.
         | 
| 34 | 
            +
            email: sugamasao@gmail.com
         | 
| 35 | 
            +
            executables: 
         | 
| 36 | 
            +
            - saag
         | 
| 37 | 
            +
            extensions: []
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            extra_rdoc_files: 
         | 
| 40 | 
            +
            - ChangeLog
         | 
| 41 | 
            +
            - README.rdoc
         | 
| 42 | 
            +
            - TODO
         | 
| 43 | 
            +
            files: 
         | 
| 44 | 
            +
            - ChangeLog
         | 
| 45 | 
            +
            - README.rdoc
         | 
| 46 | 
            +
            - VERSION
         | 
| 47 | 
            +
            - bin/saag
         | 
| 48 | 
            +
            - lib/saag.rb
         | 
| 49 | 
            +
            - TODO
         | 
| 50 | 
            +
            has_rdoc: true
         | 
| 51 | 
            +
            homepage: http://github.com/sugamasao/saag
         | 
| 52 | 
            +
            licenses: []
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            post_install_message: 
         | 
| 55 | 
            +
            rdoc_options: 
         | 
| 56 | 
            +
            - --title
         | 
| 57 | 
            +
            - saag documentation
         | 
| 58 | 
            +
            - --charset
         | 
| 59 | 
            +
            - utf-8
         | 
| 60 | 
            +
            - --opname
         | 
| 61 | 
            +
            - index.html
         | 
| 62 | 
            +
            - --line-numbers
         | 
| 63 | 
            +
            - --main
         | 
| 64 | 
            +
            - README.rdoc
         | 
| 65 | 
            +
            - --inline-source
         | 
| 66 | 
            +
            - --exclude
         | 
| 67 | 
            +
            - ^(examples|extras)/
         | 
| 68 | 
            +
            require_paths: 
         | 
| 69 | 
            +
            - lib
         | 
| 70 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 71 | 
            +
              requirements: 
         | 
| 72 | 
            +
              - - ">="
         | 
| 73 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 74 | 
            +
                  segments: 
         | 
| 75 | 
            +
                  - 1
         | 
| 76 | 
            +
                  - 8
         | 
| 77 | 
            +
                  - 6
         | 
| 78 | 
            +
                  version: 1.8.6
         | 
| 79 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 80 | 
            +
              requirements: 
         | 
| 81 | 
            +
              - - ">="
         | 
| 82 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 83 | 
            +
                  segments: 
         | 
| 84 | 
            +
                  - 0
         | 
| 85 | 
            +
                  version: "0"
         | 
| 86 | 
            +
            requirements: []
         | 
| 87 | 
            +
             | 
| 88 | 
            +
            rubyforge_project: 
         | 
| 89 | 
            +
            rubygems_version: 1.3.6
         | 
| 90 | 
            +
            signing_key: 
         | 
| 91 | 
            +
            specification_version: 3
         | 
| 92 | 
            +
            summary: SAss Automatic monitor and Generate css file.
         | 
| 93 | 
            +
            test_files: 
         | 
| 94 | 
            +
            - spec/saag_spec.rb
         | 
| 95 | 
            +
            - spec/spec_helper.rb
         |