Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 2 additions & 69 deletions dpm.py
Original file line number Diff line number Diff line change
@@ -1,72 +1,5 @@
#!/usr/bin/env python3

import argparse
import subprocess
import sys
import dpm

import dpm.store
from dpm.types import Needs, Provides
import dpm.pkg_definition
import logging

parser = argparse.ArgumentParser(
prog="DPM",
description="The Package Manager of last Resort",
)

parser.add_argument("-v", "--verbose", action="store_true")


subparsers = parser.add_subparsers(dest="subparser_name")
parser_install = subparsers.add_parser("install")

parser_install.add_argument("-r", "--required", action="append")
parser_install.add_argument("-f", "--forbidden", action="append")
parser_install.add_argument("STORE")
parser_install.add_argument("PKG")

parser_uninstall = subparsers.add_parser("uninstall")

parser_uninstall.add_argument("STORE")
parser_uninstall.add_argument("PKG")

parser_stored = subparsers.add_parser("stored")

parser_stored.add_argument("STORE")

parser_shell = subparsers.add_parser("shell")

parser_shell.add_argument("STORE")
parser_shell.add_argument("PKG", nargs="*", action="append")
args = parser.parse_args()

logger = logging.getLogger("dpm")
if args.verbose:
print("Setting verbose!")
logging.basicConfig(level=logging.INFO)
if args.subparser_name == "install":
required_variants = args.required
forbidden_variants = args.forbidden
store = dpm.store.Store(args.STORE)
store.install(Needs(args.PKG, required_variants, forbidden_variants))
sys.exit(0)

if args.subparser_name == "uninstall":
store = dpm.store.Store(args.STORE)
store.uninstall(Provides(args.PKG))
sys.exit(1)

if args.subparser_name == "stored":
store = dpm.store.Store(args.STORE)
store.stored()
sys.exit(0)

if args.subparser_name == "shell":
store = dpm.store.Store(args.STORE)
env = dpm.pkg_definition.Environment(store)

for pkg in args.PKG[0]:
print(f"Registering {pkg}")
env.register_package(Needs(pkg))
print(env.to_dict())
subprocess.run(["bash"], env=env.to_dict(), check=False)
dpm.main()
91 changes: 91 additions & 0 deletions dpm/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import argparse
import logging
import subprocess
import sys

import dpm.pkg_definition
import dpm.store
from dpm.types import Needs, Provides


def main():
parser = argparse.ArgumentParser(
prog="DPM",
description="The Package Manager of last Resort",
)

parser.add_argument("-v", "--verbose", action="store_true")

subparsers = parser.add_subparsers(dest="subparser_name")
parser_install = subparsers.add_parser("install")

parser_install.add_argument("-r", "--required", action="append")
parser_install.add_argument("-f", "--forbidden", action="append")
parser_install.add_argument("--repo", default="")
parser_install.add_argument("STORE")
parser_install.add_argument("PKG")

parser_uninstall = subparsers.add_parser("uninstall")

parser_uninstall.add_argument("STORE")
parser_uninstall.add_argument("PKG")

parser_reinstall = subparsers.add_parser("reinstall")
parser_reinstall.add_argument("-r", "--required", action="append")
parser_reinstall.add_argument("-f", "--forbidden", action="append")
parser_reinstall.add_argument("--repo", default="")
parser_reinstall.add_argument("STORE")
parser_reinstall.add_argument("PKG")

parser_stored = subparsers.add_parser("stored")

parser_stored.add_argument("STORE")

parser_shell = subparsers.add_parser("shell")

parser_shell.add_argument("STORE")
parser_shell.add_argument("PKG", nargs="*", action="append")
args = parser.parse_args()

logger = logging.getLogger("dpm")
if args.verbose:
print("Setting verbose!")
logging.basicConfig(level=logging.INFO)
if args.subparser_name == "install":
required_variants = args.required
forbidden_variants = args.forbidden
store = dpm.store.Store(args.STORE, args.repo)
store.install(Needs(args.PKG, required_variants, forbidden_variants))
sys.exit(0)

if args.subparser_name == "uninstall":
store = dpm.store.Store(args.STORE)
store.uninstall(Provides(args.PKG))
sys.exit(1)

if args.subparser_name == "reinstall":
required_variants = args.required
forbidden_variants = args.forbidden
store = dpm.store.Store(args.STORE, args.repo)
store.uninstall(Provides(args.PKG))
store.install(Needs(args.PKG, required_variants, forbidden_variants))
sys.exit(0)

if args.subparser_name == "stored":
store = dpm.store.Store(args.STORE)
store.stored()
sys.exit(0)

if args.subparser_name == "shell":
store = dpm.store.Store(args.STORE)
env = dpm.pkg_definition.Environment(store)

for pkg in args.PKG[0]:
print(f"Registering {pkg}")
env.register_package(Needs(pkg))
print(env.to_dict())
subprocess.run(["bash"], env=env.to_dict(), check=False)


if __name__ == "__main__":
main()
9 changes: 1 addition & 8 deletions dpm/downloader/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,6 @@ def __init__(self, pkg, filename: str):
self.filename: str = filename

def download(self) -> None:
res_path = (
pathlib.Path(__file__).parent
/ ".."
/ "repo"
/ self.pkg.name
/ "misc"
/ self.filename
)
res_path = self.pkg.repo / self.pkg.name / "misc" / self.filename

self.pkg.tmpdir_execute(["cp", res_path, "."])
15 changes: 8 additions & 7 deletions dpm/pkg_definition/recipe.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
from __future__ import annotations

import json
import logging
import pathlib
import shutil
import subprocess
import pathlib
import uuid
import logging
import json

from typing import TYPE_CHECKING

from .environment import Environment
from .aspect import Aspect
from dpm.types import Needs, Forbids, Provides, Package
from dpm.downloader import Resource
from dpm.types import Forbids, Needs, Package, Provides

from .aspect import Aspect
from .environment import Environment

if TYPE_CHECKING:
from store import Store
Expand Down
1 change: 0 additions & 1 deletion dpm/repo/python_wrapper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from dpm.pkg_definition import WrapperPackageRecipe

from dpm.types import Provides


Expand Down
44 changes: 33 additions & 11 deletions dpm/store/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from __future__ import annotations

import importlib
import importlib.util
import json
import logging
import pathlib
import shutil
from typing import TYPE_CHECKING
Expand All @@ -15,26 +16,34 @@

from dpm.types import Package

logger = logging.getLogger("dpm")


class Store:
def __init__(self, path: str):
def __init__(self, path: str, repo: str = ""):
self.path = pathlib.Path(path).absolute()
if not self.path.is_dir():
print("Store", self.path, " does not exists yet, creating")
self.path.mkdir()

if repo:
logger.info(f"Using repo {repo}")
self.repo = pathlib.Path(repo).absolute()
else:
logger.info(f"Using default repo")
self.repo = pathlib.Path(__file__).parent.parent.resolve() / "repo"
self._solver: dpm.solver.Solver = dpm.solver.Solver(self)

def get_installed_packages(self) -> list[Package]:
return [Package(file.name) for file in self.path.iterdir() if file.is_dir()]

def get_all_packages(self) -> list[Package]:
return [
Package(file.name)
for file in (
pathlib.Path(__file__).parent.parent.resolve() / "repo"
).iterdir()
Package(file.name, self.repo)
for file in self.path.iterdir()
if file.is_dir()
]

def get_all_packages(self) -> list[Package]:
return [Package(file.name, self.repo) for file in (self.repo).iterdir()]

def is_installed(self, pkg: Package) -> bool:
return (self.path / pkg.pkg).is_dir()

Expand All @@ -50,11 +59,24 @@ def stored(self):
else:
print(f"{r.name} +{r.required_variants} -{r.forbidden_variants}")

def get_package_mod(self, pkg):
logger.debug(f"Loading package module for {pkg.pkg} from {self.repo / pkg.pkg}")
spec = importlib.util.spec_from_file_location(
"dpm.repo." + pkg.pkg, self.repo / pkg.pkg / "__init__.py"
)
logger.debug(f"Spec info {spec}")
if spec:
package_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(package_mod)
else:
raise RuntimeError(f"Failed to load spec for {pkg.pkg}")
return package_mod

def get_recipe(self, pkg: Package) -> BasePackageRecipe:
if self.is_installed(pkg):
try:
spec_file = (self.path / f"{pkg.pkg}.spec").open("r")
package_mod = importlib.import_module("dpm.repo." + pkg.pkg)
package_mod = self.get_package_mod(pkg)
r = package_mod.PackageRecipe(self, pkg.pkg)
spec = json.load(spec_file)
for v in spec["required_variants"]:
Expand All @@ -67,7 +89,7 @@ def get_recipe(self, pkg: Package) -> BasePackageRecipe:
if dpm.helpers.yes_no():
shutil.rmtree(self.path / pkg.pkg)

package_mod = importlib.import_module("dpm.repo." + pkg.pkg)
package_mod = self.get_package_mod(pkg)
return package_mod.PackageRecipe(self, pkg.pkg)

def resolve(self, need: Needs) -> BasePackageRecipe:
Expand Down
7 changes: 3 additions & 4 deletions dpm/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
Expand All @@ -23,9 +24,6 @@ def __hash__(self):
def __str__(self):
return f"Provides: {self.name}"

def as_package(self) -> "Package":
return Package(self.name)

def as_needs(self) -> Needs:
return Needs(self.name)

Expand Down Expand Up @@ -126,8 +124,9 @@ def flatten(self):


class Package:
def __init__(self, pkg: str):
def __init__(self, pkg: str, repo: Path = Path()):
self.pkg = pkg
self.repo = repo

def __eq__(self, other) -> bool:
if not isinstance(other, Package):
Expand Down
21 changes: 21 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[build-system]
requires = ["setuptools >= 77.0.3"]
build-backend = "setuptools.build_meta"

[project]
name = "dpm"
version = "0.0.1"
dependencies = []
authors = [
{name = "Andreas Gocht-Zech", email = "andreas.gocht-zech@sva.de"},
{name = "Christian von Elm", email = "cvonelm@cvonelm.de"},
]
maintainers = [
{name = "Christian von Elm", email = "cvonelm@cvonelm.de"}
]

[project.scripts]
dpm = "dpm:main"

[tool.setuptools.packages.find]
include = ["dpm*"]