mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 20:18:28 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7dacad6be2 | ||
|
|
5fe7df23db | ||
|
|
483bf0d676 | ||
|
|
eb2ad7b1eb | ||
|
|
cf1ae2ec50 | ||
|
|
3b91577d61 | ||
|
|
539bb3bfad | ||
|
|
ab53a37f9f | ||
|
|
1f8be0593f |
@@ -125,7 +125,7 @@ So far I have not created an AUR package for decman, because I'm not sure if oth
|
|||||||
|
|
||||||
### Packages
|
### Packages
|
||||||
|
|
||||||
Decman can be used to install pacman packages. Decman will install all packages defined in the source and **remove** all packages not defined in the source. You can set packages to be ignored by decman, so that it won't install them nor remove them.
|
Decman can be used to install pacman packages. Decman will install all packages defined in the source and **remove** all explicitly installed packages not defined in the source. You don't need to list dependencies as those will be handeled by pacman. You can set packages to be ignored by decman, so that it won't install them nor remove them.
|
||||||
|
|
||||||
```py
|
```py
|
||||||
# Include both foreign and pacman packages here.
|
# Include both foreign and pacman packages here.
|
||||||
@@ -148,7 +148,7 @@ decman.user_packages.append(
|
|||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
# Note, this example may not be up to date
|
# Note, this example may not be up to date
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
version="0.2.1",
|
version="0.3.1",
|
||||||
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
||||||
make_dependencies=[
|
make_dependencies=[
|
||||||
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
||||||
@@ -276,7 +276,7 @@ user_packages = [{
|
|||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
# Note, this example may not be up to date
|
# Note, this example may not be up to date
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
version="0.2.1",
|
version="0.3.1",
|
||||||
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
dependencies=["python", "python-requests", "devtools", "pacman", "systemd", "git"],
|
||||||
make_dependencies=[
|
make_dependencies=[
|
||||||
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
"python-setuptools", "python-build", "python-installer", "python-wheel"
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class MyModule(Module):
|
|||||||
return [
|
return [
|
||||||
UserPackage(
|
UserPackage(
|
||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
version="0.2.1",
|
version="0.3.1",
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
dependencies=[
|
dependencies=[
|
||||||
"python",
|
"python",
|
||||||
|
|||||||
+30
-6
@@ -40,7 +40,7 @@ decman.config.makepkg_user = "kk"
|
|||||||
decman.user_packages.append(
|
decman.user_packages.append(
|
||||||
UserPackage(
|
UserPackage(
|
||||||
pkgname="decman-git",
|
pkgname="decman-git",
|
||||||
version="0.2.1",
|
version="0.3.1",
|
||||||
provides=["decman"],
|
provides=["decman"],
|
||||||
dependencies=[
|
dependencies=[
|
||||||
"python",
|
"python",
|
||||||
@@ -132,6 +132,23 @@ decman.config.suppress_command_output = True
|
|||||||
# Make output less verbose. Summaries are still printed.
|
# Make output less verbose. Summaries are still printed.
|
||||||
decman.config.quiet_output = False
|
decman.config.quiet_output = False
|
||||||
|
|
||||||
|
# Decman captures pacman command output, and any line (and adjacent lines) that contains any of
|
||||||
|
# the following keywords (case-insensetive) will be printed after the pacman command finishes.
|
||||||
|
#
|
||||||
|
# REMEMBER: You should still generally pay attention to pacman output
|
||||||
|
# since these keywords may not catch all cases.
|
||||||
|
decman.config.pacman_output_keywords = [
|
||||||
|
"pacsave",
|
||||||
|
"pacnew",
|
||||||
|
# Additional keywords can be:
|
||||||
|
#"warning",
|
||||||
|
#"error",
|
||||||
|
#"note",
|
||||||
|
# They might cause too many highlights however.
|
||||||
|
]
|
||||||
|
# If you don't want to print lines that contain keywords, set this to False
|
||||||
|
decman.config.print_pacman_output_highlights = True
|
||||||
|
|
||||||
# The user which builds aur and user packages.
|
# The user which builds aur and user packages.
|
||||||
# decman.config.makepkg_user = "nobody" # This was set in a previous example. Let's not override it.
|
# decman.config.makepkg_user = "nobody" # This was set in a previous example. Let's not override it.
|
||||||
|
|
||||||
@@ -163,26 +180,30 @@ class MyCommands(decman.config.Commands):
|
|||||||
def list_foreign_pkgs_versioned(self) -> list[str]:
|
def list_foreign_pkgs_versioned(self) -> list[str]:
|
||||||
return ["pacman", "-Qm", "--color=never"]
|
return ["pacman", "-Qm", "--color=never"]
|
||||||
|
|
||||||
|
# --color=always is used in many commands since --color=auto results in no color.
|
||||||
|
# It seems a sensible default for me, since decman already uses color and it can't be disabled.
|
||||||
|
|
||||||
def install_pkgs(self, pkgs: list[str]) -> list[str]:
|
def install_pkgs(self, pkgs: list[str]) -> list[str]:
|
||||||
return ["pacman", "-S", "--needed"] + pkgs
|
return ["pacman", "-S", "--color=always", "--needed"] + pkgs
|
||||||
|
|
||||||
def install_files(self, pkg_files: list[str]) -> list[str]:
|
def install_files(self, pkg_files: list[str]) -> list[str]:
|
||||||
return ["pacman", "-U", "--asdeps"] + pkg_files
|
return ["pacman", "-U", "--color=always", "--asdeps"] + pkg_files
|
||||||
|
|
||||||
def set_as_explicitly_installed(self, pkgs: list[str]) -> list[str]:
|
def set_as_explicitly_installed(self, pkgs: list[str]) -> list[str]:
|
||||||
return ["pacman", "-D", "--asexplicit"] + pkgs
|
return ["pacman", "-D", "--asexplicit"] + pkgs
|
||||||
|
|
||||||
def install_deps(self, deps: list[str]) -> list[str]:
|
def install_deps(self, deps: list[str]) -> list[str]:
|
||||||
return ["pacman", "-S", "--needed", "--asdeps"] + deps
|
return ["pacman", "-S", "--color=always", "--needed", "--asdeps"
|
||||||
|
] + deps
|
||||||
|
|
||||||
def is_installable(self, pkg: str) -> list[str]:
|
def is_installable(self, pkg: str) -> list[str]:
|
||||||
return ["pacman", "-Sddp", pkg]
|
return ["pacman", "-Sddp", pkg]
|
||||||
|
|
||||||
def upgrade(self) -> list[str]:
|
def upgrade(self) -> list[str]:
|
||||||
return ["pacman", "-Syu"]
|
return ["pacman", "-Syu", "--color=always"]
|
||||||
|
|
||||||
def remove(self, pkgs: list[str]) -> list[str]:
|
def remove(self, pkgs: list[str]) -> list[str]:
|
||||||
return ["pacman", "-Rs"] + pkgs
|
return ["pacman", "-Rs", "--color=always"] + pkgs
|
||||||
|
|
||||||
def enable_units(self, units: list[str]) -> list[str]:
|
def enable_units(self, units: list[str]) -> list[str]:
|
||||||
return ["systemctl", "enable"] + units
|
return ["systemctl", "enable"] + units
|
||||||
@@ -209,6 +230,9 @@ class MyCommands(decman.config.Commands):
|
|||||||
def git_get_commit_id(self) -> list[str]:
|
def git_get_commit_id(self) -> list[str]:
|
||||||
return ["git", "rev-parse", "HEAD"]
|
return ["git", "rev-parse", "HEAD"]
|
||||||
|
|
||||||
|
def git_log_commit_ids(self) -> list[str]:
|
||||||
|
return ["git", "log", "--format=format:%H"]
|
||||||
|
|
||||||
def review_file(self, file: str) -> list[str]:
|
def review_file(self, file: str) -> list[str]:
|
||||||
return ["less", file]
|
return ["less", file]
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "decman"
|
name = "decman"
|
||||||
version = "0.2.1"
|
version = "0.3.1"
|
||||||
description = "Declarative package & configuration manager for Arch Linux."
|
description = "Declarative package & configuration manager for Arch Linux."
|
||||||
license = {file = "LICENSE"}
|
license = {file = "LICENSE"}
|
||||||
authors = [
|
authors = [
|
||||||
|
|||||||
+23
-6
@@ -45,26 +45,27 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
Running this command installs the given packages from pacman repositories.
|
Running this command installs the given packages from pacman repositories.
|
||||||
"""
|
"""
|
||||||
return ["pacman", "-S", "--needed"] + pkgs
|
return ["pacman", "-S", "--color=always", "--needed"] + pkgs
|
||||||
|
|
||||||
def install_files(self, pkg_files: list[str]) -> list[str]:
|
def install_files(self, pkg_files: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command installs the given packages files.
|
Running this command installs the given packages files.
|
||||||
"""
|
"""
|
||||||
return ["pacman", "-U", "--asdeps"] + pkg_files
|
return ["pacman", "-U", "--color=always", "--asdeps"] + pkg_files
|
||||||
|
|
||||||
def set_as_explicitly_installed(self, pkgs: list[str]) -> list[str]:
|
def set_as_explicitly_installed(self, pkgs: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command installs sets the given as explicitly installed.
|
Running this command installs sets the given as explicitly installed.
|
||||||
"""
|
"""
|
||||||
return ["pacman", "-D", "--asexplicit"] + pkgs
|
return ["pacman", "-D", "--color=always", "--asexplicit"] + pkgs
|
||||||
|
|
||||||
def install_deps(self, deps: list[str]) -> list[str]:
|
def install_deps(self, deps: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command installs the given packages from pacman repositories.
|
Running this command installs the given packages from pacman repositories.
|
||||||
The packages are installed as dependencies.
|
The packages are installed as dependencies.
|
||||||
"""
|
"""
|
||||||
return ["pacman", "-S", "--needed", "--asdeps"] + deps
|
return ["pacman", "-S", "--color=always", "--needed", "--asdeps"
|
||||||
|
] + deps
|
||||||
|
|
||||||
def is_installable(self, pkg: str) -> list[str]:
|
def is_installable(self, pkg: str) -> list[str]:
|
||||||
"""
|
"""
|
||||||
@@ -76,14 +77,14 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
Running this command upgrades all pacman packages.
|
Running this command upgrades all pacman packages.
|
||||||
"""
|
"""
|
||||||
return ["pacman", "-Syu"]
|
return ["pacman", "-Syu", "--color=always"]
|
||||||
|
|
||||||
def remove(self, pkgs: list[str]) -> list[str]:
|
def remove(self, pkgs: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command removes the given packages and their dependencies
|
Running this command removes the given packages and their dependencies
|
||||||
(that aren't required by other packages).
|
(that aren't required by other packages).
|
||||||
"""
|
"""
|
||||||
return ["pacman", "-Rs"] + pkgs
|
return ["pacman", "-Rs", "--color=always"] + pkgs
|
||||||
|
|
||||||
def enable_units(self, units: list[str]) -> list[str]:
|
def enable_units(self, units: list[str]) -> list[str]:
|
||||||
"""
|
"""
|
||||||
@@ -135,6 +136,12 @@ class Commands:
|
|||||||
"""
|
"""
|
||||||
return ["git", "rev-parse", "HEAD"]
|
return ["git", "rev-parse", "HEAD"]
|
||||||
|
|
||||||
|
def git_log_commit_ids(self) -> list[str]:
|
||||||
|
"""
|
||||||
|
Running this command outputs commit hashes of the repository.
|
||||||
|
"""
|
||||||
|
return ["git", "log", "--format=format:%H"]
|
||||||
|
|
||||||
def review_file(self, file: str) -> list[str]:
|
def review_file(self, file: str) -> list[str]:
|
||||||
"""
|
"""
|
||||||
Running this command outputs a file for the user to see.
|
Running this command outputs a file for the user to see.
|
||||||
@@ -199,6 +206,16 @@ valid_pkgexts: list[str] = [
|
|||||||
".pkg.tar.Z",
|
".pkg.tar.Z",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
pacman_output_keywords: list[str] = [
|
||||||
|
"pacsave",
|
||||||
|
"pacnew",
|
||||||
|
# These cause too many false positives IMO
|
||||||
|
#"warning",
|
||||||
|
#"error",
|
||||||
|
#"note",
|
||||||
|
]
|
||||||
|
print_pacman_output_highlights: bool = True
|
||||||
|
|
||||||
makepkg_user: str = "nobody"
|
makepkg_user: str = "nobody"
|
||||||
build_dir: str = "/tmp/decman/build"
|
build_dir: str = "/tmp/decman/build"
|
||||||
pkg_cache_dir: str = "/var/cache/decman"
|
pkg_cache_dir: str = "/var/cache/decman"
|
||||||
|
|||||||
+125
-19
@@ -2,7 +2,8 @@
|
|||||||
Library module for decman.
|
Library module for decman.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pwd
|
import threading
|
||||||
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
@@ -755,14 +756,23 @@ class Pacman:
|
|||||||
if not packages:
|
if not packages:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
returncode, output = echo_and_capture_command(
|
||||||
|
conf.commands.install_pkgs(packages))
|
||||||
|
if returncode != 0:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
f"Failed to install packages using pacman. Process exited with code {returncode}."
|
||||||
|
)
|
||||||
|
if conf.print_pacman_output_highlights:
|
||||||
|
print_highlighted_pacman_messages(output)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subprocess.run(conf.commands.install_pkgs(packages), check=True)
|
|
||||||
subprocess.run(conf.commands.set_as_explicitly_installed(packages),
|
subprocess.run(conf.commands.set_as_explicitly_installed(packages),
|
||||||
check=True,
|
check=True,
|
||||||
capture_output=conf.suppress_command_output)
|
capture_output=conf.suppress_command_output)
|
||||||
except subprocess.CalledProcessError as error:
|
except subprocess.CalledProcessError as error:
|
||||||
raise err.UserFacingError(
|
raise err.UserFacingError(
|
||||||
"Failed to install packages using pacman.") from error
|
"Failed to set packages as explicitly installed using pacman."
|
||||||
|
) from error
|
||||||
|
|
||||||
def install_dependencies(self, deps: list[str]):
|
def install_dependencies(self, deps: list[str]):
|
||||||
"""
|
"""
|
||||||
@@ -771,12 +781,14 @@ class Pacman:
|
|||||||
if not deps:
|
if not deps:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
returncode, output = echo_and_capture_command(
|
||||||
subprocess.run(conf.commands.install_deps(deps), check=True)
|
conf.commands.install_deps(deps))
|
||||||
except subprocess.CalledProcessError as error:
|
if returncode != 0:
|
||||||
raise err.UserFacingError(
|
raise err.UserFacingError(
|
||||||
"Failed to install packages as dependencies using pacman."
|
f"Failed to install packages as dependencies using pacman. Process exited with code {returncode}."
|
||||||
) from error
|
)
|
||||||
|
if conf.print_pacman_output_highlights:
|
||||||
|
print_highlighted_pacman_messages(output)
|
||||||
|
|
||||||
def install_files(self, files: list[str], as_explicit: list[str]):
|
def install_files(self, files: list[str], as_explicit: list[str]):
|
||||||
"""
|
"""
|
||||||
@@ -786,9 +798,16 @@ class Pacman:
|
|||||||
if not files:
|
if not files:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
returncode, output = echo_and_capture_command(
|
||||||
subprocess.run(conf.commands.install_files(files), check=True)
|
conf.commands.install_files(files))
|
||||||
|
if returncode != 0:
|
||||||
|
raise err.UserFacingError(
|
||||||
|
f"Failed to install package files using pacman. Process exited with code {returncode}."
|
||||||
|
)
|
||||||
|
if conf.print_pacman_output_highlights:
|
||||||
|
print_highlighted_pacman_messages(output)
|
||||||
|
|
||||||
|
try:
|
||||||
if as_explicit:
|
if as_explicit:
|
||||||
subprocess.run(
|
subprocess.run(
|
||||||
conf.commands.set_as_explicitly_installed(as_explicit),
|
conf.commands.set_as_explicitly_installed(as_explicit),
|
||||||
@@ -799,17 +818,20 @@ class Pacman:
|
|||||||
print_error("Output:")
|
print_error("Output:")
|
||||||
print_continuation(error.output)
|
print_continuation(error.output)
|
||||||
raise err.UserFacingError(
|
raise err.UserFacingError(
|
||||||
"Failed to install package files using pacman.") from error
|
"Failed to set packages as explicitly installed using pacman."
|
||||||
|
) from error
|
||||||
|
|
||||||
def upgrade(self):
|
def upgrade(self):
|
||||||
"""
|
"""
|
||||||
Upgrades all packages.
|
Upgrades all packages.
|
||||||
"""
|
"""
|
||||||
try:
|
returncode, output = echo_and_capture_command(conf.commands.upgrade())
|
||||||
subprocess.run(conf.commands.upgrade(), check=True)
|
if returncode != 0:
|
||||||
except subprocess.CalledProcessError as error:
|
|
||||||
raise err.UserFacingError(
|
raise err.UserFacingError(
|
||||||
"Failed to upgrade packages using pacman.") from error
|
f"Failed to upgrade packages using pacman. Process exited with code {returncode}."
|
||||||
|
)
|
||||||
|
if conf.print_pacman_output_highlights:
|
||||||
|
print_highlighted_pacman_messages(output)
|
||||||
|
|
||||||
def remove(self, packages: list[str]):
|
def remove(self, packages: list[str]):
|
||||||
"""
|
"""
|
||||||
@@ -817,11 +839,95 @@ class Pacman:
|
|||||||
"""
|
"""
|
||||||
if not packages:
|
if not packages:
|
||||||
return
|
return
|
||||||
try:
|
|
||||||
subprocess.run(conf.commands.remove(packages), check=True)
|
returncode, output = echo_and_capture_command(
|
||||||
except subprocess.CalledProcessError as error:
|
conf.commands.remove(packages))
|
||||||
|
if returncode != 0:
|
||||||
raise err.UserFacingError(
|
raise err.UserFacingError(
|
||||||
"Failed to remove packages using pacman.") from error
|
f"Failed to remove packages using pacman. Process exited with code {returncode}."
|
||||||
|
)
|
||||||
|
if conf.print_pacman_output_highlights:
|
||||||
|
print_highlighted_pacman_messages(output)
|
||||||
|
|
||||||
|
|
||||||
|
def print_highlighted_pacman_messages(output: str):
|
||||||
|
"""
|
||||||
|
Prints lines that contain pacman output keywords.
|
||||||
|
"""
|
||||||
|
print_summary("Pacman output highlights:")
|
||||||
|
lines = output.split("\n")
|
||||||
|
for index, line in enumerate(lines):
|
||||||
|
for keyword in conf.pacman_output_keywords:
|
||||||
|
if keyword.lower() in line.lower():
|
||||||
|
print_summary(f"lines: {index}-{index+2}")
|
||||||
|
if index >= 1:
|
||||||
|
print_continuation(lines[index - 1])
|
||||||
|
print_continuation(line)
|
||||||
|
if index + 1 < len(lines):
|
||||||
|
print_continuation(lines[index + 1])
|
||||||
|
print_continuation("")
|
||||||
|
|
||||||
|
# Break, as to not print the same line again if it contains multiple keywords
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def echo_and_capture_command(program: list[str]) -> tuple[int, str]:
|
||||||
|
"""
|
||||||
|
Runs the given CLI program and arguments.
|
||||||
|
|
||||||
|
Returns a tuple containing the return code of the program as well as all output of the program.
|
||||||
|
"""
|
||||||
|
with subprocess.Popen(program,
|
||||||
|
stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT) as process:
|
||||||
|
os.set_blocking(process.stdout.fileno(), False)
|
||||||
|
|
||||||
|
output_thread = _OutputCapturingThread(process.stdout)
|
||||||
|
output_thread.start()
|
||||||
|
|
||||||
|
os.set_blocking(sys.stdin.fileno(), False)
|
||||||
|
|
||||||
|
# Capture stdin and forward it to the process in a non-blocking manner
|
||||||
|
while process.poll() is None:
|
||||||
|
inp = sys.stdin.readline()
|
||||||
|
|
||||||
|
if inp:
|
||||||
|
process.stdin.write(inp.encode())
|
||||||
|
process.stdin.flush()
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
os.set_blocking(sys.stdin.fileno(), True)
|
||||||
|
|
||||||
|
output_thread.done = True
|
||||||
|
output_thread.join()
|
||||||
|
|
||||||
|
# Capture any output that may not have been yet captured
|
||||||
|
output = output_thread.output
|
||||||
|
missing_output = process.stdout.read()
|
||||||
|
if missing_output:
|
||||||
|
output += missing_output.decode()
|
||||||
|
|
||||||
|
return (process.returncode, output)
|
||||||
|
|
||||||
|
|
||||||
|
class _OutputCapturingThread(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, stream):
|
||||||
|
super().__init__()
|
||||||
|
self._stream = stream
|
||||||
|
self.output = ""
|
||||||
|
self.done = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
while not self.done and not self._stream.closed:
|
||||||
|
output = self._stream.read()
|
||||||
|
if output:
|
||||||
|
output = output.decode()
|
||||||
|
self.output += output
|
||||||
|
print(output, end="")
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
|
||||||
class Systemd:
|
class Systemd:
|
||||||
|
|||||||
@@ -1078,7 +1078,14 @@ before and thus are found in the cache."
|
|||||||
default=True):
|
default=True):
|
||||||
latest_reviewed_commit = self._store.pkgbuild_latest_reviewed_commits.get(
|
latest_reviewed_commit = self._store.pkgbuild_latest_reviewed_commits.get(
|
||||||
pkgbase)
|
pkgbase)
|
||||||
if latest_reviewed_commit is None:
|
|
||||||
|
git_commit_ids = subprocess.run(
|
||||||
|
conf.commands.git_log_commit_ids(),
|
||||||
|
check=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
).stdout.decode().strip().split('\n')
|
||||||
|
|
||||||
|
if latest_reviewed_commit is None or latest_reviewed_commit not in git_commit_ids:
|
||||||
for file in os.scandir("."):
|
for file in os.scandir("."):
|
||||||
if file.is_file() and not file.name.startswith("."):
|
if file.is_file() and not file.name.startswith("."):
|
||||||
subprocess.run(conf.commands.review_file(
|
subprocess.run(conf.commands.review_file(
|
||||||
|
|||||||
Reference in New Issue
Block a user