def test_ec_successful() -> None: """Test a basic command call with `external_command` Checks that a successful call returns an exit code of 0 and the expected output """ results = external_command(["echo", "hello"]) assert results.returncode == 0 assert results.stdout == b"hello\n"
def __init__(self, path: Path, create: bool = True, delimiter: str = "\t") -> None: """Initialise the Filer object Note ---- The attribute self.length is created to hold the number of lines in the file. This is particularly useful for checking to see if a file has been altered. Parameters ---------- path : Path A Posix filepath to the desired file/location create : bool If the file does not exist, should it be created? delimiter : str What delimited should be used with the file? Examples -------- >>> from pathlib import Path >>> example = Filer(Path.home() / 'tmp.tsv') """ self.path = Path(path) self.delimiter = delimiter if not os.path.isfile(self.path): if create: self.path.touch() self.length = 0 # Specifically for initiating todos self.append([["ID", "Rank", "Date", "Task"]]) else: raise OSError("File does not exist") self.length = int( external_command(["wc", "-l", self.path]).stdout.strip().split()[0])
def delete(self, contains: str) -> bool: """Deletes all lines from self where `contains in line` Parameters ---------- contains : str String to match for line deletion Returns ------- bool True if successulf, false otherwise Example ------- >>> example.delete('j') True """ with open(self.path, "r") as r_file: reader = csv.reader(r_file, delimiter=self.delimiter) with open("tmp", "a") as w_file: writer = csv.writer(w_file, delimiter=self.delimiter) for line in reader: if contains not in line: writer.writerow(line) # If deleted, copy and return true tmp_length = int( external_command(["wc", "-l", Path("tmp")]).stdout.strip().split()[0]) if self.length != tmp_length: shutil.move("tmp", self.path) self.length = tmp_length return True # Otherwise, clean tmp and return false os.remove(Path("tmp")) return False
def test_ec_ProcessError() -> None: """Test `external_command` raise an CalledProcessError when has a non-0 status """ with pytest.raises(subprocess.CalledProcessError): external_command(["false"])
def test_ec_OSError() -> None: """Test `external_command` raise an `OSError` for `Command Not Found` """ with pytest.raises(OSError): external_command(["thisdoesntexistinanyOS"])
def doing(args: argparse.Namespace) -> None: """See tasks in your list Notes ----- `--edit` opens whatever editor is specified by your `EDITOR` env var. If one is not set, it will default to Vim. Currently, `--reminder` has a dependency on `notify-send`. If this command is absent from your system, it will failt Parameters ---------- args : argparse.Namespace Args passed from argparse. For this subcommand, these include: args.file : Filer The TODO file to echo. Derived from the root `to` command args.sort : Literal['both', 'none', rank', 'date'] How to sort echoed tasks. Derived from the root `to` command args.number : int How many tasks to return args.reminder : bool Whether to use notify-send to create a pop-up args.edit : bool Whether to laucn an editor with your TODO file Returns ------- None Example ------- $ to doing -n 3 """ keys = {"rank": [1], "date": [2], "both": [1, 2]} if args.sort != "none": args.file.sort(keys[args.sort], header=True) ids = [str(x) for x in range(1, args.file.length)] ids.insert(0, "ID") args.file.write_col(ids, 0) lines = args.file.read()[:args.number + 1] if args.edit: # print(args.file.path) __editor__ = os.environ.get("EDITOR", "vim") external_command([__editor__, args.file.path]) elif args.reminder: external_command([ "notify-send", "My TODOs", "\n".join(["\t".join(l) for l in lines]), "-u", "low", "-t", "5000", ]) else: for l in lines: print("\t".join(l))