A composite tree of files and directories, path resolution with dots, mkdir -p, no-clobber moves that refuse to move a directory into itself, and a byte quota checked before anything changes.
Build the core of the file-system round: a composite tree where a file and a directory are both nodes, and a FileSystem over it. Text is ASCII, so one character is one byte. Paths are absolute (/a/b); . and empty parts are ignored, .. goes up (and stays at the root).
Node(name, parent) with size() and path() (/home/asha/a.txt, the root is /). File(name, parent) has data and its size is its length. Directory(name, parent) has children (name to node) and its size is the sum of its children's: the composite at work.FileSystem(quota_bytes) with root, quota and used:
mkdir(path, parents=False): without parents the parent must exist (FileNotFoundError) and the directory must be new (FileExistsError); with parents it creates what is missing and is idempotent. A file in the way is always FileExistsError.ls(path): a directory's names sorted, directories with a trailing /; a file lists as [name].write(path, text, append=False) creates or replaces (or appends to) a file and returns its new size. A directory target is IsADirectoryError, a missing parent FileNotFoundError, a parent that is a file NotADirectoryError. If the change would take used over the quota it raises QuotaExceeded (given) before any byte changes; replacing a file counts only the difference.read(path) (a directory is IsADirectoryError); du(path): the size of a file or of everything under a directory.mv(src, dst) returns the new path. If dst is an existing directory the node goes inside it under its own name; otherwise dst is the new path. It never overwrites (FileExistsError) and refuses to move a directory into itself (ValueError).rm(path, recursive=False) returns the bytes freed; a non-empty directory without recursive raises OSError. used always matches the files that exist.ValueError; so does mkdir, write, mv or rm on /.The errors in Python are the built-in ones. In JavaScript and TypeScript they are the classes given below (FileNotFoundError, NotADirectoryError, FileExistsError, IsADirectoryError, DirectoryNotEmpty, InvalidPath, QuotaExceeded); the method names are the same, with quotaBytes for the constructor.
Write your code, then run 9 example tests and 4 hidden tests. Each run is limited to 8 seconds: an infinite loop gets stopped and the runtime restarts, your code stays.