Skip to content

lujun9972/elake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 

Repository files navigation

Readme

elake简介

仿真rake的elisp实现

使用方法

类似make,elake中的任务也分为两种,phony任务与file任务. 其中file任务对应操作系统中的一个文件路径.

一个任务的依赖任务是否执行由以下表格表示:

目标任务类型依赖任务类型依赖任务执行条件
phony任务phony任务依赖任务未执行
file任务phony任务依赖任务未执行
phony任务file任务依赖任务对应的文件不存在
file任务file任务依赖任务对应的文件要比目标任务对应的文件更新

定义任务

定义任务的方法是使用宏 (elake-task 目的任务 (依赖任务列表) 任务说明字符串 任务定义内容).

例如我们这样定义一个做饭的过程:

(elake-task :purchaseVegetables nil
      "任务1 -- 买菜"
      (message  "到沃尔玛去买菜。"))

(elake-task :cook (:purchaseVegetables)
    "任务2 -- 做饭"
    (message  "做一顿香喷喷的饭菜。"))

上面代码定义了两个任务

第一个任务的名称为”:purchaseVegetables”,它以”:”开头,因此是一个phony任务.

  • :purchaseVegetables任务的依赖任务列表为nil,表示它不依赖任何前置任务
  • :purchaseVegetables任务的说明是”任务1 – 买菜”
  • :purchaseVegetables任务的内容是 (message "到沃尔玛去买菜。")

第二个任务的名称为”:cook”,它是一个phony任务. 它依赖于:purchaseVegetables任务.

因此,在执行:cook任务前会先执行:purchaseVegetables

$ elake :cook
到沃尔玛去买菜。
做一顿香喷喷的饭菜。

自动变量

在任务定义中,可以使用$<指代目标任务,使用$@指代依赖任务列表. 例如:

(elake-task :task1 (/etc/passwd)
  "测试自动变量"
  (message "%s依赖于%s" $< $@))

执行任务:task1的结果为:

$ elake :task1
:task1依赖于(/etc/passwd)

默认构建任务

elake会将地一个定义的任务作为默认的构建任务. 当没有为elake指定构建哪个任务时,elake会构建默认的构建任务.

例如,上面的例子中,我们地一个定义的任务是:purchaseVegetables任务,因此直接调用elake的结果为:

$ elake
到沃尔玛去买菜。

命名空间

elake支持命名空间的概念. 使用命名空间的格式为 (elake-namespace 命名空间名称 其他elake命令...)

在命名空间内定义的phony任务,其完整的名称为”:命名空间名称:任务名称”,命名空间对file任务无效 例如:

(elake-namespace home
    (elake-task :write-blog (:turn-on-computer) ;注意,同一个命名空间内的依赖任务无需加命名空间前缀
      "写博客"
      (message  "在家写博客"))
  (elake-task :turn-on-computer ()
    "打开电脑"
    (message  "打开家里的电脑")))

这里在home命名空间内定义了两个任务:”:home:write-bog和:home:turn-on-computer”.

$ elake :home:write-blog
打开家里的电脑
在家写博客
$ elake :write-blog
未定义的任务::write-blog

目前支持命名空间的函数还有`elake-execute-task’和`elake-remove-task’

给任务传递环境变量值

给elake传递形如”环境变量:=值”的参数,可以设定环境变量的值

(elake-task :set-env nil
  "设置环境变量"
  (message "UNKNOW-ENV:%s" (getenv "UNKNOW-ENV")))

若不传递环境变量,则有:

$ elake :set-env
UNKNOW-ENV:nil

若传递环境变量,则:

$ elake :set-env UNKNOW-ENV:=whatever
UNKNOW-ENV:whatever

给任务传递参数值

可以在定义任务时,使用未定义的变量. 只需要通过形如”变量=值”的形式传递变量值就好. 例如

(elake-task :say-hello-to  nil
    "给任务传递参数"
    (message "hello to %s" who))

若不传递参数值,则会执行出错

$ elake :say-hello-to
Symbol's value as variable is void: who

若传递参数值,则

$ elake  who=darksun :say-hello-to
hello to darksun

在任务中执行其他任务

使用 (elake-execute-task task) 可以在任务内执行其他任务

(elake-task :laundry nil
  "洗衣服"
  (message "把所有衣服扔进洗衣机。"))
(elake-task :today nil
  "今天的任务"
  (elake-execute-task :home:write-blog)
  (elake-execute-task :laundry))

则调用:today任务,会以此执行:home:write-blog和:laundry任务

$ elake :today
打开家里的电脑
在家写博客
把所有衣服扔进洗衣机。

在任务中删除其他任务

使用 (elake-remove-task task) 可以删除其他任务.例如

(elake-task :task-to-be-removed nil
  "待删除的任务"
  (message "该任务会被:remove-task删除掉,删除掉后无法执行"))
(elake-task :remove-task (:task-to-be-removed)
  "删除任务:task-to-be-removed"
  (elake-remove-task :task-to-be-removed)
  (message "%s被删除" $@))

(elake-task :execute-removed-task (:remove-task)
  "删除任务测试"
  (elake-execute-task :task-to-be-removed))

在执行:remove-task前,可以执行:task-to-be-removed

$ elake :remove-task
该任务会被:remove-task删除掉,删除掉后无法执行
(:task-to-be-removed)被删除

但执行:remove-task后,无法再执行:task-to-be-removed了

$ elake :execute-removed-task
该任务会被:remove-task删除掉,删除掉后无法执行
(:task-to-be-removed)被删除
未定义的任务::task-to-be-removed

使用规则自动生成任务

使用 (elake-rule 目标任务的匹配正则表达式 依赖任务的替代表达式列表 任务内容) 来定义规则,当执行未定义的任务时,elake会尝试使用规则生成该任务.

这里匹配正则表达式必须为字符串,替代表达式列表为字符串或字符串列表.

关于匹配正则表达式和替代表达式的说明请参见`replace-regexp’函数中的`REGEXP’和`TO-STRING’说明.

例如:

(elake-rule ":make-\\(.+\\)" ("\\1")
  "测试rule"
  (message (shell-command-to-string (format "ls -l %s" (car $@)))))

(elake-rule "[^:].*" nil
  "测试rule"
  (message "touch %s" $<)
  (message (shell-command-to-string (format "touch %s" $<))))

可以使用:make-xxx任务来显示xxx文件的内容,且若xxx文件不存在则创建该文件

$ ls -l rule
rule: No such file or directory
$ elake :make-rule
touch rule

-rw-rw-r-- 1 lujun9972 lujun9972 0  7月 19 11:53 rule

$ elake :make-rule
-rw-rw-r-- 1 lujun9972 lujun9972 0  7月 19 11:53 rule

依赖任务列表中支持使用S-Form自动生成依赖任务

依赖任务列表中支持使用S-Form自动生产依赖任务,若依赖任务为list,则该list会被作为S-Form来执行,该S-Form的执行结果应该为一个包含一个多个多个依赖任务的list.

例如:

(elake-task :blog (index.html (let (files)
                                (dotimes (num 3 files)
                                  (push (format "file-%s.html" num) files))))
  "测试使用S-Form自动生成依赖任务"
  (message "%s的依赖任务为%s" $< $@))

表示:blog的依赖任务为index.html,file-2.html,file-1.html,file-0.html

因此:

~/elake $ elake :blog
touch index.html

touch file-2.html

touch file-1.html

touch file-0.html

:blog的依赖任务为(index.html file-2.html file-1.html file-0.html)

其他参数说明

-f 配置文件路径
使用指定的文件作为加载的配置文件. 默认使用`elakefile’或`elakefile.el’或`elakefile.elc’
–task 任务…
显示任务说明,若省略后面的任务,则显示所有任务说明
-p 任务…
显示任务的依赖任务,若省略后面的任务,则显示所有的任务依赖
-h
显示帮助信息

待完成事项

  • [X] 增加file类型的任务
  • [X] 增加命名空间的支持
  • [X] 仿照make添加一些自动变量
  • [X] 仿照make将第一个定义的任务作为默认的构建任务
  • [ ] 如何支持emacs本身已经占有的那些option呢?
  • [ ] 如何区分传递符号和字符串給emacs –script呢?
  • [ ] 支持定义任务和定义依赖相分离
  • [ ] 支持分多次添加依赖关系,这样就能用程序自动添加依赖关系
  • [X] 支持模式规则来自动生成某类文件
  • [X] 支持使用-f指定依赖文件,默认为elakefile或elakefile.el或elakefile.elc
  • [X] 支持带参数的任务
  • [X] 支持命令行设置环境参数
  • [X] 提供删除已定义任务的机制
  • [X] 依赖任务列表中支持使用S-Form自动生成依赖任务

About

elisp make

Resources

Stars

0 stars

Watchers

2 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors