Skip to main content

Helper to run Bash commands with python

Project description

Bulot

Helper to run shell commands with python

PyPI - Version PyPI - Python Version


Table of Contents

Installation

pip install bulot

Introduction

Shells like Bash or Zsh are powerful and essential languages. But once, you need to create huge script it quickly becomes unmaintainable. 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 !

Examples

Concept

from bulot import Shell

# Create a shell
sh = Shell()
sh | "ls" | print

# Create another shell independant from the first one
sh2 = Shell()
sh2.cd("..")
print(sh2.cwd())
# remove alias for ls
del sh2.aliases["ls"]
files = sh2 | "ls"
# without the alias, will print ls without color
print(files)

Print

import json
from pprint import pprint
from bulot import Pipe


def jprint(data):
    print(json.dumps(data, indent=4, default=repr))


data = sh << list(__builtins__.keys())[:10]
assert len(data.stdout) == 10
assert isinstance(data, Pipe)
data | print
data | pprint
data | jprint

Classes

import re
from bulot import xargs
from bulot.utils import stdout
from glob import glob


def extract_classes(stdin: str) -> list:
    """Returns classes' name"""
    def extract_name(class_line):
        return re.sub(r"class (\w+).*:", r"\1", class_line)

    return [extract_name(line) for line in stdin.splitlines() if line.startswith("class")]


classes = sh << glob("bulot/*.py") | xargs - "cat {}" | "\n".join | extract_classes
assert "Shell" in classes.stdout

sh | "ls *.py" can't expand * because subprocess.run has shell=False then we must use glob.
See https://docs.python.org/3/library/subprocess.html#security-considerations

Git

from bulot import Pipe, shell
from bulot.utils import stdout

class Git(Shell):
    def __or__(self, cmd: RunPipeCmd) -> "Pipe":
        if isinstance(cmd, str):
            cmd = f"git {cmd}"
        return super().__or__(cmd)


git = Git()

CREATE_BRANCH = False
BRANCH_NAME = "plop"

branch_init = git | "branch --show-current" | stdout

# Save current changes
nb_stash_before = git | "stash list" | str.splitlines | len | stdout
git | "stash"
nb_stash_after = git | "stash list" | str.splitlines | len | stdout
is_stashed = nb_stash_before != nb_stash_after

# Update main branch
if branch_init != "main":
    git | "chechout main"
git | "pull"

# Create new branch
checkout = git | f"checkout -b {BRANCH_NAME}"
if checkout.return_code == 128:
    git | f"checkout {BRANCH_NAME}"

# Modify
sh.fake = True  # Following sh's commands won't run
FILE = "bulot/__init__.py"
sh << "\nraise RuntimeError('Oups')" >> FILE
sh.fake = False
git.fake = True  # Following git's commands won't run
git | f"add {FILE}"
git | "commit -m 'Add error'"
git.fake = False

# push changes
branch_exist_on_remote = git | f"ls-remote --exit-code --heads origin {BRANCH_NAME}"
git.fake = True
if branch_exist_on_remote.return_code == 2:
    git | "push --set-upstream origin {BRANCH_NAME}"
else:
    git | "push"
git.fake = False

# restore previous state
git | f"checkout {branch_init}"
if is_stashed:
    git | "stash pop"

# Historic
git_commands = [command.value for command in git.historic]
assert "git branch --show-current" in git_commands
# print(git_commands)
# to print all stdout
# print([command.stdout for command in git.historic])
assert git.historic[0].stdout == branch_init
assert any(command.fake for command in git.historic)

Development

# Linter
hatch run lint
# Type checking
hatch run typecheck
# Fixer
hatch run fixer
# Tests
hatch run test:pytest
hatch run +py=310 test:pytest
# Coverage
hatch run cov

License

Bulot is distributed under the terms of the Apache-2.0 license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bulot-0.0.4.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bulot-0.0.4-py3-none-any.whl (14.1 kB view details)

Uploaded Python 3

File details

Details for the file bulot-0.0.4.tar.gz.

File metadata

  • Download URL: bulot-0.0.4.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.23.0

File hashes

Hashes for bulot-0.0.4.tar.gz
Algorithm Hash digest
SHA256 c289798d80a1f55968083ff6543196ebe42533d687ec6ab7a843e2245ebbc4bb
MD5 be17eef9aea83c9583aedf8fd2a3caff
BLAKE2b-256 235ab6328897cbc2f98aad90ce50ec0f794227384a22ff86c4a6771883909766

See more details on using hashes here.

File details

Details for the file bulot-0.0.4-py3-none-any.whl.

File metadata

  • Download URL: bulot-0.0.4-py3-none-any.whl
  • Upload date:
  • Size: 14.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.23.0

File hashes

Hashes for bulot-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 3e819df0af612c4679df03e81779eea7c2ea612f396393ca22bc3ce6f36ecae4
MD5 a39090920766682ece55d39881508319
BLAKE2b-256 4188582ef2ab81cb138e65778d415c466c5ca265a04cf3f329109a64c1cc1461

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page