Using filelists in Rantfiles

You can find documentation for Rant’s FileList class in the file doc/filelist.rdoc. This document describes how you can use filelists in your Rant build scripts (Rantfiles).

First of all, you don’t need to require or import anything to use filelists in Rantfiles. Additionally the Rant::FileList class is directly available as FileList. Thus, for example, instead of typing:

    c_files = Rant::FileList["*.c"]

you can type:

    c_files = FileList["*.c"]

Again, you don’t need to require "rant/filelist". But if you want to use one of the methods no_dir, files or dirs import "filelist/std" is required.

Often there are files/directories you want to always ignore when using filelists. This could be the "CVS" directories if you are using the CVS version control system or simply all backup files.

Rant allows you to specify a set of patterns once for your project with the sys.ignore method.

E.g. place the following line of code in your Rantfile:

    sys.ignore "CVS", /~$/

In the Rant::FileList documentation there are five ways to create a filelist documented. In Rantfiles:

    instead of                          |   use
    -----------------------------------------------------------------
    Rant::FileList.new                  |   sys.filelist
    Rant::FileList[*patterns]           |   sys[*patterns]
    Rant::FileList.glob(*patterns)      |   sys.glob(*patterns)
    Rant::FileList.glob_all(*patterns)  |   sys.glob_all(*patterns)
    Rant::FileList(list)                |   sys.filelist(list)

The sys variants of filelist creation all honour the project wide ignore patterns set by sys.ignore.

Let’s look at an example. First an Rantfile using the "normal" filelist constructors:

    all_files = FileList["**/*"].ignore("CVS", /~$/)
    lib_files = FileList["lib/**/*.rb"].ignore("CVS")
    pkg_files = FileList["bin/*", "lib/**/*.rb", "test/**/*"].ignore("CVS", /~$/)
    backup_files = FileList["**/*~"]

    # define tasks

I admit that the example is a bit exaggerated, but in essence you always have to care that you don’t accidently include a backup file or some file living under a "CVS" directory. Now look at the equivalent Rantfile using sys to create filelists.

    sys.ignore "CVS", /~$/
    all_files = sys["**/*"]
    lib_files = sys["lib/**/*.rb"]
    pkg_files = sys["bin/*", "lib/**/*.rb", "test/**/*"]
    backup_files = FileList["**/*~"]

    # define tasks

Now, per default CVS directories and backup files won’t appear in filelists. We use a "stateless" filelist for backup_files, since all backup files would be ignored otherwise.

Where to use filelists?

Basically, you can use a filelist wherever you can use an array. The following is a list of use cases where filelists are handy.

  • As prerequisite list for a task. Example:
      # get a list of all c files
      c_files = sys["**/*.c"]
      # get a list of all resulting object files
      obj_files = c_files.ext("o")
    
      # static library "foo" depends on all object files
      file "libfoo.a" => obj_files do |t|
          # build t.name from t.prerequisites (obj_files)
      end
    
  • As argument to file system operations. Example:
      task :clean do
          # remove all backup files
          sys.rm_f FileList["**/*~"]
      end
    
  • If you want to apply an operation to a list of files, e.g. substituting a variable in text files. Example:
      # Do something with all files in the project
      import "filelist/std"
      sys["**/*"].files.each { |filename|
          # do something with the file "filename"
      }
    

See also

Rant Overview:README
Rant::FileList documentation:doc/filelist.rdoc
Rantfile basics:doc/rantfile.rdoc
Advanced Rantfiles:doc/advanced.rdoc