Skip to content

Commit 6c02ba3

Browse files
committed
Add possibility for user to fetch specific packages from other sources
- config right now for parsing packages, which should be installed from sources where they normally would not be installed from see: #23 Add possibility for user to fetch specific packages from other sources see: #23 Append aurman config to README Explain the possibility of how to choose an explicit source for a package in case of multiple available sources see: #23 Add newlines to README Fix typo in README Do not forget already ignored things Add --do_everything Flag so that aurman handles also -u for repo packages Merge branch 'other_repos' into develop
1 parent f6908f1 commit 6c02ba3

File tree

7 files changed

+276
-34
lines changed

7 files changed

+276
-34
lines changed

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,38 @@ you may specify more than one package, space separated
7373

7474
- `--holdpkg_conf`: append packages from the pacman.conf to `--holdpkg`
7575

76+
- `--do_everything`: `-u` for repo packages will also be handled by `aurman`, not by `pacman`.
77+
may be useful if you are using the `aurman` config to fetch repo packages from other repos than they would normally be installed from.
78+
this is in general **not** recommended!
79+
80+
## Config
81+
You may use the file `aurman_config` under `$XDG_CONFIG_HOME/aurman` (fallback to `~/.config/aurman` in case of no `$XDG_CONFIG_HOME`) as config for aurman.
82+
83+
### config options
84+
#### choose between multiple package sources
85+
By default `aurman` assumes the following priorities in case of multiple available packages with the same names (high to low):
86+
- repository package as listed in the pacman.conf - see https://www.archlinux.org/pacman/pacman.conf.5.html#_repository_sections
87+
> The order of repositories in the configuration files matters; repositories listed first will take precedence over those listed later in the file when packages in two repositories have identical names, regardless of version number.
88+
- aur packages
89+
90+
If one wants to override this priority, it has to be done via the aurman config.
91+
92+
For aur packages create a section `[aur_packages]` and list the names of the aur packages.
93+
94+
For repo packages create a section `[repo_packages]` and list the names of the repo packages followed by `=` and the name of the repo.
95+
96+
Example:
97+
```ini
98+
[aur_packages]
99+
aur_package_name
100+
other_aur_package_name
101+
102+
[repo_packages]
103+
repo_package_name=repo_one
104+
other_repo_package_name=repo_two
105+
```
106+
107+
76108
## Features
77109

78110
- threaded sudo loop in the background so you only have to enter your password once
@@ -84,6 +116,7 @@ you may specify more than one package, space separated
84116
- let the user see and edit all needed PKGBUILDs before any of the building of AUR packages starts
85117
- fetching of needed pgp keys for package building
86118
- pacman --search for repo and aur packages (aur results sorted by popularity)
119+
- differentiate between the possible sources to install packages from in case of same names in different known repos and/or the aur
87120

88121
## Dependency solving description including benchmarks
89122
https://github.com/polygamma/aurman/wiki/Description-of-the-aurman-dependency-solving

src/aurman/classes.py

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from aurman.aur_utilities import is_devel, get_aur_info
1010
from aurman.coloring import aurman_status, aurman_note, aurman_error, aurman_question, Colors
1111
from aurman.own_exceptions import InvalidInput, ConnectionProblem
12+
from aurman.parsing_config import packages_from_other_sources
1213
from aurman.utilities import strip_versioning_from_name, split_name_with_versioning, version_comparison, ask_user
1314
from aurman.wrappers import expac, makepkg, pacman
1415

@@ -248,10 +249,13 @@ def get_packages_from_expac(expac_operation: str, packages_names: Sequence[str],
248249
if "Q" in expac_operation:
249250
formatting = list("nvDHoPReGw")
250251
repos = []
252+
repo_dict = {}
251253
else:
252254
assert "S" in expac_operation
253255
formatting = list("nvDHoPReGr")
254256
repos = Package.get_known_repos()
257+
# packages the user wants to install from another repo
258+
repo_dict = packages_from_other_sources()[1]
255259

256260
expac_return = expac(expac_operation, formatting, packages_names)
257261
return_dict = {}
@@ -290,15 +294,42 @@ def get_packages_from_expac(expac_operation: str, packages_names: Sequence[str],
290294
assert "S" in expac_operation
291295
to_expand['repo'] = splitted_line[9]
292296

293-
if to_expand['name'] in return_dict and repos.index(return_dict[to_expand['name']].repo) < repos.index(
294-
to_expand['repo']):
295-
continue
297+
# continue if we explicitly want a package from a specific repo
298+
# and the package is not from that repo
299+
# or if the order of the repos in pacman.conf tells us to
300+
if to_expand['name'] in return_dict:
301+
if to_expand['name'] in repo_dict:
302+
if to_expand['repo'] == repo_dict[to_expand['name']]:
303+
pass
304+
elif return_dict[to_expand['name']].repo != repo_dict[to_expand['name']]:
305+
if repos.index(return_dict[to_expand['name']].repo) < repos.index(to_expand['repo']):
306+
continue
307+
308+
elif repos.index(return_dict[to_expand['name']].repo) < repos.index(to_expand['repo']):
309+
continue
296310

297311
if to_expand['name'] in to_expand['conflicts']:
298312
to_expand['conflicts'].remove(to_expand['name'])
299313

300314
return_dict[to_expand['name']] = Package(**to_expand)
301315

316+
# check if all repos the user gave us are actually known
317+
for repo_package_name in repo_dict:
318+
if repo_package_name not in return_dict:
319+
aurman_error("Package {} "
320+
"not known in any repo".format(Colors.BOLD(Colors.LIGHT_MAGENTA(repo_package_name))))
321+
raise InvalidInput("Package {} "
322+
"not known in any repo".format(Colors.BOLD(Colors.LIGHT_MAGENTA(repo_package_name))))
323+
324+
package_repo = return_dict[repo_package_name].repo
325+
if package_repo != repo_dict[repo_package_name]:
326+
aurman_error("Package {} not found in repo {}"
327+
"".format(Colors.BOLD(Colors.LIGHT_MAGENTA(repo_package_name)),
328+
Colors.BOLD(Colors.LIGHT_MAGENTA(repo_dict[repo_package_name]))))
329+
raise InvalidInput("Package {} not found in repo {}"
330+
"".format(Colors.BOLD(Colors.LIGHT_MAGENTA(repo_package_name)),
331+
Colors.BOLD(Colors.LIGHT_MAGENTA(repo_dict[repo_package_name]))))
332+
302333
return list(return_dict.values())
303334

304335
def __init__(self, name: str, version: str, depends: Sequence[str] = None, conflicts: Sequence[str] = None,
@@ -1102,6 +1133,11 @@ def get_installed_packages() -> List['Package']:
11021133
:return: A list containing the installed packages
11031134
"""
11041135
repo_packages_names = set(expac("-S", ('n',), ()))
1136+
1137+
# packages the user wants to install from aur
1138+
aur_names = packages_from_other_sources()[0]
1139+
repo_packages_names -= aur_names
1140+
11051141
installed_packages_names = set(expac("-Q", ('n',), ()))
11061142
installed_repo_packages_names = installed_packages_names & repo_packages_names
11071143
unclassified_installed_names = installed_packages_names - installed_repo_packages_names
@@ -1116,6 +1152,10 @@ def get_installed_packages() -> List['Package']:
11161152
# installed aur packages
11171153
installed_aur_packages_names = set(
11181154
[package.name for package in Package.get_packages_from_aur(list(unclassified_installed_names))])
1155+
for name in aur_names:
1156+
if name not in installed_aur_packages_names:
1157+
aurman_error("Package {} not found in AUR!".format(Colors.BOLD(Colors.LIGHT_MAGENTA(name))))
1158+
raise InvalidInput("Package {} not found in AUR!".format(Colors.BOLD(Colors.LIGHT_MAGENTA(name))))
11191159

11201160
if installed_aur_packages_names:
11211161
return_list.extend(
@@ -1153,6 +1193,9 @@ def __init__(self, packages: Sequence['Package']):
11531193

11541194
self.append_packages(packages)
11551195

1196+
def recreate_dicts(self):
1197+
self.__init__(list(self.all_packages_dict.values()))
1198+
11561199
def append_packages(self, packages: Sequence['Package']):
11571200
"""
11581201
Appends packages to this system.
@@ -1293,19 +1336,38 @@ def append_packages_by_name(self, packages_names: Sequence[str]):
12931336

12941337
packages_names = set([strip_versioning_from_name(name) for name in packages_names])
12951338
packages_names_to_fetch = [name for name in packages_names if name not in self.all_packages_dict]
1339+
aur_names = packages_from_other_sources()[0]
1340+
for name in packages_names:
1341+
if name in packages_names_to_fetch:
1342+
continue
12961343

1344+
if name not in aur_names:
1345+
continue
1346+
1347+
package = self.all_packages_dict[name]
1348+
if package.type_of is not PossibleTypes.AUR_PACKAGE and package.type_of is not PossibleTypes.DEVEL_PACKAGE:
1349+
packages_names_to_fetch.append(name)
1350+
1351+
deleted_while_appending = False
12971352
while packages_names_to_fetch:
12981353
fetched_packages = Package.get_packages_from_aur(packages_names_to_fetch)
1299-
self.append_packages(fetched_packages)
13001354

13011355
deps_of_the_fetched_packages = []
13021356
for package in fetched_packages:
13031357
deps_of_the_fetched_packages.extend(package.relevant_deps())
1358+
if package.name in self.all_packages_dict:
1359+
del self.all_packages_dict[package.name]
1360+
deleted_while_appending = True
1361+
1362+
self.append_packages(fetched_packages)
13041363

13051364
relevant_deps = list(set([strip_versioning_from_name(dep) for dep in deps_of_the_fetched_packages]))
13061365

13071366
packages_names_to_fetch = [dep for dep in relevant_deps if dep not in self.all_packages_dict]
13081367

1368+
if deleted_while_appending:
1369+
self.recreate_dicts()
1370+
13091371
def are_all_deps_fulfilled(self, package: 'Package', only_make_check: bool = False,
13101372
only_depends: bool = False, print_reason: bool = False) -> bool:
13111373
"""

src/aurman/help_printing.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,6 @@ def __repr__(self):
154154
only_aurman_points.append(HelpOption(["--holdpkg_conf"],
155155
"append packages from the pacman.conf to"
156156
" {}".format(Colors.LIGHT_GREEN("--holdpkg"))))
157+
only_aurman_points.append(HelpOption(["--do_everything"],
158+
"{} will be handled by aurman for repo packages, too"
159+
"".format(Colors.LIGHT_GREEN("-u"))))

src/aurman/main.py

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from aurman.help_printing import aurman_help
1111
from aurman.own_exceptions import InvalidInput
1212
from aurman.parse_args import PacmanOperations, parse_pacman_args
13+
from aurman.parsing_config import read_config, packages_from_other_sources
1314
from aurman.utilities import acquire_sudo, version_comparison, search_and_print
1415
from aurman.wrappers import pacman, expac
1516

@@ -69,6 +70,12 @@ def process(args):
6970
noconfirm = pacman_args.noconfirm # if --noconfirm
7071
search = pacman_args.search # list containing the specified strings for -s and --search
7172
solution_way = pacman_args.solution_way # if --solution_way
73+
do_everything = pacman_args.do_everything # if --do_everything
74+
75+
try:
76+
read_config() # read config - available via AurmanConfig.aurman_config
77+
except InvalidInput:
78+
return
7279

7380
not_remove = pacman_args.holdpkg # list containing the specified packages for --holdpkg
7481
# if --holdpkg_conf append holdpkg from pacman.conf
@@ -105,27 +112,44 @@ def process(args):
105112
# if user just wants to search
106113
if search:
107114
if not repo:
108-
installed_system = System(System.get_installed_packages())
115+
try:
116+
installed_system = System(System.get_installed_packages())
117+
except InvalidInput:
118+
return
109119
else:
110120
installed_system = None
111121
search_and_print(search, installed_system, str(pacman_args), repo, aur)
112122
return
113123

114124
# groups are for pacman
115-
groups = pacman("-Sg", True, sudo=False)
116125
groups_chosen = []
117-
for name in packages_of_user_names[:]:
118-
if name in groups:
119-
groups_chosen.append(name)
120-
packages_of_user_names.remove(name)
121-
122-
# in case of sysupgrade or groups to install and not --aur, call pacman
123-
if (sysupgrade or groups_chosen) and not aur:
126+
if not aur:
127+
groups = pacman("-Sg", True, sudo=False)
128+
for name in packages_of_user_names[:]:
129+
if name in groups:
130+
groups_chosen.append(name)
131+
packages_of_user_names.remove(name)
132+
133+
# pacman call in the beginning of the routine
134+
if not aur \
135+
and (sysupgrade and (not do_everything or pacman_args.refresh) or groups_chosen):
124136
if not sudo_acquired:
125137
acquire_sudo()
126138
sudo_acquired = True
127139
pacman_args_copy = deepcopy(pacman_args)
128140
pacman_args_copy.targets = groups_chosen
141+
# aurman handles the update
142+
if do_everything:
143+
pacman_args_copy.sysupgrade = False
144+
# ignore packages from other sources for sysupgrade
145+
packages_from_other_sources_ret = packages_from_other_sources()
146+
names_to_ignore = packages_from_other_sources_ret[0]
147+
for name_to_ignore in packages_from_other_sources_ret[1]:
148+
names_to_ignore.add(name_to_ignore)
149+
for already_ignored in pacman_args_copy.ignore:
150+
names_to_ignore |= set(already_ignored.split(","))
151+
if names_to_ignore:
152+
pacman_args_copy.ignore = [",".join(names_to_ignore)]
129153
try:
130154
pacman(str(pacman_args_copy), False)
131155
except InvalidInput:
@@ -144,18 +168,21 @@ def process(args):
144168
aurman_status("initializing {}...".format(Colors.BOLD("aurman")), True)
145169

146170
# analyzing installed packages
147-
installed_system = System(System.get_installed_packages())
171+
try:
172+
installed_system = System(System.get_installed_packages())
173+
except InvalidInput:
174+
return
148175

149176
if installed_system.not_repo_not_aur_packages_list:
150177
aurman_status("the following packages are neither in known repos nor in the aur")
151178
for package in installed_system.not_repo_not_aur_packages_list:
152179
aurman_note("{}".format(Colors.BOLD(Colors.LIGHT_MAGENTA(package))))
153180

154181
# fetching upstream repo packages...
155-
if not aur:
182+
try:
156183
upstream_system = System(System.get_repo_packages())
157-
else:
158-
upstream_system = System(())
184+
except InvalidInput:
185+
return
159186

160187
# fetching needed aur packages
161188
if not repo:
@@ -165,6 +192,12 @@ def process(args):
165192
names_of_installed_aur_packages.extend([package.name for package in installed_system.devel_packages_list])
166193
upstream_system.append_packages_by_name(names_of_installed_aur_packages)
167194

195+
# remove known repo packages in case of --aur
196+
if aur:
197+
for package in upstream_system.repo_packages_list:
198+
del upstream_system.all_packages_dict[package.name]
199+
upstream_system = System(list(upstream_system.all_packages_dict.values()))
200+
168201
# sanitize user input
169202
try:
170203
sanitized_names = upstream_system.sanitize_user_input(packages_of_user_names)
@@ -236,11 +269,15 @@ def process(args):
236269
else:
237270
concrete_packages_to_install.append(package)
238271

239-
# in case of sysupgrade and not --repo fetch all installed aur packages, of which newer versions are available
240-
if sysupgrade and not repo:
241-
installed_aur_packages = [package for package in installed_system.aur_packages_list]
242-
installed_aur_packages.extend([package for package in installed_system.devel_packages_list])
243-
for package in installed_aur_packages:
272+
# in case of sysupgrade fetch all installed packages, of which newer versions are available
273+
if sysupgrade:
274+
installed_packages = []
275+
if not repo:
276+
installed_packages.extend([package for package in installed_system.aur_packages_list])
277+
installed_packages.extend([package for package in installed_system.devel_packages_list])
278+
if not aur:
279+
installed_packages.extend([package for package in installed_system.repo_packages_list])
280+
for package in installed_packages:
244281
# must not be that we have not received the upstream information
245282
assert package.name in upstream_system.all_packages_dict
246283
upstream_package = upstream_system.all_packages_dict[package.name]
@@ -298,6 +335,9 @@ def process(args):
298335
if not sudo_acquired:
299336
acquire_sudo()
300337

338+
# repo packages to install from other sources
339+
repo_packages_dict = packages_from_other_sources()[1]
340+
301341
# generate pacman args for the aur packages
302342
pacman_args_copy = deepcopy(pacman_args)
303343
pacman_args_copy.operation = PacmanOperations.UPGRADE
@@ -324,7 +364,11 @@ def process(args):
324364
as_explicit_container.add(package.name)
325365

326366
pacman_args_copy = deepcopy(pacman_args)
327-
pacman_args_copy.targets = [package.name for package in package_chunk]
367+
pacman_args_copy.targets = [package.name for package in package_chunk if
368+
package.name not in repo_packages_dict]
369+
370+
pacman_args_copy.targets.extend(["{}/".format(repo_packages_dict[package.name]) + package.name
371+
for package in package_chunk if package.name in repo_packages_dict])
328372
pacman_args_copy.asdeps = True
329373
pacman_args_copy.asexplicit = False
330374
try:
@@ -352,7 +396,7 @@ def process(args):
352396
def main():
353397
try:
354398
# auto completion
355-
if argv[1] == "--auto_complete":
399+
if len(argv) >= 2 and argv[1] == "--auto_complete":
356400
possible_completions()
357401
return
358402

0 commit comments

Comments
 (0)