改了一个文件,重做哪几步
改了一个源文件,重做的只有它下游的
另一支一动不动
(RULES 里每个目标记着它的依赖和命令;stale(目标) 判它要不要重做:目标不存在、或任何一个依赖比它新、或依赖自己就要重做;plan(目标) 按依赖先、目标后的顺序列出要重做的目标。)
贯穿 n05 的构建规则(目标 ← 依赖:命令):
dist/app.pyz ← build/app.py, build/lib.py : zipapp build -o dist/app.pyz
build/app.py ← src/app.py : cp src/app.py build/
build/lib.py ← src/lib.py, src/lib.cfg : gen.py src/lib.py src/lib.cfg > build/lib.pyMTIME 是每个文件的修改时间(数越大越新):src/app.py 10、src/lib.py 12、src/lib.cfg 5、build/app.py 11、build/lib.py 13、dist/app.pyz 14。
先按现在的时间看要不要重做,再把 src/lib.cfg 改一下(时间变成 20)看一次:
RULES = {
"dist/app.pyz": (["build/app.py", "build/lib.py"], "zipapp build -o dist/app.pyz"),
"build/app.py": (["src/app.py"], "cp src/app.py build/"),
"build/lib.py": (["src/lib.py", "src/lib.cfg"], "gen.py src/lib.py src/lib.cfg > build/lib.py"),
}
MTIME = {"src/app.py": 10, "src/lib.py": 12, "src/lib.cfg": 5, "build/app.py": 11, "build/lib.py": 13, "dist/app.pyz": 14}
def stale(target):
if target not in RULES:
return False
if target not in MTIME:
return True
for d in RULES[target][0]:
if stale(d) or MTIME.get(d, 0) > MTIME[target]:
return True
return False
def plan(target, done=None):
done = [] if done is None else done
if target in RULES:
for d in RULES[target][0]:
plan(d, done)
if stale(target) and target not in done:
done.append(target)
return done
before = plan("dist/app.pyz")
MTIME["src/lib.cfg"] = 20
after = plan("dist/app.pyz")
print(str(before) + "/" + ",".join(after) + "/" + str(stale("build/app.py")))
全部评论