Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # an abstract representation of source file or a way to build a file
- # usually, any given build run cannot have two active files with the same path
- # (attempting to build the second immediately one triggers an error)
- class File:
- # returns the path of this file
- def get_path(self) -> path
- # asynchronously runs the build command for this file and eventually
- # returns an object that can be used to read the contents of the file
- def build(self) -> Promise[FileHandle]
- # returns a File object representing a file provided by the outside world
- # (usually, a source file)
- # its build command is a simple noop
- def fs_source(p:path) -> File
- # returns a File object representing a file that can be built builder is
- # a function that will be invoked in response to the build() command
- # on the file
- def fs_artifact(p:path, builder:Callable[[], Promise[None]]) -> File
- # checks if a cache record for the path was built using the given command,
- # and all of its dependencies are still up to date
- # returns True if cache validation passed, and False if the file needs to be
- # rebuilt
- def cache_verify(p:path, command:any) -> bool
- # removes a cache record
- def cache_drop(p:path) -> None
- # stores a cache record for the given path, with the given command and the list
- # of dependencies
- def cache_commit(p:path, command:any, deps:List[File]) -> None
- # This is how a copy file command may look like:
- def copy_file(source:File, target:path) -> File:
- # this will be executed if someone wants to build the File
- def builder():
- # this is a free-form object that will be stored in the cache for
- # the target path
- # this way we can still rebuild it later if the command changes
- # but none of the dependencies do
- command = ["copy", source.get_path()]
- # request building of the source file
- # it is crucial we do this before cache_verify, otherwise it may not
- # work properly (if source is itself an artifact, then it may not be
- # yet "built" this run, so it is not registered, and cache may not
- # discovered that its dependency is in fact did not change)
- yield source.build()
- # we check if our target file was already built using the same command
- if not cache_verify(target, command):
- # if not, we first drop the cache record for it, to avoid race
- # conditions
- cache_drop(target)
- # then we do the neccessary system calls
- shutil.copy2(source.get_path(), target)
- # after we are done, we commit the new cache record ([source] states
- # our target file depends on the source)
- cache_commit(target, command, [source])
- # wrap the path and the builder into a "defered" file object
- return fs_artifact(target, builder)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement