RakeのFileListでドットファイル・ディレクトリを再帰的に取得

RakeのFileListオブジェクトが、標準ではドットファイル・ディレクトリの再帰的な取得を行えないため、FileListクラスを再定義し、再帰的にドットファイル・ディレクトリを取得できるようにしました。

再定義したのは、Rake::FileList#add_matchingとRake::FileList#exclude?です。Rakefileの中でFileListクラスを再定義します。

class FileList
    def add_matching(pattern)
        Dir.glob(pattern, File::FNM_DOTMATCH).each do |fn|
            self << fn unless exclude?(fn) or /(?:^(?:\.|\.\.)$)|(?:\/(?:\.|\.\.)$)/.match(fn)
        end
    end
    private :add_matching

    # Should the given file name be excluded?
    def exclude?(fn)
      return true if @exclude_patterns.any? do |pat|
        case pat
        when Regexp
          fn =~ pat
        when /[*?]/
          File.fnmatch?(pat, fn, File::FNM_PATHNAME | File::FNM_DOTMATCH)
        else
          fn == pat
        end
      end
      @exclude_procs.any? { |p| p.call(fn) }
    end
end

あとは、FileListオブジェクトへ通常通りにパターンを渡すだけで、カレントディレクトリ(.)と親ディレクトリ(..)を追加することなく、ドットファイル・ディレクトリを再帰的に追加・除外できるようになりました。

# カレントディレクトリ以下のドットファイル・ディレクトリを含む全てのファイルを再帰的に追加
fileset = FileList['**/*'].clear_exclude    # 標準では.svn, .bak等が除外されるので、必要に応じて除外パターンを初期化

# カレントディレクトリ以下のドットディレクトリとドットディレクトリ内の全てのファイルを再帰的に除外
fileset.exclude('**/.git', '**/.git/**/*')

# カレントディレクトリ以下のドットファイルを再帰的に除外
fileset.exclude('**/.gitignore')

FileListオブジェクトからのドットファイル・ディレクトリの除外のみであれば、Rake::FileList#excludeがブロックの受け渡しに対応しているので、除外パターンを生成する処理などを書いたブロックを渡すことでも対応できそうです。

コメント (0)

この記事へのコメントはまだありません。

コメントフォーム

トラックバック (0)

この記事へのトラックバックはまだありません。

この記事のトラックバックURI
http://dxd8.com/archives/222/trackback/
この記事のURI
http://dxd8.com/archives/222/