How to write a beautiful rake file

Time:2020-3-22

Rake, I won’t talk about Ruby’s make any more than make in many aspects. Unlike Makefile, rakefile itself is a piece of ruby code, which has many advantages. On the one hand, it can do anything Ruby can do directly in rake. On the other hand, because Ruby supports DSL well, rakefile usually does not look like “code”.

However, the code is always the code, and makefile can be written in a mess. It’s easier for rake file to write in a mess. Fortunately, rake provides some functions for us to do some organization work for rake file.

One of them is the import function, which writes tasks of different functions to different files, for example, like this:

Copy codeThe code is as follows:
Rakefile
task/
  +– doc.rake
  +– compile.rake
  `– deploy.rake

So, write it in the rake file

Copy codeThe code is as follows:
import(“task/doc.rake”)

Such statements can be imported into each subtask, and different tasks will not be messed up when they are written to different files. Moreover, import is different from Ruby’s own require. Import is not imported immediately, but only after the execution of the entire rakefile. Therefore, you can write import anywhere without worrying about dependency. You only need to define shared variables in the main rakefile.

Import is to organize different functional modules. In addition, rake allows us to abstract some repetitive tasks, specifically, custom tasks. In general, we use the general task and file task provided by rake to construct the work we need to complete. In addition, rake also brings some task types for special tasks, such as building RDOC or running test. In fact, a task is a common Ruby class. We can inherit the task class in rake and redefine the related functions to implement the custom task type. However, it’s a bit cumbersome. In fact, most of the tasks we want to define can be decomposed into small tasks that are implemented with built-in general tasks and file tasks. At this time, we can use tasklib to define custom tasks more easily.

Specifically, it is to write a class that inherits from tasklib (although it is actually just a convention rather than a requirement), and then use task or file in the class’s initialization function to define the subtask that actually completes the task. In a practical example, for example, we can define an erlctask, which can be used to compile some Erlang files into a directory, and automatically clean up the compiled. Beam files when clean:

Copy codeThe code is as follows:
require ‘rake’
require ‘rake/clean’
require ‘rake/tasklib’

class ErlcTask < Rake::TaskLib
  attr_accessor :name
  attr_accessor :sources
  attr_accessor :dest_dir
  attr_accessor :include_path
  attr_accessor :flags
  attr_accessor :extra_dep

  def initialize(name = :erlc)
    # default values
    if name.is_a? Hash
      @name = name.keys.first
      @extra_dep = name.values.first
    else
      @name = name
      @extra_dep = []
    end
    @sources = FileList[]
    @dest_dir = ‘.’
    @include_path = []
    @flags = “-W +warn_unused_vars +warn_unused_import”

    yield self if block_given?
    define
  end

 
  def define
    beams = @sources.pathmap(File.join(@dest_dir, ‘%n.beam’))

    include_path = Array(@include_path).map{|incl|”-I”+incl}.join(” “)

    directory @dest_dir
    beams.zip(@sources).each do |beam, source|
      file beam => source do
        sh “erlc -pa #{@dest_dir} #{@flags} #{include_path} -o #{@dest_dir} #{source}”
      end
    end

    task @name => beams + Array(@extra_dep)
    CLEAN.include(beams)
  end
end

First, define some Task related attributes, set the initial value in the initialization function, then call block to fill the actual value, and finally call the define function. The define function defines the tasks of building directory, compiling and cleaning using directory, file and task respectively. If you know the basic syntax of ruby and rake, it should be easy to understand.

Next, save this file to a. Rb, and then in the rake file, require it. You can write as follows:

Copy codeThe code is as follows:
ErlcTask.new :compile do |t|
    t.sources = FileList[‘src/*.erl’]
    t.dest_dir = ‘../ebin’
    t.include_path = ‘../include’
    t.extra_dep = :library
end

It looks much cooler! And it can be reused. At last, by the way, I would like to say that although I have used Python a lot recently, I feel comfortable writing every time I write ruby, which is almost impossible to find in Python!

Recommended Today

Python basics Chinese series tutorial · translation completed

Original: Python basics Python tutorial Protocol: CC by-nc-sa 4.0 Welcome anyone to participate and improve: a person can go very fast, but a group of people can go further. Online reading Apache CN learning resources catalog introduce Seven reasons to learn Python Why Python is great Learn Python introduction Executing Python scripts variable character string […]