tinyevil Jan 5th, 2019 69 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # an abstract representation of source file or a way to build a file
  2. # usually, any given build run cannot have two active files with the same path
  3. # (attempting to build the second immediately one triggers an error)
  4. class File:
  5.     # returns the path of this file
  6.     def get_path(self) -> path
  7.     # asynchronously runs the build command for this file and eventually
  8.     # returns an object that can be used to read the contents of the file
  9.     def build(self) -> Promise[FileHandle]
  12. # returns a File object representing a file provided by the outside world
  13. # (usually, a source file)
  14. # its build command is a simple noop
  15. def fs_source(p:path) -> File
  16. # returns a File object representing a file that can be built builder is
  17. # a function that will be invoked in response to the build() command
  18. # on the file
  19. def fs_artifact(p:path, builder:Callable[[], Promise[None]]) -> File
  21. # checks if a cache record for the path was built using the given command,
  22. # and all of its dependencies are still up to date
  23. # returns True if cache validation passed, and False if the file needs to be
  24. # rebuilt
  25. def cache_verify(p:path, command:any) -> bool
  26. # removes a cache record
  27. def cache_drop(p:path) -> None
  28. # stores a cache record for the given path, with the given command and the list
  29. # of dependencies
  30. def cache_commit(p:path, command:any, deps:List[File]) -> None
  33. # This is how a copy file command may look like:
  35. def copy_file(source:File, target:path) -> File:
  36.     # this will be executed if someone wants to build the File
  37.     def builder():
  38.         # this is a free-form object that will be stored in the cache for
  39.         # the target path
  40.         # this way we can still rebuild it later if the command changes
  41.         # but none of the dependencies do
  42.         command = ["copy", source.get_path()]
  43.         # request building of the source file
  44.         # it is crucial we do this before cache_verify, otherwise it may not
  45.         # work properly (if source is itself an artifact, then it may not be
  46.         # yet "built" this run, so it is not registered, and cache may not
  47.         # discovered that its dependency is in fact did not change)
  48.         yield
  49.         # we check if our target file was already built using the same command
  50.         if not cache_verify(target, command):
  51.             # if not, we first drop the cache record for it, to avoid race
  52.             # conditions
  53.             cache_drop(target)
  54.             # then we do the neccessary system calls
  55.             shutil.copy2(source.get_path(), target)
  56.             # after we are done, we commit the new cache record ([source] states
  57.             # our target file depends on the source)
  58.             cache_commit(target, command, [source])
  60.     # wrap the path and the builder into a "defered" file object
  61.     return fs_artifact(target, builder)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!