sysetup 1.0.26__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sysetup-1.0.26 → sysetup-1.2.0}/LICENSE +1 -1
- sysetup-1.2.0/PKG-INFO +54 -0
- sysetup-1.2.0/README.md +33 -0
- sysetup-1.2.0/pyproject.toml +75 -0
- sysetup-1.2.0/src/sysetup/__init__.py +0 -0
- sysetup-1.2.0/src/sysetup/cli/__init__.py +1 -0
- sysetup-1.2.0/src/sysetup/cli/entry_point.py +6 -0
- sysetup-1.2.0/src/sysetup/context/__init__.py +1 -0
- sysetup-1.2.0/src/sysetup/context/context.py +31 -0
- sysetup-1.2.0/src/sysetup/main/__init__.py +0 -0
- sysetup-1.2.0/src/sysetup/main/environment.py +14 -0
- sysetup-1.2.0/src/sysetup/main/files/__init__.py +1 -0
- sysetup-1.2.0/src/sysetup/main/files/assets.py +40 -0
- sysetup-1.2.0/src/sysetup/main/files/permissions.py +33 -0
- sysetup-1.2.0/src/sysetup/main/files/settings.py +45 -0
- sysetup-1.2.0/src/sysetup/main/files/setup.py +8 -0
- sysetup-1.2.0/src/sysetup/main/installations.py +67 -0
- sysetup-1.2.0/src/sysetup/main/main.py +30 -0
- sysetup-1.2.0/src/sysetup/main/packages.py +60 -0
- sysetup-1.2.0/src/sysetup/models/__init__.py +3 -0
- sysetup-1.2.0/src/sysetup/models/action.py +9 -0
- sysetup-1.2.0/src/sysetup/models/options.py +11 -0
- {sysetup-1.0.26/sysetup → sysetup-1.2.0/src/sysetup/models}/path.py +9 -10
- sysetup-1.2.0/src/sysetup/py.typed +0 -0
- sysetup-1.2.0/src/sysetup/utils/__init__.py +1 -0
- sysetup-1.2.0/src/sysetup/utils/download.py +12 -0
- sysetup-1.2.0/src/sysetup.egg-info/PKG-INFO +54 -0
- sysetup-1.2.0/src/sysetup.egg-info/SOURCES.txt +37 -0
- sysetup-1.2.0/src/sysetup.egg-info/entry_points.txt +3 -0
- sysetup-1.2.0/src/sysetup.egg-info/requires.txt +11 -0
- sysetup-1.2.0/tests/test_background.py +65 -0
- sysetup-1.2.0/tests/test_cli_entry_point.py +11 -0
- sysetup-1.2.0/tests/test_installer.py +14 -0
- sysetup-1.2.0/tests/test_main.py +11 -0
- sysetup-1.0.26/PKG-INFO +0 -45
- sysetup-1.0.26/README.md +0 -24
- sysetup-1.0.26/pyproject.toml +0 -58
- sysetup-1.0.26/sysetup/__init__.py +0 -1
- sysetup-1.0.26/sysetup/env.py +0 -17
- sysetup-1.0.26/sysetup/files.py +0 -98
- sysetup-1.0.26/sysetup/installer.py +0 -177
- sysetup-1.0.26/sysetup/main.py +0 -36
- sysetup-1.0.26/sysetup.egg-info/PKG-INFO +0 -45
- sysetup-1.0.26/sysetup.egg-info/SOURCES.txt +0 -19
- sysetup-1.0.26/sysetup.egg-info/entry_points.txt +0 -3
- sysetup-1.0.26/sysetup.egg-info/requires.txt +0 -13
- sysetup-1.0.26/tests/test_background.py +0 -38
- sysetup-1.0.26/tests/test_installer.py +0 -17
- {sysetup-1.0.26 → sysetup-1.2.0}/bin/pw +0 -0
- /sysetup-1.0.26/bin/pw_askpass → /sysetup-1.2.0/bin/pw-askpass +0 -0
- {sysetup-1.0.26 → sysetup-1.2.0}/setup.cfg +0 -0
- {sysetup-1.0.26 → sysetup-1.2.0/src}/sysetup.egg-info/dependency_links.txt +0 -0
- {sysetup-1.0.26 → sysetup-1.2.0/src}/sysetup.egg-info/top_level.txt +0 -0
sysetup-1.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: sysetup
|
|
3
|
+
Version: 1.2.0
|
|
4
|
+
Summary: Personal system setup
|
|
5
|
+
Author-email: Quinten Roets <qdr2104@columbia.edu>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Source Code, https://github.com/quintenroets/sysetup
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: backupmaster<2,>=1.2.6
|
|
12
|
+
Requires-Dist: dbus-next<1,>=0.2.3
|
|
13
|
+
Requires-Dist: package-utils[context]<1,>=0.6.1
|
|
14
|
+
Requires-Dist: powercli<1,>=0.3.1
|
|
15
|
+
Requires-Dist: python-dotenv<2,>=1.0.1
|
|
16
|
+
Requires-Dist: requests<3,>=2.32.3
|
|
17
|
+
Requires-Dist: superpathlib<3,>=2.0.4
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: package-dev-tools<1,>=0.5.11; extra == "dev"
|
|
20
|
+
Requires-Dist: package-dev-utils<1,>=0.1.6; extra == "dev"
|
|
21
|
+
|
|
22
|
+
# Sysetup
|
|
23
|
+
[](https://badge.fury.io/py/sysetup)
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
## [Plasma](https://kde.org/plasma-desktop/) 5.22 required
|
|
28
|
+
|
|
29
|
+
[Setup info](docs/setup-plasma.md)
|
|
30
|
+
|
|
31
|
+
## Setup steps
|
|
32
|
+
1) Run
|
|
33
|
+
```shell
|
|
34
|
+
wget -O - https://raw.githubusercontent.com/quintenroets/sysetup/main/bin/setup | bash
|
|
35
|
+
```
|
|
36
|
+
give rclone password when prompted
|
|
37
|
+
2) Appearance
|
|
38
|
+
* Set wallpaper
|
|
39
|
+
* Select We10OSX Cursors
|
|
40
|
+
3) Configure autocpufreq
|
|
41
|
+
4) Setup Chrome
|
|
42
|
+
* Enable GPU acceleration in chrome://flags
|
|
43
|
+
* PDF viewer: set page zoom to page fit
|
|
44
|
+
* Import certificate from Scripts/assets/sysetup/certificates/certificate.crt
|
|
45
|
+
* Click experimental: enable tab groups save and sync
|
|
46
|
+
5) Login to
|
|
47
|
+
* Pycharm professional
|
|
48
|
+
* VNC Server
|
|
49
|
+
6) For new device: set touchpad scroll direction and click on touch
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
```shell
|
|
53
|
+
pip install sysetup
|
|
54
|
+
```
|
sysetup-1.2.0/README.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Sysetup
|
|
2
|
+
[](https://badge.fury.io/py/sysetup)
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+
## [Plasma](https://kde.org/plasma-desktop/) 5.22 required
|
|
7
|
+
|
|
8
|
+
[Setup info](docs/setup-plasma.md)
|
|
9
|
+
|
|
10
|
+
## Setup steps
|
|
11
|
+
1) Run
|
|
12
|
+
```shell
|
|
13
|
+
wget -O - https://raw.githubusercontent.com/quintenroets/sysetup/main/bin/setup | bash
|
|
14
|
+
```
|
|
15
|
+
give rclone password when prompted
|
|
16
|
+
2) Appearance
|
|
17
|
+
* Set wallpaper
|
|
18
|
+
* Select We10OSX Cursors
|
|
19
|
+
3) Configure autocpufreq
|
|
20
|
+
4) Setup Chrome
|
|
21
|
+
* Enable GPU acceleration in chrome://flags
|
|
22
|
+
* PDF viewer: set page zoom to page fit
|
|
23
|
+
* Import certificate from Scripts/assets/sysetup/certificates/certificate.crt
|
|
24
|
+
* Click experimental: enable tab groups save and sync
|
|
25
|
+
5) Login to
|
|
26
|
+
* Pycharm professional
|
|
27
|
+
* VNC Server
|
|
28
|
+
6) For new device: set touchpad scroll direction and click on touch
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
```shell
|
|
32
|
+
pip install sysetup
|
|
33
|
+
```
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sysetup"
|
|
3
|
+
version = "1.2.0"
|
|
4
|
+
description = "Personal system setup"
|
|
5
|
+
authors = [{name = "Quinten Roets", email = "qdr2104@columbia.edu"}]
|
|
6
|
+
license = {text = "MIT"}
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.10"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"backupmaster >=1.2.6, <2",
|
|
11
|
+
"dbus-next >=0.2.3, <1",
|
|
12
|
+
"package-utils[context] >=0.6.1, <1",
|
|
13
|
+
"powercli >=0.3.1, <1",
|
|
14
|
+
"python-dotenv >=1.0.1, <2",
|
|
15
|
+
"requests >=2.32.3, <3",
|
|
16
|
+
"superpathlib >=2.0.4, <3",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
dev = [
|
|
21
|
+
"package-dev-tools >=0.5.11, <1",
|
|
22
|
+
"package-dev-utils >=0.1.6, <1",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
"Source Code" = "https://github.com/quintenroets/sysetup"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
sysetup = "sysetup.cli:entry_point"
|
|
30
|
+
exportcrontab = "sysetup.main.files.assets:move_crontab"
|
|
31
|
+
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["setuptools"]
|
|
34
|
+
build-backend = "setuptools.build_meta"
|
|
35
|
+
|
|
36
|
+
[tool.coverage.run]
|
|
37
|
+
command_line = "-m pytest tests"
|
|
38
|
+
|
|
39
|
+
[tool.coverage.report]
|
|
40
|
+
precision = 4
|
|
41
|
+
fail_under = 60
|
|
42
|
+
|
|
43
|
+
[tool.mypy]
|
|
44
|
+
strict = true
|
|
45
|
+
no_implicit_reexport = false
|
|
46
|
+
|
|
47
|
+
[tool.pytest.ini_options]
|
|
48
|
+
pythonpath = [
|
|
49
|
+
"src", ".",
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
[tool.ruff]
|
|
53
|
+
fix = true
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint]
|
|
56
|
+
select = ["ALL"]
|
|
57
|
+
ignore = [
|
|
58
|
+
"ANN101", # annotate self
|
|
59
|
+
"ANN102", # annotate cls
|
|
60
|
+
"ANN401", # annotated with Any
|
|
61
|
+
"D", # docstrings
|
|
62
|
+
"S101", # assert used
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[tool.ruff.lint.isort]
|
|
66
|
+
known-first-party = ["src"]
|
|
67
|
+
|
|
68
|
+
[tool.ruff.lint.per-file-ignores]
|
|
69
|
+
"__init__.py" = ["F401"]
|
|
70
|
+
|
|
71
|
+
[tool.setuptools]
|
|
72
|
+
script-files = ["bin/pw", "bin/pw-askpass"]
|
|
73
|
+
|
|
74
|
+
[tool.setuptools.package-data]
|
|
75
|
+
sysetup = ["assets/scripts/update_wallpaper.js", "py.typed"]
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .entry_point import entry_point
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .context import Context, context
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from collections.abc import Iterator
|
|
3
|
+
from functools import cached_property
|
|
4
|
+
|
|
5
|
+
import cli
|
|
6
|
+
from package_utils.context import Context as Context_
|
|
7
|
+
|
|
8
|
+
from sysetup.models import Options
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Context(Context_[Options, None, None]):
|
|
12
|
+
@cached_property
|
|
13
|
+
def package_manager(self) -> str:
|
|
14
|
+
def generate_package_manager() -> Iterator[str]:
|
|
15
|
+
package_managers = "apt-get", "pacman"
|
|
16
|
+
for package_manager in package_managers:
|
|
17
|
+
if cli.completes_successfully("which", package_manager):
|
|
18
|
+
yield package_manager
|
|
19
|
+
|
|
20
|
+
return next(generate_package_manager())
|
|
21
|
+
|
|
22
|
+
@cached_property
|
|
23
|
+
def apt_is_installed(self) -> bool:
|
|
24
|
+
return self.package_manager == "apt-get"
|
|
25
|
+
|
|
26
|
+
@cached_property
|
|
27
|
+
def is_running_in_test(self) -> bool:
|
|
28
|
+
return "DISPLAY" not in os.environ
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
context = Context(Options)
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
|
|
5
|
+
from sysetup.models import Path
|
|
6
|
+
from sysetup.utils import download_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def setup() -> None:
|
|
10
|
+
download_file(Path("etc") / "environment")
|
|
11
|
+
if "SUDO_ASKPASS" not in os.environ:
|
|
12
|
+
path = Path.HOME / ".bask_profile"
|
|
13
|
+
download_file(Path.HOME / ".bask_profile")
|
|
14
|
+
load_dotenv(dotenv_path=Path.HOME / path)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .setup import setup
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import cli
|
|
2
|
+
from backup.backups.cache import cache
|
|
3
|
+
|
|
4
|
+
from sysetup.models import Path
|
|
5
|
+
from sysetup.utils import download_directory
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def setup() -> None:
|
|
9
|
+
download_directory(Path.assets)
|
|
10
|
+
move_crontab()
|
|
11
|
+
move_setup_files()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def move_crontab() -> None:
|
|
15
|
+
src = Path.assets / "crontab" / "crontab"
|
|
16
|
+
cli.run("crontab -", input=src.text)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def move_setup_files() -> None:
|
|
20
|
+
setup_files_root = Path.assets / "files"
|
|
21
|
+
setup_files = []
|
|
22
|
+
archived_setup_files = []
|
|
23
|
+
for path in setup_files_root.rglob("*"):
|
|
24
|
+
if path.is_file():
|
|
25
|
+
if path.archive_format is None:
|
|
26
|
+
setup_files.append(path)
|
|
27
|
+
else:
|
|
28
|
+
archived_setup_files.append(path)
|
|
29
|
+
|
|
30
|
+
backup = cache.Backup(paths=setup_files)
|
|
31
|
+
backup.pull()
|
|
32
|
+
|
|
33
|
+
for path in archived_setup_files:
|
|
34
|
+
dest = (backup.source / path.relative_to(setup_files_root)).parent
|
|
35
|
+
if dest.is_root and not dest.exists():
|
|
36
|
+
cli.run("mkdir -p", dest, root=True)
|
|
37
|
+
else:
|
|
38
|
+
dest.create_parent()
|
|
39
|
+
with cli.status(f"Unpacking {path.relative_to(setup_files_root)}"):
|
|
40
|
+
cli.capture_output("unzip -o", path, "-d", dest, root=dest.is_root)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import stat
|
|
2
|
+
|
|
3
|
+
import cli
|
|
4
|
+
|
|
5
|
+
from sysetup.models import Path
|
|
6
|
+
from sysetup.utils import download_directory
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def setup() -> None:
|
|
10
|
+
set_git_permissions()
|
|
11
|
+
set_ssh_permissions()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def set_git_permissions() -> None:
|
|
15
|
+
git_hooks_folder = Path.HOME / ".config" / "git" / "hooks"
|
|
16
|
+
download_directory(git_hooks_folder)
|
|
17
|
+
for path in git_hooks_folder.iterdir():
|
|
18
|
+
cli.run("chmod +x", path)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def set_ssh_permissions() -> None:
|
|
22
|
+
directory = Path.HOME / ".ssh"
|
|
23
|
+
download_directory(directory)
|
|
24
|
+
for path in directory.glob("id_*"):
|
|
25
|
+
if path.suffix != ".pub":
|
|
26
|
+
check_permissions(path)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def check_permissions(path: Path) -> None:
|
|
30
|
+
permissions = path.stat().st_mode
|
|
31
|
+
other_users_can_read = permissions & (stat.S_IRGRP | stat.S_IROTH)
|
|
32
|
+
if other_users_can_read:
|
|
33
|
+
path.chmod(33152)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import cli
|
|
2
|
+
|
|
3
|
+
from sysetup.context import context
|
|
4
|
+
from sysetup.models import Path
|
|
5
|
+
from sysetup.utils import download_directory
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def remove_clutter() -> None:
|
|
9
|
+
names = (
|
|
10
|
+
"Desktop",
|
|
11
|
+
"Downloads",
|
|
12
|
+
"Music",
|
|
13
|
+
"Pictures",
|
|
14
|
+
"Public",
|
|
15
|
+
"Templates",
|
|
16
|
+
"Videos",
|
|
17
|
+
)
|
|
18
|
+
for name in names:
|
|
19
|
+
path = Path.HOME / name
|
|
20
|
+
path.rmtree(missing_ok=True)
|
|
21
|
+
|
|
22
|
+
nginx_path = Path("/") / "etc" / "nginx" / "sites-enabled" / "default"
|
|
23
|
+
if nginx_path.exists():
|
|
24
|
+
cli.run("rm", nginx_path, root=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def set_background() -> None: # pragma: nocover
|
|
28
|
+
wallpaper_path = (
|
|
29
|
+
Path.HOME / ".local" / "share" / "wallpapers" / "Qwallpapers" / "background.jpg"
|
|
30
|
+
)
|
|
31
|
+
download_directory(wallpaper_path.parent)
|
|
32
|
+
wallpaper_uri = wallpaper_path.as_uri()
|
|
33
|
+
script = Path.update_wallpaper_script.text.replace(
|
|
34
|
+
"__wallpaper_uri__",
|
|
35
|
+
wallpaper_uri,
|
|
36
|
+
)
|
|
37
|
+
run_kde_script(script)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def run_kde_script(script: str) -> None: # pragma: nocover
|
|
41
|
+
command = (
|
|
42
|
+
"qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript"
|
|
43
|
+
)
|
|
44
|
+
if not context.is_running_in_test:
|
|
45
|
+
cli.run(command, script)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import cli
|
|
4
|
+
|
|
5
|
+
from sysetup.context import context
|
|
6
|
+
from sysetup.models import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def setup() -> None:
|
|
10
|
+
install_chromium()
|
|
11
|
+
install_jumpapp()
|
|
12
|
+
install_language_support()
|
|
13
|
+
install_linter_env()
|
|
14
|
+
install_personal_git_repositories()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def install_personal_git_repositories() -> None:
|
|
18
|
+
base_url = "https://github.com/quintenroets"
|
|
19
|
+
token = os.getenv("GITHUB", None)
|
|
20
|
+
if token is not None:
|
|
21
|
+
base_url = base_url.replace("github.com", f"{token}@github.com")
|
|
22
|
+
if not Path.extensions.exists():
|
|
23
|
+
command = f"git clone {base_url}/extensions.git"
|
|
24
|
+
cli.run(command, Path.extensions)
|
|
25
|
+
cli.run(f"pip install git+{base_url}/system.git")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def install_language_support() -> None:
|
|
29
|
+
try:
|
|
30
|
+
packages = cli.capture_output("check-language-support")
|
|
31
|
+
except FileNotFoundError:
|
|
32
|
+
pass
|
|
33
|
+
else:
|
|
34
|
+
if packages:
|
|
35
|
+
cli.install(packages)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def install_chromium() -> None:
|
|
39
|
+
if not cli.capture_output("which chromium-browser", check=False):
|
|
40
|
+
_install_chromium()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _install_chromium() -> None:
|
|
44
|
+
release_name = cli.capture_output_lines("lsb_release -sc")[-1]
|
|
45
|
+
repo_url = f"https://freeshell.de/phd/chromium/{release_name}"
|
|
46
|
+
commands = (
|
|
47
|
+
f'echo "deb {repo_url} /" | sudo tee /etc/apt/sources.list.d/phd-chromium.list',
|
|
48
|
+
"apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 869689FE09306074",
|
|
49
|
+
"apt-get update",
|
|
50
|
+
"apt-get install -y chromium",
|
|
51
|
+
)
|
|
52
|
+
check = not context.is_running_in_test
|
|
53
|
+
cli.run_commands(*commands, shell=True, root=True, check=check) # noqa: S604
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def install_linter_env() -> None:
|
|
57
|
+
if not Path.linter_env.exists():
|
|
58
|
+
cli.run("python -m venv", Path.linter_env.name, cwd=Path.linter_env.parent)
|
|
59
|
+
python_path = Path.linter_env / "bin" / "python"
|
|
60
|
+
cli.run(f"{python_path} -m pip install autoimport powertrace-hooks")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def install_jumpapp() -> None:
|
|
64
|
+
if not cli.capture_output("which jumpapp", check=False):
|
|
65
|
+
with Path.tempdir() as directory:
|
|
66
|
+
cli.run("git clone https://github.com/mkropat/jumpapp", directory)
|
|
67
|
+
cli.run_commands("make", "sudo make install", cwd=directory)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import cli
|
|
2
|
+
|
|
3
|
+
from sysetup.context import context
|
|
4
|
+
from sysetup.models import Action
|
|
5
|
+
|
|
6
|
+
from . import environment, files, installations, packages
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main() -> None:
|
|
10
|
+
"""
|
|
11
|
+
Personal system setup.
|
|
12
|
+
"""
|
|
13
|
+
action_mapper = {
|
|
14
|
+
Action.all.value: setup,
|
|
15
|
+
Action.env.value: environment.setup,
|
|
16
|
+
Action.files.value: files.setup,
|
|
17
|
+
Action.install.value: installations.setup,
|
|
18
|
+
Action.packages.value: packages.setup,
|
|
19
|
+
}
|
|
20
|
+
action = action_mapper[context.options.action.value]
|
|
21
|
+
action()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def setup() -> None:
|
|
25
|
+
environment.setup()
|
|
26
|
+
packages.setup()
|
|
27
|
+
files.setup()
|
|
28
|
+
installations.setup()
|
|
29
|
+
if not context.is_running_in_test:
|
|
30
|
+
cli.run("reboot now", root=True)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import cli
|
|
2
|
+
|
|
3
|
+
from sysetup.context import context
|
|
4
|
+
from sysetup.models import Path
|
|
5
|
+
from sysetup.utils import download_directory
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def setup() -> None:
|
|
9
|
+
update_package_manager()
|
|
10
|
+
install_packages()
|
|
11
|
+
cleanup_after_install()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def install_packages() -> None:
|
|
15
|
+
download_directory(Path.packages)
|
|
16
|
+
installations = {"packages": None, "snap": "snap install"}
|
|
17
|
+
for name, command in installations.items():
|
|
18
|
+
path = (Path.packages / name).with_suffix(".yaml")
|
|
19
|
+
packages: list[str] = path.yaml
|
|
20
|
+
cli.install(*packages, install_command=command)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def update_package_manager() -> None:
|
|
24
|
+
if context.apt_is_installed:
|
|
25
|
+
update_apt()
|
|
26
|
+
else:
|
|
27
|
+
cli.run("pacman -Syy", root=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def update_apt() -> None:
|
|
31
|
+
agree_eula_command = (
|
|
32
|
+
"echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula"
|
|
33
|
+
"select true | sudo debconf-set-selections"
|
|
34
|
+
)
|
|
35
|
+
commands = ["sudo apt-get update", agree_eula_command]
|
|
36
|
+
if not context.is_running_in_test:
|
|
37
|
+
# snap currently doesn't work on arm
|
|
38
|
+
commands.append("sudo systemctl enable --now snapd.socket")
|
|
39
|
+
cli.run_commands_in_shell(*commands)
|
|
40
|
+
if not Path("/snap").exists():
|
|
41
|
+
cli.run("ln -s /var/lib/snapd/snap /snap", root=True)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def cleanup_after_install() -> None:
|
|
45
|
+
after_install_command = (
|
|
46
|
+
"sudo apt-get autoremove -y"
|
|
47
|
+
if context.apt_is_installed
|
|
48
|
+
else (
|
|
49
|
+
"sudo pacman -S --noconfirm python-pip; sudo pacman -S --noconfirm"
|
|
50
|
+
" base-devel; pip install wheel"
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
cli.run_commands_in_shell(after_install_command, "sudo tlp start")
|
|
54
|
+
cli.run("systemctl enable ssh", root=True) # start ssh server before log in
|
|
55
|
+
delete = "apt purge -y" if context.apt_is_installed else "pacman -R --noconfirm"
|
|
56
|
+
commands = (
|
|
57
|
+
"auto-cpufreq --install", # Fails on VM
|
|
58
|
+
f"{delete} firefox", # fails if firefox not installed
|
|
59
|
+
)
|
|
60
|
+
cli.run_commands(*commands, check=False, root=True)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
from typing import TypeVar
|
|
1
|
+
from typing import TypeVar, cast
|
|
3
2
|
|
|
4
3
|
import superpathlib
|
|
5
4
|
from simple_classproperty import classproperty
|
|
@@ -11,40 +10,40 @@ class Path(superpathlib.Path):
|
|
|
11
10
|
@classmethod
|
|
12
11
|
@classproperty
|
|
13
12
|
def source_root(cls: type[T]) -> T:
|
|
14
|
-
return cls(__file__).parent
|
|
13
|
+
return cls(__file__).parent.parent
|
|
15
14
|
|
|
16
15
|
@classmethod
|
|
17
16
|
@classproperty
|
|
18
17
|
def assets(cls: type[T]) -> T:
|
|
19
18
|
path = cls.script_assets / cls.source_root.name
|
|
20
|
-
return
|
|
19
|
+
return cast(T, path)
|
|
21
20
|
|
|
22
21
|
@classmethod
|
|
23
22
|
@classproperty
|
|
24
23
|
def config(cls: type[T]) -> T:
|
|
25
24
|
path = cls.assets / "config" / "config.yaml"
|
|
26
|
-
return
|
|
25
|
+
return cast(T, path)
|
|
27
26
|
|
|
28
27
|
@classmethod
|
|
29
28
|
@classproperty
|
|
30
29
|
def packages(cls: type[T]) -> T:
|
|
31
30
|
path = cls.assets / "packages"
|
|
32
|
-
return
|
|
31
|
+
return cast(T, path)
|
|
33
32
|
|
|
34
33
|
@classmethod
|
|
35
34
|
@classproperty
|
|
36
35
|
def linter_env(cls: type[T]) -> T:
|
|
37
|
-
path =
|
|
38
|
-
return
|
|
36
|
+
path = Path.HOME / ".local" / "share" / "envs" / "linterenv"
|
|
37
|
+
return cast(T, path)
|
|
39
38
|
|
|
40
39
|
@classmethod
|
|
41
40
|
@classproperty
|
|
42
41
|
def extensions(cls: type[T]) -> T:
|
|
43
42
|
path = cls.HOME / ".local" / "share" / "extensions"
|
|
44
|
-
return
|
|
43
|
+
return cast(T, path)
|
|
45
44
|
|
|
46
45
|
@classmethod
|
|
47
46
|
@classproperty
|
|
48
47
|
def update_wallpaper_script(cls: type[T]) -> T:
|
|
49
48
|
path = cls.source_root / "assets" / "scripts" / "update_wallpaper.js"
|
|
50
|
-
return
|
|
49
|
+
return cast(T, path)
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .download import download_directory, download_file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from backup.backups import Backup
|
|
2
|
+
from backup.models import Path as BackupPath
|
|
3
|
+
|
|
4
|
+
from sysetup.models import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def download_directory(path: Path) -> None:
|
|
8
|
+
Backup(sub_check_path=BackupPath(path), confirm=False).pull()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def download_file(path: Path) -> None:
|
|
12
|
+
Backup(path=BackupPath(path), confirm=False).pull()
|