Package: bulot
BulotHelper to run shell commands with pythonTable of ContentsInstallationIntroductionExamplesConceptPrintClassesGitDevelopmentLicenseInstallationpip install bulotIntroductionShells like Bash or Zsh are powerful and essential languages. But once, you need to create
huge script it quickly becomesunmaintainable.
The best to create a complex script is so to use a more ergonomic language like Python, Perl, ...This library is still in early development stages, and might change. It requires feedbacks, so don't hesitate to open an
issue !ExamplesConceptfrombulotimportShell# Create a shellsh=Shell()sh|"ls"|print# Create another shell independant from the first onesh2=Shell()sh2.cd("..")print(sh2.cwd())# remove alias for lsdelsh2.aliases["ls"]files=sh2|"ls"# without the alias, will print ls without colorprint(files)PrintimportjsonfrompprintimportpprintfrombulotimportPipedefjprint(data):print(json.dumps(data,indent=4,default=repr))data=sh<<list(__builtins__.keys())[:10]assertlen(data.stdout)==10assertisinstance(data,Pipe)data|printdata|pprintdata|jprintClassesimportrefrombulotimportxargsfrombulot.utilsimportstdoutfromglobimportglobdefextract_classes(stdin:str)->list:"""Returns classes' name"""defextract_name(class_line):returnre.sub(r"class (\w+).*:",r"\1",class_line)return[extract_name(line)forlineinstdin.splitlines()ifline.startswith("class")]classes=sh<<glob("bulot/*.py")|xargs-"cat{}"|"\n".join|extract_classesassert"Shell"inclasses.stdoutsh | "ls *.py"can't expand*because subprocess.run has shell=False then we must use glob.Seehttps://docs.python.org/3/library/subprocess.html#security-considerationsGitfrombulotimportPipe,shellfrombulot.utilsimportstdoutclassGit(Shell):def__or__(self,cmd:RunPipeCmd)->"Pipe":ifisinstance(cmd,str):cmd=f"git{cmd}"returnsuper().__or__(cmd)git=Git()CREATE_BRANCH=FalseBRANCH_NAME="plop"branch_init=git|"branch --show-current"|stdout# Save current changesnb_stash_before=git|"stash list"|str.splitlines|len|stdoutgit|"stash"nb_stash_after=git|"stash list"|str.splitlines|len|stdoutis_stashed=nb_stash_before!=nb_stash_after# Update main branchifbranch_init!="main":git|"chechout main"git|"pull"# Create new branchcheckout=git|f"checkout -b{BRANCH_NAME}"ifcheckout.return_code==128:git|f"checkout{BRANCH_NAME}"# Modifysh.fake=True# Following sh's commands won't runFILE="bulot/__init__.py"sh<<"\nraise RuntimeError('Oups')">>FILEsh.fake=Falsegit.fake=True# Following git's commands won't rungit|f"add{FILE}"git|"commit -m 'Add error'"git.fake=False# push changesbranch_exist_on_remote=git|f"ls-remote --exit-code --heads origin{BRANCH_NAME}"git.fake=Trueifbranch_exist_on_remote.return_code==2:git|"push --set-upstream origin{BRANCH_NAME}"else:git|"push"git.fake=False# restore previous stategit|f"checkout{branch_init}"ifis_stashed:git|"stash pop"# Historicgit_commands=[command.valueforcommandingit.historic]assert"git branch --show-current"ingit_commands# print(git_commands)# to print all stdout# print([command.stdout for command in git.historic])assertgit.historic[0].stdout==branch_initassertany(command.fakeforcommandingit.historic)Development#Linterhatch run lint#Typecheckinghatch run typecheck#Fixerhatch run fixer#Testshatch run test:pytesthatch run +py=310 test:pytest#Coveragehatch run covLicenseBulotis distributed under the terms of theApache-2.0license.