├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── apacman
├── apacman.8
├── apacman.conf
├── apacman.conf.5
├── apacman.install
├── docs
├── apacman.8.html
└── apacman.conf.5.html
├── release.sh
├── test.bats
└── zsh-completion
/.gitignore:
--------------------------------------------------------------------------------
1 | old/
2 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM vcatechnology/arch-ci:latest
2 | MAINTAINER oshazard
3 | RUN sudo pacman -Syu
4 | RUN sudo pacman -S jshon bash-bats --needed --asdeps --noconfirm
5 | RUN sudo curl -O "https://raw.githubusercontent.com/oshazard/apacman/master/apacman"
6 | RUN sudo bash ./apacman -S apacman --noconfirm
7 | RUN sudo apacman -S apacman-deps proot fuse --needed --asdeps --noconfirm
8 |
9 | # docker build -t "apacman:dockerfile" .
10 | # docker run -t -i "apacman:dockerfile" bats /usr/share/bats/apacman.bats
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | GNU GENERAL PUBLIC LICENSE
3 | Version 3, 29 June 2007
4 |
5 | Copyright (C) 2007 Free Software Foundation, Inc. [http://fsf.org/]
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The GNU General Public License is a free, copyleft license for
12 | software and other kinds of works.
13 |
14 | The licenses for most software and other practical works are designed
15 | to take away your freedom to share and change the works. By contrast,
16 | the GNU General Public License is intended to guarantee your freedom to
17 | share and change all versions of a program--to make sure it remains free
18 | software for all its users. We, the Free Software Foundation, use the
19 | GNU General Public License for most of our software; it applies also to
20 | any other work released this way by its authors. You can apply it to
21 | your programs, too.
22 |
23 | When we speak of free software, we are referring to freedom, not
24 | price. Our General Public Licenses are designed to make sure that you
25 | have the freedom to distribute copies of free software (and charge for
26 | them if you wish), that you receive source code or can get it if you
27 | want it, that you can change the software or use pieces of it in new
28 | free programs, and that you know you can do these things.
29 |
30 | To protect your rights, we need to prevent others from denying you
31 | these rights or asking you to surrender the rights. Therefore, you have
32 | certain responsibilities if you distribute copies of the software, or if
33 | you modify it: responsibilities to respect the freedom of others.
34 |
35 | For example, if you distribute copies of such a program, whether
36 | gratis or for a fee, you must pass on to the recipients the same
37 | freedoms that you received. You must make sure that they, too, receive
38 | or can get the source code. And you must show them these terms so they
39 | know their rights.
40 |
41 | Developers that use the GNU GPL protect your rights with two steps:
42 | (1) assert copyright on the software, and (2) offer you this License
43 | giving you legal permission to copy, distribute and/or modify it.
44 |
45 | For the developers' and authors' protection, the GPL clearly explains
46 | that there is no warranty for this free software. For both users' and
47 | authors' sake, the GPL requires that modified versions be marked as
48 | changed, so that their problems will not be attributed erroneously to
49 | authors of previous versions.
50 |
51 | Some devices are designed to deny users access to install or run
52 | modified versions of the software inside them, although the manufacturer
53 | can do so. This is fundamentally incompatible with the aim of
54 | protecting users' freedom to change the software. The systematic
55 | pattern of such abuse occurs in the area of products for individuals to
56 | use, which is precisely where it is most unacceptable. Therefore, we
57 | have designed this version of the GPL to prohibit the practice for those
58 | products. If such problems arise substantially in other domains, we
59 | stand ready to extend this provision to those domains in future versions
60 | of the GPL, as needed to protect the freedom of users.
61 |
62 | Finally, every program is threatened constantly by software patents.
63 | States should not allow patents to restrict development and use of
64 | software on general-purpose computers, but in those that do, we wish to
65 | avoid the special danger that patents applied to a free program could
66 | make it effectively proprietary. To prevent this, the GPL assures that
67 | patents cannot be used to render the program non-free.
68 |
69 | The precise terms and conditions for copying, distribution and
70 | modification follow.
71 |
72 | TERMS AND CONDITIONS
73 |
74 | 0. Definitions.
75 |
76 | "This License" refers to version 3 of the GNU General Public License.
77 |
78 | "Copyright" also means copyright-like laws that apply to other kinds of
79 | works, such as semiconductor masks.
80 |
81 | "The Program" refers to any copyrightable work licensed under this
82 | License. Each licensee is addressed as "you". "Licensees" and
83 | "recipients" may be individuals or organizations.
84 |
85 | To "modify" a work means to copy from or adapt all or part of the work
86 | in a fashion requiring copyright permission, other than the making of an
87 | exact copy. The resulting work is called a "modified version" of the
88 | earlier work or a work "based on" the earlier work.
89 |
90 | A "covered work" means either the unmodified Program or a work based
91 | on the Program.
92 |
93 | To "propagate" a work means to do anything with it that, without
94 | permission, would make you directly or secondarily liable for
95 | infringement under applicable copyright law, except executing it on a
96 | computer or modifying a private copy. Propagation includes copying,
97 | distribution (with or without modification), making available to the
98 | public, and in some countries other activities as well.
99 |
100 | To "convey" a work means any kind of propagation that enables other
101 | parties to make or receive copies. Mere interaction with a user through
102 | a computer network, with no transfer of a copy, is not conveying.
103 |
104 | An interactive user interface displays "Appropriate Legal Notices"
105 | to the extent that it includes a convenient and prominently visible
106 | feature that (1) displays an appropriate copyright notice, and (2)
107 | tells the user that there is no warranty for the work (except to the
108 | extent that warranties are provided), that licensees may convey the
109 | work under this License, and how to view a copy of this License. If
110 | the interface presents a list of user commands or options, such as a
111 | menu, a prominent item in the list meets this criterion.
112 |
113 | 1. Source Code.
114 |
115 | The "source code" for a work means the preferred form of the work
116 | for making modifications to it. "Object code" means any non-source
117 | form of a work.
118 |
119 | A "Standard Interface" means an interface that either is an official
120 | standard defined by a recognized standards body, or, in the case of
121 | interfaces specified for a particular programming language, one that
122 | is widely used among developers working in that language.
123 |
124 | The "System Libraries" of an executable work include anything, other
125 | than the work as a whole, that (a) is included in the normal form of
126 | packaging a Major Component, but which is not part of that Major
127 | Component, and (b) serves only to enable use of the work with that
128 | Major Component, or to implement a Standard Interface for which an
129 | implementation is available to the public in source code form. A
130 | "Major Component", in this context, means a major essential component
131 | (kernel, window system, and so on) of the specific operating system
132 | (if any) on which the executable work runs, or a compiler used to
133 | produce the work, or an object code interpreter used to run it.
134 |
135 | The "Corresponding Source" for a work in object code form means all
136 | the source code needed to generate, install, and (for an executable
137 | work) run the object code and to modify the work, including scripts to
138 | control those activities. However, it does not include the work's
139 | System Libraries, or general-purpose tools or generally available free
140 | programs which are used unmodified in performing those activities but
141 | which are not part of the work. For example, Corresponding Source
142 | includes interface definition files associated with source files for
143 | the work, and the source code for shared libraries and dynamically
144 | linked subprograms that the work is specifically designed to require,
145 | such as by intimate data communication or control flow between those
146 | subprograms and other parts of the work.
147 |
148 | The Corresponding Source need not include anything that users
149 | can regenerate automatically from other parts of the Corresponding
150 | Source.
151 |
152 | The Corresponding Source for a work in source code form is that
153 | same work.
154 |
155 | 2. Basic Permissions.
156 |
157 | All rights granted under this License are granted for the term of
158 | copyright on the Program, and are irrevocable provided the stated
159 | conditions are met. This License explicitly affirms your unlimited
160 | permission to run the unmodified Program. The output from running a
161 | covered work is covered by this License only if the output, given its
162 | content, constitutes a covered work. This License acknowledges your
163 | rights of fair use or other equivalent, as provided by copyright law.
164 |
165 | You may make, run and propagate covered works that you do not
166 | convey, without conditions so long as your license otherwise remains
167 | in force. You may convey covered works to others for the sole purpose
168 | of having them make modifications exclusively for you, or provide you
169 | with facilities for running those works, provided that you comply with
170 | the terms of this License in conveying all material for which you do
171 | not control copyright. Those thus making or running the covered works
172 | for you must do so exclusively on your behalf, under your direction
173 | and control, on terms that prohibit them from making any copies of
174 | your copyrighted material outside their relationship with you.
175 |
176 | Conveying under any other circumstances is permitted solely under
177 | the conditions stated below. Sublicensing is not allowed; section 10
178 | makes it unnecessary.
179 |
180 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
181 |
182 | No covered work shall be deemed part of an effective technological
183 | measure under any applicable law fulfilling obligations under article
184 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
185 | similar laws prohibiting or restricting circumvention of such
186 | measures.
187 |
188 | When you convey a covered work, you waive any legal power to forbid
189 | circumvention of technological measures to the extent such circumvention
190 | is effected by exercising rights under this License with respect to
191 | the covered work, and you disclaim any intention to limit operation or
192 | modification of the work as a means of enforcing, against the work's
193 | users, your or third parties' legal rights to forbid circumvention of
194 | technological measures.
195 |
196 | 4. Conveying Verbatim Copies.
197 |
198 | You may convey verbatim copies of the Program's source code as you
199 | receive it, in any medium, provided that you conspicuously and
200 | appropriately publish on each copy an appropriate copyright notice;
201 | keep intact all notices stating that this License and any
202 | non-permissive terms added in accord with section 7 apply to the code;
203 | keep intact all notices of the absence of any warranty; and give all
204 | recipients a copy of this License along with the Program.
205 |
206 | You may charge any price or no price for each copy that you convey,
207 | and you may offer support or warranty protection for a fee.
208 |
209 | 5. Conveying Modified Source Versions.
210 |
211 | You may convey a work based on the Program, or the modifications to
212 | produce it from the Program, in the form of source code under the
213 | terms of section 4, provided that you also meet all of these conditions:
214 |
215 | a) The work must carry prominent notices stating that you modified
216 | it, and giving a relevant date.
217 |
218 | b) The work must carry prominent notices stating that it is
219 | released under this License and any conditions added under section
220 | 7. This requirement modifies the requirement in section 4 to
221 | "keep intact all notices".
222 |
223 | c) You must license the entire work, as a whole, under this
224 | License to anyone who comes into possession of a copy. This
225 | License will therefore apply, along with any applicable section 7
226 | additional terms, to the whole of the work, and all its parts,
227 | regardless of how they are packaged. This License gives no
228 | permission to license the work in any other way, but it does not
229 | invalidate such permission if you have separately received it.
230 |
231 | d) If the work has interactive user interfaces, each must display
232 | Appropriate Legal Notices; however, if the Program has interactive
233 | interfaces that do not display Appropriate Legal Notices, your
234 | work need not make them do so.
235 |
236 | A compilation of a covered work with other separate and independent
237 | works, which are not by their nature extensions of the covered work,
238 | and which are not combined with it such as to form a larger program,
239 | in or on a volume of a storage or distribution medium, is called an
240 | "aggregate" if the compilation and its resulting copyright are not
241 | used to limit the access or legal rights of the compilation's users
242 | beyond what the individual works permit. Inclusion of a covered work
243 | in an aggregate does not cause this License to apply to the other
244 | parts of the aggregate.
245 |
246 | 6. Conveying Non-Source Forms.
247 |
248 | You may convey a covered work in object code form under the terms
249 | of sections 4 and 5, provided that you also convey the
250 | machine-readable Corresponding Source under the terms of this License,
251 | in one of these ways:
252 |
253 | a) Convey the object code in, or embodied in, a physical product
254 | (including a physical distribution medium), accompanied by the
255 | Corresponding Source fixed on a durable physical medium
256 | customarily used for software interchange.
257 |
258 | b) Convey the object code in, or embodied in, a physical product
259 | (including a physical distribution medium), accompanied by a
260 | written offer, valid for at least three years and valid for as
261 | long as you offer spare parts or customer support for that product
262 | model, to give anyone who possesses the object code either (1) a
263 | copy of the Corresponding Source for all the software in the
264 | product that is covered by this License, on a durable physical
265 | medium customarily used for software interchange, for a price no
266 | more than your reasonable cost of physically performing this
267 | conveying of source, or (2) access to copy the
268 | Corresponding Source from a network server at no charge.
269 |
270 | c) Convey individual copies of the object code with a copy of the
271 | written offer to provide the Corresponding Source. This
272 | alternative is allowed only occasionally and noncommercially, and
273 | only if you received the object code with such an offer, in accord
274 | with subsection 6b.
275 |
276 | d) Convey the object code by offering access from a designated
277 | place (gratis or for a charge), and offer equivalent access to the
278 | Corresponding Source in the same way through the same place at no
279 | further charge. You need not require recipients to copy the
280 | Corresponding Source along with the object code. If the place to
281 | copy the object code is a network server, the Corresponding Source
282 | may be on a different server (operated by you or a third party)
283 | that supports equivalent copying facilities, provided you maintain
284 | clear directions next to the object code saying where to find the
285 | Corresponding Source. Regardless of what server hosts the
286 | Corresponding Source, you remain obligated to ensure that it is
287 | available for as long as needed to satisfy these requirements.
288 |
289 | e) Convey the object code using peer-to-peer transmission, provided
290 | you inform other peers where the object code and Corresponding
291 | Source of the work are being offered to the general public at no
292 | charge under subsection 6d.
293 |
294 | A separable portion of the object code, whose source code is excluded
295 | from the Corresponding Source as a System Library, need not be
296 | included in conveying the object code work.
297 |
298 | A "User Product" is either (1) a "consumer product", which means any
299 | tangible personal property which is normally used for personal, family,
300 | or household purposes, or (2) anything designed or sold for incorporation
301 | into a dwelling. In determining whether a product is a consumer product,
302 | doubtful cases shall be resolved in favor of coverage. For a particular
303 | product received by a particular user, "normally used" refers to a
304 | typical or common use of that class of product, regardless of the status
305 | of the particular user or of the way in which the particular user
306 | actually uses, or expects or is expected to use, the product. A product
307 | is a consumer product regardless of whether the product has substantial
308 | commercial, industrial or non-consumer uses, unless such uses represent
309 | the only significant mode of use of the product.
310 |
311 | "Installation Information" for a User Product means any methods,
312 | procedures, authorization keys, or other information required to install
313 | and execute modified versions of a covered work in that User Product from
314 | a modified version of its Corresponding Source. The information must
315 | suffice to ensure that the continued functioning of the modified object
316 | code is in no case prevented or interfered with solely because
317 | modification has been made.
318 |
319 | If you convey an object code work under this section in, or with, or
320 | specifically for use in, a User Product, and the conveying occurs as
321 | part of a transaction in which the right of possession and use of the
322 | User Product is transferred to the recipient in perpetuity or for a
323 | fixed term (regardless of how the transaction is characterized), the
324 | Corresponding Source conveyed under this section must be accompanied
325 | by the Installation Information. But this requirement does not apply
326 | if neither you nor any third party retains the ability to install
327 | modified object code on the User Product (for example, the work has
328 | been installed in ROM).
329 |
330 | The requirement to provide Installation Information does not include a
331 | requirement to continue to provide support service, warranty, or updates
332 | for a work that has been modified or installed by the recipient, or for
333 | the User Product in which it has been modified or installed. Access to a
334 | network may be denied when the modification itself materially and
335 | adversely affects the operation of the network or violates the rules and
336 | protocols for communication across the network.
337 |
338 | Corresponding Source conveyed, and Installation Information provided,
339 | in accord with this section must be in a format that is publicly
340 | documented (and with an implementation available to the public in
341 | source code form), and must require no special password or key for
342 | unpacking, reading or copying.
343 |
344 | 7. Additional Terms.
345 |
346 | "Additional permissions" are terms that supplement the terms of this
347 | License by making exceptions from one or more of its conditions.
348 | Additional permissions that are applicable to the entire Program shall
349 | be treated as though they were included in this License, to the extent
350 | that they are valid under applicable law. If additional permissions
351 | apply only to part of the Program, that part may be used separately
352 | under those permissions, but the entire Program remains governed by
353 | this License without regard to the additional permissions.
354 |
355 | When you convey a copy of a covered work, you may at your option
356 | remove any additional permissions from that copy, or from any part of
357 | it. (Additional permissions may be written to require their own
358 | removal in certain cases when you modify the work.) You may place
359 | additional permissions on material, added by you to a covered work,
360 | for which you have or can give appropriate copyright permission.
361 |
362 | Notwithstanding any other provision of this License, for material you
363 | add to a covered work, you may (if authorized by the copyright holders of
364 | that material) supplement the terms of this License with terms:
365 |
366 | a) Disclaiming warranty or limiting liability differently from the
367 | terms of sections 15 and 16 of this License; or
368 |
369 | b) Requiring preservation of specified reasonable legal notices or
370 | author attributions in that material or in the Appropriate Legal
371 | Notices displayed by works containing it; or
372 |
373 | c) Prohibiting misrepresentation of the origin of that material, or
374 | requiring that modified versions of such material be marked in
375 | reasonable ways as different from the original version; or
376 |
377 | d) Limiting the use for publicity purposes of names of licensors or
378 | authors of the material; or
379 |
380 | e) Declining to grant rights under trademark law for use of some
381 | trade names, trademarks, or service marks; or
382 |
383 | f) Requiring indemnification of licensors and authors of that
384 | material by anyone who conveys the material (or modified versions of
385 | it) with contractual assumptions of liability to the recipient, for
386 | any liability that these contractual assumptions directly impose on
387 | those licensors and authors.
388 |
389 | All other non-permissive additional terms are considered "further
390 | restrictions" within the meaning of section 10. If the Program as you
391 | received it, or any part of it, contains a notice stating that it is
392 | governed by this License along with a term that is a further
393 | restriction, you may remove that term. If a license document contains
394 | a further restriction but permits relicensing or conveying under this
395 | License, you may add to a covered work material governed by the terms
396 | of that license document, provided that the further restriction does
397 | not survive such relicensing or conveying.
398 |
399 | If you add terms to a covered work in accord with this section, you
400 | must place, in the relevant source files, a statement of the
401 | additional terms that apply to those files, or a notice indicating
402 | where to find the applicable terms.
403 |
404 | Additional terms, permissive or non-permissive, may be stated in the
405 | form of a separately written license, or stated as exceptions;
406 | the above requirements apply either way.
407 |
408 | 8. Termination.
409 |
410 | You may not propagate or modify a covered work except as expressly
411 | provided under this License. Any attempt otherwise to propagate or
412 | modify it is void, and will automatically terminate your rights under
413 | this License (including any patent licenses granted under the third
414 | paragraph of section 11).
415 |
416 | However, if you cease all violation of this License, then your
417 | license from a particular copyright holder is reinstated (a)
418 | provisionally, unless and until the copyright holder explicitly and
419 | finally terminates your license, and (b) permanently, if the copyright
420 | holder fails to notify you of the violation by some reasonable means
421 | prior to 60 days after the cessation.
422 |
423 | Moreover, your license from a particular copyright holder is
424 | reinstated permanently if the copyright holder notifies you of the
425 | violation by some reasonable means, this is the first time you have
426 | received notice of violation of this License (for any work) from that
427 | copyright holder, and you cure the violation prior to 30 days after
428 | your receipt of the notice.
429 |
430 | Termination of your rights under this section does not terminate the
431 | licenses of parties who have received copies or rights from you under
432 | this License. If your rights have been terminated and not permanently
433 | reinstated, you do not qualify to receive new licenses for the same
434 | material under section 10.
435 |
436 | 9. Acceptance Not Required for Having Copies.
437 |
438 | You are not required to accept this License in order to receive or
439 | run a copy of the Program. Ancillary propagation of a covered work
440 | occurring solely as a consequence of using peer-to-peer transmission
441 | to receive a copy likewise does not require acceptance. However,
442 | nothing other than this License grants you permission to propagate or
443 | modify any covered work. These actions infringe copyright if you do
444 | not accept this License. Therefore, by modifying or propagating a
445 | covered work, you indicate your acceptance of this License to do so.
446 |
447 | 10. Automatic Licensing of Downstream Recipients.
448 |
449 | Each time you convey a covered work, the recipient automatically
450 | receives a license from the original licensors, to run, modify and
451 | propagate that work, subject to this License. You are not responsible
452 | for enforcing compliance by third parties with this License.
453 |
454 | An "entity transaction" is a transaction transferring control of an
455 | organization, or substantially all assets of one, or subdividing an
456 | organization, or merging organizations. If propagation of a covered
457 | work results from an entity transaction, each party to that
458 | transaction who receives a copy of the work also receives whatever
459 | licenses to the work the party's predecessor in interest had or could
460 | give under the previous paragraph, plus a right to possession of the
461 | Corresponding Source of the work from the predecessor in interest, if
462 | the predecessor has it or can get it with reasonable efforts.
463 |
464 | You may not impose any further restrictions on the exercise of the
465 | rights granted or affirmed under this License. For example, you may
466 | not impose a license fee, royalty, or other charge for exercise of
467 | rights granted under this License, and you may not initiate litigation
468 | (including a cross-claim or counterclaim in a lawsuit) alleging that
469 | any patent claim is infringed by making, using, selling, offering for
470 | sale, or importing the Program or any portion of it.
471 |
472 | 11. Patents.
473 |
474 | A "contributor" is a copyright holder who authorizes use under this
475 | License of the Program or a work on which the Program is based. The
476 | work thus licensed is called the contributor's "contributor version".
477 |
478 | A contributor's "essential patent claims" are all patent claims
479 | owned or controlled by the contributor, whether already acquired or
480 | hereafter acquired, that would be infringed by some manner, permitted
481 | by this License, of making, using, or selling its contributor version,
482 | but do not include claims that would be infringed only as a
483 | consequence of further modification of the contributor version. For
484 | purposes of this definition, "control" includes the right to grant
485 | patent sublicenses in a manner consistent with the requirements of
486 | this License.
487 |
488 | Each contributor grants you a non-exclusive, worldwide, royalty-free
489 | patent license under the contributor's essential patent claims, to
490 | make, use, sell, offer for sale, import and otherwise run, modify and
491 | propagate the contents of its contributor version.
492 |
493 | In the following three paragraphs, a "patent license" is any express
494 | agreement or commitment, however denominated, not to enforce a patent
495 | (such as an express permission to practice a patent or covenant not to
496 | sue for patent infringement). To "grant" such a patent license to a
497 | party means to make such an agreement or commitment not to enforce a
498 | patent against the party.
499 |
500 | If you convey a covered work, knowingly relying on a patent license,
501 | and the Corresponding Source of the work is not available for anyone
502 | to copy, free of charge and under the terms of this License, through a
503 | publicly available network server or other readily accessible means,
504 | then you must either (1) cause the Corresponding Source to be so
505 | available, or (2) arrange to deprive yourself of the benefit of the
506 | patent license for this particular work, or (3) arrange, in a manner
507 | consistent with the requirements of this License, to extend the patent
508 | license to downstream recipients. "Knowingly relying" means you have
509 | actual knowledge that, but for the patent license, your conveying the
510 | covered work in a country, or your recipient's use of the covered work
511 | in a country, would infringe one or more identifiable patents in that
512 | country that you have reason to believe are valid.
513 |
514 | If, pursuant to or in connection with a single transaction or
515 | arrangement, you convey, or propagate by procuring conveyance of, a
516 | covered work, and grant a patent license to some of the parties
517 | receiving the covered work authorizing them to use, propagate, modify
518 | or convey a specific copy of the covered work, then the patent license
519 | you grant is automatically extended to all recipients of the covered
520 | work and works based on it.
521 |
522 | A patent license is "discriminatory" if it does not include within
523 | the scope of its coverage, prohibits the exercise of, or is
524 | conditioned on the non-exercise of one or more of the rights that are
525 | specifically granted under this License. You may not convey a covered
526 | work if you are a party to an arrangement with a third party that is
527 | in the business of distributing software, under which you make payment
528 | to the third party based on the extent of your activity of conveying
529 | the work, and under which the third party grants, to any of the
530 | parties who would receive the covered work from you, a discriminatory
531 | patent license (a) in connection with copies of the covered work
532 | conveyed by you (or copies made from those copies), or (b) primarily
533 | for and in connection with specific products or compilations that
534 | contain the covered work, unless you entered into that arrangement,
535 | or that patent license was granted, prior to 28 March 2007.
536 |
537 | Nothing in this License shall be construed as excluding or limiting
538 | any implied license or other defenses to infringement that may
539 | otherwise be available to you under applicable patent law.
540 |
541 | 12. No Surrender of Others' Freedom.
542 |
543 | If conditions are imposed on you (whether by court order, agreement or
544 | otherwise) that contradict the conditions of this License, they do not
545 | excuse you from the conditions of this License. If you cannot convey a
546 | covered work so as to satisfy simultaneously your obligations under this
547 | License and any other pertinent obligations, then as a consequence you may
548 | not convey it at all. For example, if you agree to terms that obligate you
549 | to collect a royalty for further conveying from those to whom you convey
550 | the Program, the only way you could satisfy both those terms and this
551 | License would be to refrain entirely from conveying the Program.
552 |
553 | 13. Use with the GNU Affero General Public License.
554 |
555 | Notwithstanding any other provision of this License, you have
556 | permission to link or combine any covered work with a work licensed
557 | under version 3 of the GNU Affero General Public License into a single
558 | combined work, and to convey the resulting work. The terms of this
559 | License will continue to apply to the part which is the covered work,
560 | but the special requirements of the GNU Affero General Public License,
561 | section 13, concerning interaction through a network will apply to the
562 | combination as such.
563 |
564 | 14. Revised Versions of this License.
565 |
566 | The Free Software Foundation may publish revised and/or new versions of
567 | the GNU General Public License from time to time. Such new versions will
568 | be similar in spirit to the present version, but may differ in detail to
569 | address new problems or concerns.
570 |
571 | Each version is given a distinguishing version number. If the
572 | Program specifies that a certain numbered version of the GNU General
573 | Public License "or any later version" applies to it, you have the
574 | option of following the terms and conditions either of that numbered
575 | version or of any later version published by the Free Software
576 | Foundation. If the Program does not specify a version number of the
577 | GNU General Public License, you may choose any version ever published
578 | by the Free Software Foundation.
579 |
580 | If the Program specifies that a proxy can decide which future
581 | versions of the GNU General Public License can be used, that proxy's
582 | public statement of acceptance of a version permanently authorizes you
583 | to choose that version for the Program.
584 |
585 | Later license versions may give you additional or different
586 | permissions. However, no additional obligations are imposed on any
587 | author or copyright holder as a result of your choosing to follow a
588 | later version.
589 |
590 | 15. Disclaimer of Warranty.
591 |
592 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
593 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
594 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
595 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
596 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
597 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
598 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
599 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
600 |
601 | 16. Limitation of Liability.
602 |
603 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
604 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
605 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
606 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
607 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
608 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
609 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
610 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
611 | SUCH DAMAGES.
612 |
613 | 17. Interpretation of Sections 15 and 16.
614 |
615 | If the disclaimer of warranty and limitation of liability provided
616 | above cannot be given local legal effect according to their terms,
617 | reviewing courts shall apply local law that most closely approximates
618 | an absolute waiver of all civil liability in connection with the
619 | Program, unless a warranty or assumption of liability accompanies a
620 | copy of the Program in return for a fee.
621 |
622 | END OF TERMS AND CONDITIONS
623 |
624 | How to Apply These Terms to Your New Programs
625 |
626 | If you develop a new program, and you want it to be of the greatest
627 | possible use to the public, the best way to achieve this is to make it
628 | free software which everyone can redistribute and change under these terms.
629 |
630 | To do so, attach the following notices to the program. It is safest
631 | to attach them to the start of each source file to most effectively
632 | state the exclusion of warranty; and each file should have at least
633 | the "copyright" line and a pointer to where the full notice is found.
634 |
635 | {one line to give the program's name and a brief idea of what it does.}
636 | Copyright (C) {year} {name of author}
637 |
638 | This program is free software: you can redistribute it and/or modify
639 | it under the terms of the GNU General Public License as published by
640 | the Free Software Foundation, either version 3 of the License, or
641 | (at your option) any later version.
642 |
643 | This program is distributed in the hope that it will be useful,
644 | but WITHOUT ANY WARRANTY; without even the implied warranty of
645 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
646 | GNU General Public License for more details.
647 |
648 | You should have received a copy of the GNU General Public License
649 | along with this program. If not, see [http://www.gnu.org/licenses/].
650 |
651 | Also add information on how to contact you by electronic and paper mail.
652 |
653 | If the program does terminal interaction, make it output a short
654 | notice like this when it starts in an interactive mode:
655 |
656 | {project} Copyright (C) {year} {fullname}
657 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
658 | This is free software, and you are welcome to redistribute it
659 | under certain conditions; type `show c' for details.
660 |
661 | The hypothetical commands `show w' and `show c' should show the appropriate
662 | parts of the General Public License. Of course, your program's commands
663 | might be different; for a GUI interface, you would use an "about box".
664 |
665 | You should also get your employer (if you work as a programmer) or school,
666 | if any, to sign a "copyright disclaimer" for the program, if necessary.
667 | For more information on this, and how to apply and follow the GNU GPL, see
668 | [http://www.gnu.org/licenses/].
669 |
670 | The GNU General Public License does not permit incorporating your program
671 | into proprietary programs. If your program is a subroutine library, you
672 | may consider it more useful to permit linking proprietary applications with
673 | the library. If this is what you want to do, use the GNU Lesser General
674 | Public License instead of this License. But first, please read
675 | [http://www.gnu.org/philosophy/why-not-lgpl.html].
676 |
677 |
678 |
679 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | apacman
2 | ==================
3 |
4 | ArchLinux User Repository ([AUR](https://aur.archlinux.org/packages/)) helper and pacman wrapper
5 |
6 | **Chat room:** [](https://gitter.im/apacman/Lobby)
7 |
8 | **Comments:** [](https://aur.archlinux.org/packages/apacman/)
9 |
10 | ------------
11 |
12 | **Total:** [](https://github.com/oshazard/apacman/releases)
13 |
14 | **Previous:** [](https://github.com/oshazard/apacman/releases/tag/v2.6) [](https://github.com/oshazard/apacman/releases/tag/v3.0)
15 |
16 | **Current:** [](https://github.com/oshazard/apacman/releases/latest)
17 |
18 | **Votes:** [](https://aur.archlinux.org/packages/apacman/) [](https://github.com/oshazard/apacman/stargazers)
19 | (if you like this software, please upvote it on AUR)
20 |
21 |
22 | See also
23 | ------------
24 |
25 | [](https://aur.archlinux.org/packages/apacman-utils/) [(AUR uploader)](https://github.com/oshazard/apacman-utils/blob/master/aurpush) [(Migrate wizard for AUR4)](https://github.com/oshazard/apacman-utils/blob/master/apac-migrate)
26 |
27 | [Forked](https://github.com/keenerd/packer/pull/141) from [packer](https://github.com/keenerd/packer)
28 |
29 |
30 | Installation:
31 | ==========
32 | 1. `pacman -S --needed --asdeps jshon`
33 | 2. `curl -O "https://raw.githubusercontent.com/oshazard/apacman/master/apacman"`
34 | 3. `bash ./apacman -S apacman`
35 | 4. `apacman -S apacman-deps` (_optional_)
36 |
37 |
38 | Documentation:
39 | ==========
40 | * [`man 8 apacman`](https://oshazard.github.io/apacman/apacman.8.html)
41 | * [`man 5 apacman.conf`](https://oshazard.github.io/apacman/apacman.conf.5.html)
42 |
43 |
44 | Changelog:
45 | ==========
46 |
47 | Version 3.1
48 | ----------
49 | * **NEW** Clean build directory and temp directory (fixed #75)
50 | * **NEW** Expanded -G to fetch old AUR package source (`-G foobar~` or `-G foobar==2.0-1`)
51 | * **NEW** Added new exit codes (fixed #72)
52 | * **NEW** Converted manpages to HTML
53 | * **NEW** Fix for progress bar to match `pacman` (pull request #76)
54 | * **NEW** Fix ZSH completion (pull request #74)
55 | * **NEW** Miscellaneous fixes and cleanup
56 |
57 | Version 3.0
58 | ----------
59 | * Add alternative --flag=parameter syntax for relevant options
60 | * Fix for installing groups and virtual packages
61 | * Fix to allow installing cached packages without Internet
62 | * Implement unit tests using [bats](https://github.com/sstephenson/bats) (WIP)
63 | * Add regex/wildcard support to -S and -Ss
64 | * Return code 1 on errors
65 | * Improve viewing package comments
66 | * Update manpages
67 | * Closed 10+ issues since last release
68 |
69 | Version 2.9
70 | -----------
71 | * -P parameter uses AUR passthrough for pkgfile
72 | * Save installed AUR package metadata to database
73 | * --nodatabase parameter does not store AUR database
74 | * --gendb parameter to generate AUR database files
75 | * Display remaining packages in queue
76 | * --notify parameter for notify-send notifications
77 | * --noprogress to disable transaction progress
78 | * Enabled terminal title progress by default
79 | * --edit parameter to override 'noedit' option in config file
80 | * fix CLI flag precedence over config file
81 |
82 | Version 2.6
83 | -----------
84 | * improve -U to display packages removed from AUR as "unresolvable"
85 | * bug fix for --devel
86 | * merged fix that improves curl debugging
87 | * merged fix that removes split package support
88 | * merged pull requests for AUR5 support
89 | * improved virtual package support
90 | * improved -U handling
91 | * -W parameter to view package comments
92 | * sanity checks for curl with debugging
93 | * fixes for ABS
94 | * improved signed package support
95 | * --keepkeys parameter stores PGP keys
96 | * --purgekeys parameter removes trusted PGP keys
97 | * fix for piping output
98 | * fix for yes/no dialog
99 |
100 | Version 2.0
101 | -----------
102 | * Split package support and shared source
103 | * Improved AUR4 support
104 | * Bug fix for AUR4 -Si
105 | * Bug fix for built/failed
106 | * --legacy flag for AUR3
107 | * Preliminary AUR4 support
108 | * Signed package support
109 |
110 | Version 1.6
111 | -----------
112 | * Display [installed], [installed: VER], or [local: VER] in -Ss
113 | * --progress parameter sets terminal title to package status
114 | * Add AUR link to -Si info
115 | * Bug fix for saved AUR packages and --cachevcs
116 | * Bug fix for pacmatic
117 | * Build status log
118 | * Override EDITOR for PKGBUILDs in config file
119 | * --buildonly parameter to build but not AUR install packages
120 | * --nofail parameter to quit if a package does not build
121 | * --purgebuild parameter to remove unneeded build depends
122 | * --skiptest to avoid installing unit test packages
123 |
124 | Version 1.0
125 | -----------
126 | * Config file support (/etc/apacman.conf)
127 | * Cleaned up manpages
128 | * Replacement for pacsysclean (-L list installed packages by size)
129 | * -G now supports ABS + AUR packages
130 | * --noaur parameter to skip AUR packages
131 | * --warn parameter makes errors non-fatal (only enable if you know what you are doing)
132 | * Run as root workaround for Pacman 4.2+
133 |
134 | Version 0.6
135 | -----------
136 | * All features from packer
137 | * Saves built AUR packages to /var/cache/apacman/pkg
138 | * Uses AUR package cache directory if applicable
139 | * --needed parameter that does not install up-to-date packages
140 | * --ignorearch parameter that ignores architectures specified in PKGBUILD (useful for ARM devices)
141 | * --skipcache parameter that skips check for pre-built package in cache directory
142 | * --cachevcs parameter installs cached VCS (git, svn, hg) packages newer than AUR PKGBUILDs
143 | * Partial passthrough support for -R, -Q, and -U pacman parameters
144 |
--------------------------------------------------------------------------------
/apacman:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | ######################################################################
3 | # apacman - AUR wrapper forked from packer
4 | version="3.1"
5 | # Copyright OS Hazard
6 | #
7 | # New Features:
8 | # * Build old AUR releases from source (pkgname~, pkgname==ver)
9 | # * Merge fix for aurbar length
10 | # * Clean build files
11 | # * Clean temp files
12 | # * --savedir , --savedir=
13 | # * Install AUR packages offline
14 | # * --testing for unit testing purposes only
15 | # * Regex matching for searching packages
16 | # * Regex matching for installing packages
17 | # * -P patched AUR passthrough for pkgfile
18 | # * Save installed AUR package metadata to database
19 | # * Enabled --progress by default
20 | # * Fix CLI switch precedence over config file
21 | # * Improved support for virtual packages
22 | # * Improved -U handling
23 | # * Built-in ABS support (improved)
24 | # * -W View AUR comments (WIP)
25 | # * Signed package support (improved)
26 | # * Split package support
27 | # * AUR4 support
28 | # * Config file support
29 | # * Workaround for running as root
30 | # * Saves AUR packages to /var/cache/apacman/pkg
31 | # * Uses AUR package cache directory if applicable
32 | # * --asdeps install AUR packages non-explicitly
33 | # * --asexplicit install AUR packages explicitly
34 | # * --edit always ask to edit PKGBUILD
35 | # * --gendb generate AUR database files
36 | # * --keepkeys do not remove imported PGP keys
37 | # * --purgekeys remove imported PGP keys
38 | # * --legacy backwards compatability for AUR3 (deprecated)
39 | # * --progress transaction status in terminal titlebar
40 | # * --nodatabase do not store AUR database
41 | # * --nosource for security do not source PKGBUILDs (WIP)
42 | # * --noprogress no transaction status in titlebar
43 | # * --notify transaction status in notification
44 | # * --buildonly create but do not install packages
45 | # * --nofail do not continue if a package fails to build
46 | # * --purgebuild remove unneeded build dependencies
47 | # * --skiptest skips installing check() unit test packages
48 | # * --config specify alternate config file (default: /etc/apacman.conf)
49 | # * --verbose turns on verbose output
50 | # * -L list installed packages by size
51 | # * --noaur do not actions for aur
52 | # * --warn treat errors as non-fatal warnings
53 | # * --needed does not install up-to-date packages
54 | # * --ignorearch ignores architectures specified in PKGBUILD
55 | # * --skipcache skips check for pre-built package in cache directory
56 | # * --cachevcs installs cached VCS (git, svn, hg) packages newer than AUR PKGBUILDs
57 | # * partial passthrough for -R, -Q, -T and -U parameters
58 | ######################################################################
59 |
60 | # Copyright Matthew Bruenig
61 | # This program is free software: you can redistribute it and/or modify
62 | # it under the terms of the GNU General Public License as published by
63 | # the Free Software Foundation, either version 3 of the License, or
64 | # (at your option) any later version.
65 |
66 | # This program is distributed in the hope that it will be useful,
67 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
68 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
69 | # GNU General Public License for more details.
70 |
71 | # You should have received a copy of the GNU General Public License
72 | # along with this program. If not, see .
73 |
74 | [[ $PACMAN ]] || PACMAN="pacman"
75 | pacmanbin="/usr/bin/pacman"
76 |
77 | makepkgconf='/etc/makepkg.conf'
78 | usermakepkgconf="$HOME/.makepkg.conf"
79 | pacmanconf='/etc/pacman.conf'
80 | apacmanconf='/etc/apacman.conf'
81 | gpgconf='/etc/pacman.d/gnupg/gpg.conf'
82 | downdir='/var/cache/pacman/pkg'
83 | savedir='/var/cache/apacman/pkg'
84 | database='/var/lib/apacman'
85 | pacmandb='/var/lib/pacman/sync/aur.db'
86 | pkgfiledb='/var/cache/pkgfile/aur.files'
87 | localrepo='aur'
88 | builddir="${TMPDIR:-/tmp}/pkgbuild-$UID"
89 | tmpdir="${TMPDIR:-/tmp}/apacmantmp-$UID"
90 | testdir="${TMPDIR:-/tmp}/apacman-testing"
91 |
92 | editor="vi"
93 | [[ $EDITOR ]] && editor="$EDITOR"
94 |
95 | pager="less -R"
96 | [[ $PAGER ]] && pager="$PAGER"
97 |
98 | RPCURL="https://aur.archlinux.org/rpc/?v=5&type"
99 | PKGURL="https://aur.archlinux.org"
100 | WEBURL="https://www.archlinux.org"
101 | ABSURL="rsync.archlinux.org"
102 | legacy="0"
103 |
104 | if [[ -t 1 && ! $COLOR = "NO" ]]; then
105 | COLOR1='\e[1;39m'
106 | COLOR2='\e[1;32m'
107 | COLOR3='\e[1;35m'
108 | COLOR4='\e[1;36m'
109 | COLOR5='\e[1;34m'
110 | COLOR6='\e[1;33m'
111 | COLOR7='\e[1;31m'
112 | ENDCOLOR='\e[0m'
113 | S='\\'
114 | fi
115 | _WIDTH="$(stty size | cut -d ' ' -f 2)"
116 |
117 | trap ctrlc INT
118 | ctrlc() {
119 | echo
120 | exit 1
121 | }
122 |
123 | err() {
124 | echo -e "$1"
125 | [[ "$warn" == 1 ]] || exit 3
126 | }
127 |
128 | dne() {
129 | echo -e "$1"
130 | [[ "$warn" == 1 ]] || exit 5
131 | }
132 |
133 | invalid() {
134 | echo -e "${COLOR7}error:${ENDCOLOR} invalid option \`$1'"
135 | [[ $nofail ]] && exit 2
136 | }
137 |
138 | progress() {
139 | [[ $progress == 1 || $progress == 3 ]] && echo -en "\033]2;$@\007"
140 | [[ $progress == 2 || $progress == 3 ]] && notify-send "$@"
141 | }
142 |
143 | deptest() {
144 | type -p $1 &>/dev/null
145 | }
146 |
147 | version() {
148 | pacver=$($pacmanbin -V 2>/dev/null | grep -o "Pacman v.*")
149 | echo " === = = ===== apacman v${version} - forked from packer"
150 | echo " = = = = = = ${pacver}"
151 | echo ' ===== = = ===='
152 | echo ' = = = = = = This program may be freely redistributed under'
153 | echo ' = = === = = the terms of the GNU General Public License.'
154 | exit
155 | }
156 |
157 | usage() {
158 | echo 'usage: apacman [option] [package] [package] [...]'
159 | echo 'If no operation is specified, searches and installs packages by number'
160 | echo
161 | echo 'OPERATIONS'
162 | echo ' -S - installs package'
163 | echo ' -Syu|-Su - updates all packages, also takes -uu and -yy options'
164 | echo ' -Ss|-Ssq - searches for package'
165 | echo ' -Si - outputs info for package'
166 | echo ' -G - download and extract aur tarball only'
167 | echo ' -L - list installed packages by size'
168 | echo ' -P - passthrough for pkgfile command'
169 | echo ' -W - view web comments for package'
170 | echo
171 | echo 'OPTIONS'
172 | echo ' --asdeps - install AUR packages marked as dependencies'
173 | echo ' --asexplicit - install AUR packages marked as explicit'
174 | echo ' --auronly - only do actions for AUR'
175 | echo ' --buildonly - create but do not install packages'
176 | echo ' --config - specify alternate config file (default: /etc/apacman.conf)'
177 | echo ' --cachevcs - installs cached VCS packages newer than AUR PKGBUILDs'
178 | echo ' --devel - update VCS (git, svn, hg) packages during -Su'
179 | echo ' --edit - always ask to edit PKGBUILD'
180 | echo ' --gendb - generate AUR database files'
181 | echo ' --ignore - takes a comma-separated list of packages to ignore'
182 | echo ' --ignorearch - ignore a missing or incomplete architecture field'
183 | echo ' --keepkeys - do not remove imported PGP keys'
184 | echo ' --legacy - uses AUR3.0 instead of AUR4.0 (deprecated)'
185 | echo ' --needed - do not install up-to-date packages'
186 | echo ' --noaur - do not actions for AUR'
187 | echo ' --noconfirm - do not prompt for any confirmation'
188 | echo ' --nodatabase - do not store AUR database'
189 | echo ' --noedit - do not prompt to edit files'
190 | echo ' --nofail - do not continue if a package fails to build'
191 | echo ' --noprogress - no transaction status in titlebar'
192 | echo ' --nosource - do not source PKGBUILDs (WIP)'
193 | echo ' --notify - transaction status in notification'
194 | echo ' --preview - edit pkgbuild before sourcing'
195 | echo ' --progress - transaction status in terminal titlebar'
196 | echo ' --purgebuild - remove unneeded build dependencies'
197 | echo ' --purgekeys - remove trusted PGP keys'
198 | echo ' --quickcheck - check for updates and exit'
199 | echo ' --quiet - only output package name for searches'
200 | echo ' --savedir - takes a path as the cache directory'
201 | echo ' --skipcache - skips check for pre-built package in cache directory'
202 | echo ' --skipinteg - when using makepkg, do not check md5s'
203 | echo ' --skiptest - when using makepkg, do not parse check() test deps'
204 | echo ' --testing - for unit testing purposes only'
205 | echo ' --warn - treat errors as non-fatal warnings'
206 | echo ' -v - turns on verbose output'
207 | echo ' -V - display version'
208 | echo ' -h - outputs this message'
209 | exit
210 | }
211 |
212 | varstatus() {
213 | val=$(eval echo \$$1)
214 | if [ "$val" == 1 ]; then
215 | echo -e "${COLOR1}$1${ENDCOLOR}" | awk '{printf "%-25s %-40s\n",$1,": yes"}';
216 | elif [ "$val" == 0 ]; then
217 | echo -e "${COLOR1}$1${ENDCOLOR}" | awk '{printf "%-25s %-40s\n",$1,": no"}';
218 | elif [ "$val" == 2 ] || [ "$val" == 3 ]; then
219 | echo -e "${COLOR1}$1${ENDCOLOR}" | awk '{printf "%-25s %-40s\n",$1,": alt mode"}';
220 | elif [[ -r $val ]]; then
221 | echo -e "${COLOR1}$1${ENDCOLOR} $val" | awk '{printf "%-25s %-40s\n",$1,": "$2}';
222 | fi
223 | }
224 |
225 | infoconf() {
226 | vars="apacmanconf builddir database downdir editor localrepo makepkgconf"
227 | vars="$vars pacmanconf pacmandb pkgfiledb savedir tmpdir usermakepkgconf"
228 | for i in $vars; do
229 | varstatus $i
230 | done
231 |
232 | vars="asdeps asexplicit auronly buildonly cachevcs force gendb ignorearch keepkeys"
233 | vars="$vars legacy needed noaur noconfirm nodatabase noedit nofail preview progress"
234 | vars="$vars purgebuild purgekeys quiet skipcache skipinteg skiptest testing warn"
235 | for j in $vars; do
236 | varstatus $j
237 | done
238 | }
239 |
240 | # Called whenever anything needs to be run as root ($@ is the command)
241 | runasroot() {
242 | if [[ $testing == 1 ]]; then
243 | fakeroot "$@" || code='10'
244 | elif [[ $UID -eq 0 ]]; then
245 | "$@" || code='11'
246 | elif sudo -v &>/dev/null && sudo -l "$@" &>/dev/null; then
247 | sudo -E "$@" || code='12'
248 | else
249 | echo -n "root "
250 | su -c "$(printf '%q ' "$@")" || code='13'
251 | fi
252 | }
253 |
254 | # debugging for curl ($1 is curl exit code, $2 package name)
255 | curlyq() {
256 | if [ $1 -eq 6 ]; then
257 | offline='1'
258 | echo -e "${COLOR7}:: ${COLOR1}No internet connection${ENDCOLOR}"
259 | elif [ $1 -ne 0 -a $1 -ne 7 -a $1 -ne 22 ]; then
260 | echo -e "${COLOR6}notice:${ENDCOLOR} curl exited with code $1 on $2"
261 | if deptest man; then
262 | curlman=$(man curl | sed '1,/^EXIT CODES/d' | grep " $1 ")
263 | curlman=$(echo "$curlman" | awk -F " " '{print $3}' | sed 's/^[ \t]*//')
264 | echo -e "${COLOR3}manpage:${ENDCOLOR} $curlman"
265 | fi
266 | fi
267 | }
268 |
269 | # Extract from AUR4 .info
270 | infoparser() {
271 | pkgname=$(jshon -Qe results < $1 -Qe Name -u)
272 | pkgver=$(jshon -Qe results < $1 -Qe Version -u)
273 | pkgbase=$(jshon -Qe results < $1 -Qe PackageBase -u)
274 | url=$(jshon -Qe results < $1 -Qe URL -u)
275 | licnum=$(($(jshon -Qe results < $1 -a -e License -l)-1))
276 | license=$(while [ ${licnum} -ge '0' ]; do jshon -e results < $1 -a -e License -e ${licnum} -u ; ((licnum-=1)) ; done)
277 | groups=$(jshon -Qe results < $1 -Qe PackageBase -u)
278 | }
279 |
280 | # FIXME
281 | parser() {
282 | if [ -f "$1" ]; then
283 | if [[ $nosource == 1 ]]; then
284 | unset pkgname pkgver pkgrel arch checkdepends makedepends depends epoch
285 | pkgname=$(grep -o "^pkgname=\S*" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_.\n');
286 | pkgver=$(grep -o "^pkgver=\S*" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_.\n');
287 | pkgrel=$(grep -o "^pkgrel=\S*" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_.\n');
288 | epoch=$(grep -o "^epoch=\S*" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_.\n');
289 | _arch=$(grep "^arch=" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_. \n');
290 | _checkdepends=$(grep "^checkdepends=" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_. \n');
291 | _makedepends=$(grep "^makedepends=" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_. \n');
292 | _depends=$(grep "^depends=" "$1" | awk -F = '{print $2}' | tr -dc 'a-z0-9-_. \n');
293 |
294 | for _machine in $_arch; do arch+=("$_machine"); done
295 | for _pkg in $_checkdepends; do depends+=("$_pkg"); done
296 | for _pkg in $_makedepends; do makedepends+=("$_pkg"); done
297 | for _pkg in $_depends; do depends+=("$_pkg"); done
298 |
299 | echo "==> pkgname: $pkgname"
300 | echo "==> pkgver: $pkgver"
301 | echo "==> pkgrel: $pkgrel"
302 | echo "==> arch: ${arch[@]}"
303 | echo "==> checkdepends: ${checkdepends[@]}"
304 | echo "==> makedepends: ${makedepends[@]}"
305 | echo "==> depends: ${depends[@]}"
306 | return 0
307 | else
308 | . "$1"
309 | fi
310 | else
311 | return 1
312 | fi
313 | }
314 |
315 | # grep PKGBUILD arrays ($1 is array var)
316 | pkgbuildgrep() {
317 | grep "^${1}=" PKGBUILD 2>/dev/null | awk -F = '{print $2}' | tr -dc 'a-z0-9-_. \n';
318 | }
319 |
320 | # Source apacman.conf file
321 | sourceapacmanconf() {
322 | [[ -r "$apacmanconf" ]] && . "$apacmanconf"
323 | [[ $noconfirm ]] && PACOPTS+=("--noconfirm")
324 | [[ $needed ]] && PACOPTS+=("--needed")
325 | [[ $skiptest ]] && MAKEPKGOPTS+=("--nocheck")
326 | [[ $skipinteg ]] && MAKEPKGOPTS+=("--skipinteg")
327 | [[ $ignorearch ]] && MAKEPKGOPTS+=("--ignorearch")
328 | export keepkeys noconfirm COLOR1 COLOR2 COLOR3 COLOR4 COLOR5 COLOR6 COLOR7 ENDCOLOR
329 | }
330 |
331 | # Source makepkg.conf file
332 | sourcemakepkgconf() {
333 | . "$makepkgconf"
334 | [[ -r "$usermakepkgconf" ]] && . "$usermakepkgconf"
335 | }
336 |
337 | # Parse IgnorePkg and --ignore, put in globally accessible ignoredpackages array
338 | getignoredpackages() {
339 | IFS=',' read -ra ignoredpackages <<< "$ignorearg"
340 | ignoredpackages+=( $(grep '^ *IgnorePkg' "$pacmanconf" | cut -d '=' -f 2-) )
341 | }
342 |
343 | # Checks to see if $1 is an ignored package
344 | isignored() {
345 | [[ " ${ignoredpackages[@]} " =~ " $1 " ]]
346 | }
347 |
348 | # List installed packages
349 | getlistpackages() {
350 | $pacmanbin -Qi${pacmanarg} | grep -e "^Name " -e "^Installed Size " | \
351 | awk '{if ($(NF-1) ~ /^[0-9]/) printf $(NF-1); print $NF}' | paste -s -d' \n' | \
352 | sed -e 's/iB$//' -e 's/\.00K/K/' -e 's/\.00B/B/' | awk '{printf "%-10s %-40s\n",$2,$1}' | sort -h
353 | exit $?
354 | }
355 |
356 | # Tests whether package exists on the aur ($1 is name, $2 is dereferenced variable)
357 | existsinaur() {
358 | chosenpkg=$(echo "$1" | sed 's/\~$//' | awk -F "==" '{print $1}')
359 | val="${!2}"
360 |
361 | regexmatch="$(echo $val | tr -dc '0-9a-z-.\n')"
362 | if [[ $val != $regexmatch ]]; then
363 | matches=$(aurpkglist "$val")
364 | selectprovider "$val" $matches
365 | if [[ $providepkg ]]; then
366 | eval "$2=\"$providepkg\"" 2>/dev/null
367 | chosenpkg="$providepkg"
368 | fi
369 | fi
370 |
371 | rpcinfo "$chosenpkg"
372 | [[ "$(jshon -Qe resultcount -u < "$tmpdir/$chosenpkg.info")" != "0" ]]
373 | }
374 |
375 | # Tests whether $1 exists in pacman
376 | existsinpacman() {
377 | chosenpkg=$1
378 | if [[ $regex = 1 ]]; then
379 | chosenpkg=$(selectprovider)
380 | fi
381 |
382 | $pacmanbin -Si -- "$chosenpkg" &>/dev/null
383 | }
384 |
385 | # Tests whether $1 is provided in pacman, sets globally accessibly providepkg var
386 | providedinpacman() {
387 | unset providepkg
388 | IFS=$'\n' read -rd '' -a providepkg < <($pacmanbin -Ssq -- "^$1$")
389 | selectprovider $1 "${providepkg[@]}"
390 | [[ -n $providepkg ]]
391 | }
392 |
393 | # Select option from numeric choice ($1 is num, $@ is array of choices)
394 | pickone() {
395 | n=1
396 | maxnum=$1
397 | shift
398 | choices=( $(echo $@) )
399 |
400 | for v in ${choices[@]}; do
401 | echo "${n}) $v";
402 | n=$((n+1))
403 | done
404 | echo
405 | echo -n "Enter a selection (default=1): "
406 | read -r
407 |
408 | # Parse answer
409 | if [[ $REPLY ]]; then
410 | for num in $REPLY; do
411 | if [[ $num -le $maxnum ]] && [[ $num -ge 1 ]]; then
412 | num=$((num-1))
413 | chosenone="${choices[$num]}"
414 | else
415 | err "Number \`$num' is not assigned to any of the options."
416 | fi
417 | done
418 | else
419 | chosenone="$choices"
420 | fi
421 |
422 | echo "$chosenone"
423 | }
424 |
425 | # Prompts options for virtual packages, $1 is package, $@ is array of packages
426 | selectprovider() {
427 | virtpkg=$1
428 | shift
429 | virtual=($@)
430 | virtnum="${#virtual[@]}"
431 | if [[ $virtnum -eq 0 ]]; then
432 | return 1
433 | elif [[ $virtnum -eq 1 ]]; then
434 | providepkg="$virtual"
435 | elif [[ $# -gt 1 ]]; then
436 | # Multiple providers
437 | provmsg="provide"
438 | [[ $regex = 1 ]] && provmsg="match" && unset regex
439 | echo -e "${COLOR5}:: ${COLOR1}There are $virtnum packages that $provmsg $virtpkg:${ENDCOLOR}"
440 | providepkg=$(pickone $virtnum ${virtual[@]})
441 | fi
442 | }
443 |
444 | # Source old release ($1 is pkgver, $2 is pkgrel)
445 | checkrelease() {
446 | chistory=$(git rev-list --all)
447 | cmatch=$(git grep --all-match -e "pkgver = $1" -e "pkgrel = $2" ${chistory} -- .SRCINFO)
448 | chash=$(echo "$cmatch" | awk NR==1 | awk -F : '{print $1}')
449 | if [[ ! $chash ]]; then
450 | return 1
451 | fi
452 | }
453 |
454 | # Parse AUR4 git repo
455 | relhistory() {
456 | chistory=$(git rev-list --all)
457 | cpkglog=$(git grep -A 1 -e "pkgver =" ${chistory} -- .SRCINFO)
458 | cversions=$(echo "$cpkglog" | awk '{$1=""; print $0}' | sed -e 's/^$/%%%/')
459 | cwtf=$(echo "$cversions" | sed -e 's/ pkgver = //' -e 's/ pkgrel = /-/')
460 | creleases=$(echo "$cwtf" | tr -d '\n' | sed -e 's/$/\n/' -e 's/%%%/\n/g')
461 | echo "$creleases"
462 | }
463 |
464 | # Select AUR package version ($1 is pkgname)
465 | selectrel() {
466 | release=( $(relhistory) )
467 | relnum=${#release[@]}
468 | echo -e "${COLOR5}:: ${COLOR1}There are $relnum releases for $1:${ENDCOLOR}"
469 | pickone $relnum ${release[@]}
470 | }
471 |
472 | # Build old AUR releases ($1 is package name)
473 | clonehistory() {
474 | if deptest git; then
475 | git clone --quiet "${PKGURL}/${1}.git"
476 | cd "$1"
477 |
478 | if [ -z $2 ]; then
479 | selectrel "$1"
480 | relver="$chosenone"
481 | else
482 | relver="$2"
483 | fi
484 |
485 | if checkrelease ${relver%-*} ${relver##*-}; then
486 | echo -e "${COLOR5}:: ${COLOR1}Checking out $1 ${relver%-*}-${relver##*-}${ENDCOLOR}"
487 | git checkout --quiet "$chash"
488 | ls | sed "s/^/$1\//"
489 | else
490 | err "${COLOR7}error:${ENDCOLOR} package '$1' release '$relver' was not found"
491 | fi
492 | fi
493 | }
494 |
495 | # Tests whether $1 exists in a pacman group
496 | existsinpacmangroup() {
497 | [[ $($pacmanbin -Sgq "$1") ]]
498 | }
499 |
500 | # Tests whether $1 exists locally
501 | existsinlocal() {
502 | $pacmanbin -Qq -- "$1" &>/dev/null
503 | }
504 |
505 | # Scrapes .PKGINFO from local package ($1 is filename)
506 | scrapelocaldeps() {
507 | [[ -f "$1" ]] || err "${COLOR7}error:${ENDCOLOR} '$1': could not access file"
508 | dependencies=( $(pacman -T $(tar -x .PKGINFO -O -f "$1" 2>/dev/null | grep "^depend =" | awk -F " = " '{print $2}')) )
509 | }
510 |
511 | # Scrapes the aur deps from PKGBUILDS and puts in globally available dependencies array
512 | scrapeaurdeps() {
513 | pkginfo "$1" "$preview"
514 | parser "$tmpdir/$1.PKGBUILD"
515 | [[ $skiptest = 1 ]] && unset checkdepends
516 | IFS=$'\n'
517 | dependencies=( $(echo -e "${depends[*]}\n${makedepends[*]}\n${checkdepends[*]}" | sed -e 's/=.*//' -e 's/>.*//' -e 's/<.*//'| sort -u) )
518 | purgedepends=( $(echo -e "${makedepends[*]}\n${checkdepends[*]}" | sed -e 's/=.*//' -e 's/>.*//' -e 's/<.*//'| sort -u) )
519 | unset IFS
520 | }
521 |
522 | # Finds dependencies of package $1
523 | # Sets pacmandeps and aurdeps array, which can be accessed globally after function runs
524 | finddeps() {
525 | # loop through dependencies, if not installed, determine if pacman or aur deps
526 | pacmandeps=()
527 | aurdeps=()
528 | scrapeaurdeps "$1"
529 | [[ $buildonly = 1 || $purgebuild = 1 ]] && purgedeps+=( $($pacmanbin -T "${purgedepends[@]}") )
530 | missingdeps=( $($pacmanbin -T "${dependencies[@]}") )
531 | while [[ $missingdeps ]]; do
532 | checkdeps=()
533 | for dep in "${missingdeps[@]}"; do
534 | if [[ " $1 ${aurdeps[@]} ${pacmandeps[@]} " =~ " $dep " ]]; then
535 | continue
536 | fi
537 | if existsinpacman "$dep"; then
538 | pacmandeps+=("$dep")
539 | elif existsinaur "$dep" "dep"; then
540 | if [[ $aurdeps ]]; then
541 | aurdeps=("$dep" "${aurdeps[@]}")
542 | else
543 | aurdeps=("$dep")
544 | fi
545 | checkdeps+=("$dep")
546 | elif providedinpacman "$dep"; then
547 | pacmandeps+=("$providepkg")
548 | else
549 | [[ $option = "install" ]] && dne "Dependency \`$dep' of \`$1' does not exist."
550 | echo "Dependency \`$dep' of \`$1' does not exist."
551 | return 1
552 | fi
553 | done
554 | missingdeps=()
555 | for dep in "${checkdeps[@]}"; do
556 | scrapeaurdeps "$dep"
557 | for depdep in "${dependencies[@]}"; do
558 | [[ $($pacmanbin -T "$depdep") ]] && missingdeps+=("$depdep")
559 | done
560 | done
561 | done
562 | return 0
563 | }
564 |
565 | # Displays a progress bar ($1 is numerator, $2 is denominator, $3 is candy/normal)
566 | aurbar() {
567 | # Delete line
568 | printf "\033[0G"
569 |
570 | # Get vars for output
571 | beginline=" aur"
572 | beginbar="["
573 | endbar="]"
574 | perc="$(($1*100/$2))"
575 | width="$(stty size)"
576 | width="${width##* }"
577 | infolen="$(($width*6/10))"
578 | [ $infolen -lt 50 ] && infolen=50
579 |
580 | charsbefore="$((${#beginline}+${#1}+${#2}+3))"
581 | spaces="$(($infolen-$charsbefore))"
582 | barchars="$(($width-$infolen-${#beginbar}-${#endbar}-6))"
583 | hashes="$(($barchars*$perc/100))"
584 | dashes="$(($barchars-$hashes))"
585 |
586 | # Print output
587 | printf "$beginline %${spaces}s$1 $2 ${beginbar}" ""
588 |
589 | # ILoveCandy
590 | if [[ $3 = candy ]]; then
591 | for ((n=1; n<$hashes; n++)); do
592 | if (( (n==($hashes-1)) && ($dashes!=0) )); then
593 | (($n%2==0)) && printf "\e[1;33mc\e[0m" || printf "\e[1;33mC\e[0m"
594 | else
595 | printf "-"
596 | fi
597 | done
598 | for ((n=1; n<$dashes; n++)); do
599 | N=$(( $n+$hashes ))
600 | (($hashes>0)) && N=$(($N-1))
601 | (($N%3==0)) && printf "o" || printf " "
602 | done
603 | else
604 | for ((n=0; n<$hashes; n++)); do
605 | printf "#"
606 | done
607 | for ((n=0; n<$dashes; n++)); do
608 | printf "-"
609 | done
610 | fi
611 | printf "%s %3s%%\r" ${endbar} ${perc}
612 | }
613 |
614 | aurpkglist() {
615 | if ! [[ -f "$tmpdir/packages.lst" ]]; then
616 | curl -Lfs "$PKGURL/packages.gz" | gunzip > "$tmpdir/packages.lst"
617 | fi
618 |
619 | grep -E "$1" "$tmpdir/packages.lst" | sort
620 | }
621 |
622 | rpcinfo() {
623 | if ! [[ -f "$tmpdir/$1.info" ]]; then
624 | curl -LfGs --data-urlencode "arg=$1" "$RPCURL=info" > "$tmpdir/$1.info"
625 | fi
626 | }
627 |
628 | pkglink() {
629 | rpcinfo $1
630 | aurpkgpath=$(jshon -Q -e results -a -e URLPath -u < "$tmpdir/$1.info")
631 | [[ $aurpkgpath ]] && echo "${PKGURL}${aurpkgpath}"
632 | }
633 |
634 | absrepo() {
635 | $pacmanbin -Si -- "$1" 2>/dev/null | grep ^Repository | awk '{print $NF}' | awk NR==1
636 | }
637 |
638 | # find pkgbase name for split packages ($1 is package repository, $2 is package name)
639 | absbase() {
640 | webpkg=$(curl -Lfs "$WEBURL/packages/$1/${makearch}/$2/"); cstatus=$?
641 | if [ $cstatus -eq 22 ]; then
642 | webpkg=$(curl -Lfs "$WEBURL/packages/$1/any/$2/"); cstatus=$?
643 | fi
644 |
645 | if [ $cstatus -eq 0 ]; then
646 | echo "$webpkg" | sed -e 's/<[^>]\+>/ /g' -e 's/^[ \t]*//' -e 's/[ \t]*$//' -e '/^$/d' | grep -A 1 "^Base Package:" | sed '1d'
647 | fi
648 | }
649 |
650 | # downloads source files ($1 is package repository, $2 is package name)
651 | abslink() {
652 | deptest rsync || err "${COLOR7}error:${ENDCOLOR} $option requires \`rsync'"
653 | rflags="-mrt --info=progress2 --no-motd --delete-after --no-p --no-o --no-g"
654 | rsync $rflags --include=/$1{,/$2} --exclude=/{$1/,}* ${ABSURL}::abs/{${makearch},any}/ .
655 |
656 | # try again
657 | if [ ! -d "$1/$2" ]; then
658 | pkgbase=$(absbase "$1" "$2")
659 | if [[ $pkgbase ]]; then
660 | [ -d "$1/$pkgbase" ] && rm -r "$1/$pkgbase"
661 | echo -e "${COLOR5}--> ${COLOR1}selected base: $pkgbase${ENDCOLOR}"
662 | rsync $rflags --include=/$1{,/$pkgbase} --exclude=/{$1/,}* ${ABSURL}::abs/{${makearch},any}/ .
663 | mv "$1/$pkgbase" "$1/$2"
664 | fi
665 | fi
666 | }
667 |
668 | # downloads pkgbuild ($1), edits if $2 is set
669 | pkginfo() {
670 | if ! [[ -f "$tmpdir/$1.PKGBUILD" ]]; then
671 | pkgpath=$(pkglink $1)
672 | basepath=$(echo ${pkgpath##*/} | sed 's/\.tar\.gz$//')
673 | [[ $basepath ]] || err "${COLOR7}error:${ENDCOLOR} package '$package' was not found"
674 |
675 | if [[ $legacy == 1 ]]; then
676 | curl -Lfs "${pkgpath%/*}/PKGBUILD" > "$tmpdir/$1.PKGBUILD"
677 | cstatus=$?; curlyq "$cstatus" "$1"
678 | else
679 | curl -Lfs "${pkgpath%/*/*}/plain/PKGBUILD?h=${basepath}" > "$tmpdir/$1.PKGBUILD"
680 | cstatus=$?; curlyq "$cstatus" "$1"
681 | fi
682 |
683 | if [[ $2 ]]; then
684 | # rename for syntax highlighting
685 | cp "$tmpdir/$1.PKGBUILD" "$tmpdir/PKGBUILD"
686 | confirm_edit "${COLOR6}Edit $1 PKGBUILD with \$editor? [Y/n]${ENDCOLOR} " "$tmpdir/PKGBUILD"
687 | mv "$tmpdir/PKGBUILD" "$tmpdir/$1.PKGBUILD"
688 | fi
689 | fi
690 | }
691 |
692 | # Checks if package is newer on aur ($1 is package name, $2 is local version)
693 | aurversionisnewer() {
694 | package="$1"
695 | rpcinfo "$package"
696 | unset aurversion
697 | if existsinaur "$package" "package"; then
698 | aurversion="$(jshon -Q -e results -a -e Version -u < "$tmpdir/$package.info")"
699 | if [[ "$(LC_ALL=C vercmp "$aurversion" "$2")" -gt 0 ]]; then
700 | return 0
701 | fi
702 | fi
703 | return 1
704 | }
705 |
706 | isoutofdate() {
707 | rpcinfo "$1"
708 | [[ "$(jshon -Q -e results -a -e OutOfDate -u < "$tmpdir/$1.info")" = "1" ]]
709 | }
710 |
711 | # Generate local AUR database
712 | aurgendb() {
713 | savecount=$(ls $savedir 2>/dev/null | wc -l)
714 | echo -e "${COLOR5}::${COLOR1} Generating AUR database... ($savecount)${ENDCOLOR}"
715 | progress "Generating AUR DB ($savecount)"
716 | runasroot mkdir -p ${database}/{local,raw}
717 | savedpkgs=$(ls ${savedir}/*-*-{any,${makearch}}.pkg.{tar,tar.xz} 2>/dev/null)
718 | runasroot repo-add ${database}/raw/aur.db.tar.gz $savedpkgs
719 | runasroot tar -xzf ${database}/raw/aur.files.tar.gz -C ${database}/local/
720 | runasroot ln -s ${database}/raw/aur.db.tar.gz $pacmandb 2>/dev/null
721 | aurpkgfile
722 | echo -e "${COLOR5}::${COLOR1} Updated AUR database${ENDCOLOR}"
723 | [[ -z $option && -z $packageargs ]] && exit
724 | }
725 |
726 | # Update AUR pkgfile database
727 | aurpkgfile() {
728 | if ! deptest pkgfile; then
729 | return
730 | fi
731 |
732 | pkgdir=$(mktemp -d)
733 | if [[ -d ${database}/local ]]; then
734 | cd ${database}/local
735 | aurlist=$(ls)
736 | for aurpkg in $aurlist; do
737 | grep -v "^%" $aurpkg/files | sed 's/^/\//' > $pkgdir/$aurpkg
738 | done
739 | fi
740 |
741 | cd "$pkgdir"
742 | runasroot tar -czf ${database}/raw/pkgfile.tar.gz *
743 | cd - >/dev/null
744 | rm -r "$pkgdir"
745 |
746 | pkgfiledir=$(dirname "$pkgfiledb" 2>/dev/null)
747 | if [[ -d "$pkgfiledir" ]]; then
748 | runasroot ln -s ${database}/raw/pkgfile.tar.gz "$pkgfiledb" 2>/dev/null
749 | fi
750 | }
751 |
752 | # Update local AUR database ($1 is package, $2 is filename)
753 | aurlocaldb() {
754 | if [[ $nodatabase ]]; then
755 | return
756 | elif [[ ! -d $database ]] || [[ ! -f $pacmandb ]]; then
757 | runasroot mkdir -p ${database}/{local,raw}
758 | echo -e "${COLOR5}::${COLOR1} Checking AUR database${ENDCOLOR}"
759 | savecount=$(ls $savedir 2>/dev/null | wc -l)
760 | if [[ $savecount -gt 0 ]]; then
761 | echo -e "${COLOR7}warning:${ENDCOLOR} need to run ${COLOR1}apacman --gendb${ENDCOLOR} (found $savecount AUR files!)"
762 | else
763 | runasroot repo-add -q ${database}/raw/aur.db.tar.gz 2>/dev/null
764 | runasroot ln -s ${database}/raw/aur.db.tar.gz $pacmandb 2>/dev/null
765 | fi
766 | fi
767 |
768 | runasroot repo-add -q ${database}/raw/aur.db.tar.gz "$2" 2>/dev/null
769 | pkgnamever=$(echo "$2" | awk -F "$savedir/" '{print $2}' | sed "s/-any.pkg.tar.*//g;s/-${makearch}.pkg.tar.*//g")
770 | runasroot tar -C ${database}/local/ -x "$pkgnamever/" -zf ${database}/raw/aur.files.tar.gz &&
771 | aurpkgfile
772 | }
773 |
774 | # List bundle package files
775 | listbundle() {
776 | if [[ $bundle ]]; then
777 | echo -e "${COLOR5}==>${ENDCOLOR} Packages to bundle"
778 | echo ${bundle[@]} | sed 's/ /\n/g' | tee "$tmpdir/bundle.lst"
779 | fi
780 | }
781 |
782 | # $1 is prompt, $2 is file
783 | confirm_edit() {
784 | if [[ (! -f "$2") || "$noconfirm" || "$noedit" ]]; then
785 | return
786 | fi
787 | echo -en "$1"
788 | if proceed; then
789 | $editor "$2"
790 | fi
791 | }
792 |
793 | # Output status of aur packages ($1 is 0 for success or 1 for failure)
794 | buildstatus() {
795 | if [[ $1 != 0 ]]; then
796 | echo
797 | echo -e "${COLOR7}==> ERROR:${ENDCOLOR} ${COLOR1}the build failed${ENDCOLOR}"
798 | code='8'
799 | fi
800 |
801 | echo -e "${COLOR5} ->${ENDCOLOR} ${COLOR1}Status${ENDCOLOR}"
802 | [[ $success ]] && echo -e "\t${COLOR4}built (${#success[@]}):${ENDCOLOR} ${success[@]}"
803 | [[ $failure ]] && echo -e "\t${COLOR7}failed (${#failure[@]}):${ENDCOLOR} ${failure[@]}"
804 | [[ $remains ]] && echo -e "\t${COLOR6}remain (${#remains[@]}):${ENDCOLOR} ${remains[@]}"
805 | echo ""
806 |
807 | [[ $nofail = 1 && $1 != 0 ]] && exit 9
808 | }
809 |
810 | # Build install ($1 is package, $2 is dependency or explicit, $3 is filename)
811 | buildinstall() {
812 | if [[ $2 = dependency ]]; then
813 | runasroot $PACMAN ${PACOPTS[@]} --asdeps -U "$3"
814 | aurlocaldb "$1" "$3"
815 | [[ $buildonly = 1 ]] && bundle+=("$3")
816 | [[ $buildonly = 1 ]] && purgedeps+=("$1")
817 | elif [[ $2 = explicit ]]; then
818 | [[ $buildonly = 1 ]] && echo -e "${COLOR6}notice:${ENDCOLOR} $1 built -- not installing"
819 | [[ $buildonly = 1 ]] && bundle+=("$3")
820 | [[ $buildonly != 1 ]] && progress "Installing ${pkgnum}/${totalcount} $1"
821 | [[ $buildonly != 1 ]] && runasroot $PACMAN ${PACOPTS[@]} -U "$3"
822 | [[ $buildonly != 1 ]] && aurlocaldb "$1" "$3"
823 | fi
824 | }
825 |
826 | # Checks if aur cache is newer than aur ($1 is package, $2 is aur version)
827 | checkvcs() {
828 | cachefile=$(ls -t ${savedir}/${1}-*-{any,${makearch}}.pkg.{tar,tar.xz} 2>/dev/null | awk NR==1 | awk -F "${savedir}/${1}-" '{print $2}');
829 | cachever=$(echo "$cachefile" | sed "s/-any.pkg.tar.*//g;s/-${makearch}.pkg.tar.*//g");
830 | if [[ "$(LC_ALL=C vercmp "$cachever" "$2")" -gt 0 ]]; then
831 | echo -e "${COLOR7}warning:${ENDCOLOR} $1 -- ${COLOR7}verify cache newer than AUR${ENDCOLOR} ($pkgver-$pkgrel)"
832 | pkgfile="${savedir}/${1}-${cachefile}";
833 | elif [[ "$(LC_ALL=C vercmp "$cachever" "$2")" -eq 0 ]]; then
834 | pkgfile="${savedir}/${1}-${cachefile}";
835 | fi
836 | }
837 |
838 | # Checks if packages are in aur cache ($1 is package, $2 is dependency or explicit)
839 | checkcache() {
840 | unset pkgfile;
841 |
842 | if [ "$skipcache" != "1" ]; then
843 | sourcemakepkgconf
844 | pkgfile=$(ls ${savedir}/${1}-${pkgver}-${pkgrel}-{any,${makearch}}.pkg.{tar,tar.xz} 2>/dev/null | awk NR==1);
845 | fi
846 |
847 | if [ "$cachevcs" = "1" ]; then
848 | checkvcs $1 $pkgver-$pkgrel
849 | fi
850 |
851 | pkgnum=$((pkgnum+1))
852 | if [ -f "$pkgfile" ]; then
853 | #progress "Installing ${pkgnum}/${totalcount} $1"
854 | cacheinstall "$1" "$2" "$pkgfile"
855 | else
856 | progress "Building ${pkgnum}/${totalcount} $1"
857 | aurinstall "$1" "$2"
858 | fi;
859 | }
860 |
861 | # Installs packages from cache ($1 is package, $2 is dependency or explicit, $3 is filename)
862 | cacheinstall() {
863 | if [ "$cachevcs" = "1" ]; then
864 | pkgrelease="$1-$cachever"
865 | else
866 | pkgrelease="$1-$pkgver-$pkgrel"
867 | fi
868 |
869 | if [[ $offline = '1' ]]; then
870 | offlinemsg="${COLOR4} offline${ENDCOLOR}"
871 | fi
872 |
873 | echo -e "${COLOR6}notice:${ENDCOLOR}${offlinemsg} installing $pkgrelease from cache"
874 | remains=(${remains[@]/$1/})
875 | buildinstall $1 $2 $3
876 | }
877 |
878 | # Retrieve PGP keys ($@ is ${validpgpkeys[@]})
879 | export gpgconf
880 | checkpgpkeys() {
881 | if [[ $1 ]]; then
882 | gpg --fingerprint $@ 2>/dev/null
883 | fi
884 | }; export -f checkpgpkeys
885 |
886 | # Prompt to import PGP keys ($@ is ${validpgpkeys[@]})
887 | askpgpkeys() {
888 | echo -e "\n${COLOR6}warning:${ENDCOLOR} One or more PGP signatures unknown"
889 | for pgpkey in $@; do
890 | echo -e "\t${COLOR7}${pgpkey}${ENDCOLOR}"
891 | done
892 | echo -en "${COLOR5}:: ${COLOR1}Verify PGP keys? [Y/n]${ENDCOLOR} "
893 | if ! [[ $noconfirm ]]; then
894 | proceed || exit
895 | else
896 | echo
897 | fi
898 | }; export -f askpgpkeys
899 |
900 | # Import PGP keys ($@ is ${validpgpkeys[@]})
901 | addpgpkeys() {
902 | [ -f $HOME/.gnupg/gpg.conf ] || cp $gpgconf $HOME/.gnupg/
903 | for pgpkey in $@; do
904 | echo -e "${COLOR6}trusting:${ENDCOLOR} ${COLOR7}${pgpkey}${ENDCOLOR}"
905 | gpg --recv-key $pgpkey
906 | done
907 | }; export -f addpgpkeys
908 |
909 | # Remove added PGP keys ($@ is ${validpgpkeys[@]})
910 | removepgpkeys() {
911 | if ! [[ $keepkeys ]]; then
912 | keycheck=$(gpg --fingerprint $@ 2>/dev/null)
913 | if [[ $keycheck ]]; then
914 | echo -e "${COLOR5} -> ${COLOR1}Removed $# trusted keys${ENDCOLOR}"
915 | gpg --batch --yes --delete-keys $@
916 | fi
917 | fi
918 | }; export -f removepgpkeys
919 |
920 | # Installs cached packages offline ($1 is package, $2 is dependency or explicit)
921 | offlineinstall() {
922 | cachedpkgs=$(ls ${savedir}/*-{any,${makearch}}.pkg.{tar,tar.xz} 2>/dev/null | awk -F "$savedir/" '{print $2}')
923 | cachedpkgs=$(echo "$cachedpkgs" | awk -F "-" '{for(i=1;i<=NF-3;++i) printf $i"-"; print " " $(NF-2) " " $(NF-1) " " $NF}' 2>/dev/null)
924 | cachedarray=$(echo "$cachedpkgs" | sed 's/- / /' | grep "^$1 " | sort -n | tail -n 1)
925 | if [[ $cachedarray ]]; then
926 | pkgver=$(echo "$cachedarray" | awk '{print $2}')
927 | pkgrel=$(echo "$cachedarray" | awk '{print $3}')
928 | pkgext=$(echo "$cachedarray" | awk '{print $4}')
929 | pkgfile=$(ls ${savedir}/${1}-${pkgver}-${pkgrel}-${pkgext} 2>/dev/null)
930 | fi
931 |
932 | if [ -f "$pkgfile" ]; then
933 | cacheinstall "$1" "$2" "$pkgfile"
934 | else
935 | echo "Package \`$1' does not exist in cache."
936 | exit 6
937 | fi
938 | }
939 |
940 | # Sanity check for umask permissions ($1 is build directory)
941 | checkumask() {
942 | otherbits=$(ls -ld "$1" | awk '{print $1}' | cut -c 8,10)
943 | if [[ $otherbits != "rx" ]]; then
944 | mask=$(umask 2>/dev/null)
945 | if [[ $mask != *022 ]]; then
946 | echo -e "${COLOR6}warning:${ENDCOLOR} umask set to ${COLOR4}${mask}${ENDCOLOR} (should be 022)"
947 | fi
948 | rmdir "$1"
949 | err "${COLOR7}error:${COLOR1} no write permission in ${1}${ENDCOLOR}"
950 | fi
951 | }
952 |
953 | # Sanity check for tmpfs free disk space ($1 is build directory)
954 | checkcapacity() {
955 | capacity=$(df -P "$1" 2>/dev/null | tail -n 1 | awk '{print $5}' | tr -dc '[0-9]\n')
956 | if [[ $capacity -ge 99 ]]; then
957 | echo -e "${COLOR7}error:${COLOR1} no free space in ${1}${ENDCOLOR}"
958 | [[ "$warn" == 1 ]] || exit 7
959 | elif [[ $capacity -gt 90 ]]; then
960 | echo -e "${COLOR6}warning:${ENDCOLOR} low disk space in ${1} (tmpfs)"
961 | fi
962 | }
963 |
964 | # Clean package source ($1 is package)
965 | cleanbuild() {
966 | whatlinkshere=$(ls -l --color=never "$builddir" | grep ^l | grep "/${1}$" | awk '{print $(NF-2)}')
967 | if [[ $whatlinkshere ]]; then
968 | echo -e "${COLOR3}notice:${ENDCOLOR} cleaning delayed until finished with $whatlinkshere"
969 | else
970 | [[ $verbose ]] &&
971 | echo -e "${COLOR5}::${COLOR1} Cleaning build ${builddir}/$1 ${ENDCOLOR}"
972 | rm -rf "${builddir}/$1"
973 | rm "${tmpdir}/$1.info" "${tmpdir}/$1.PKGBUILD"
974 | fi
975 | }
976 |
977 | # Installs packages from aur ($1 is package, $2 is dependency or explicit)
978 | aurinstall() {
979 | if [[ $offline = '1' ]]; then
980 | offlineinstall "$1" "$2"
981 | else
982 | aurmakepkg "$1" "$2"
983 | fi
984 | }
985 |
986 | # Installs packages from aur ($1 is package, $2 is dependency or explicit)
987 | aurmakepkg() {
988 | unset validpgpkeys
989 | dir="${builddir}/$1"
990 | sourcemakepkgconf
991 |
992 | # Prepare the installation directory
993 | # If there is an old directory and aurversion is not newer, use old directory
994 | if parser "$dir/PKGBUILD" &>/dev/null && ! aurversionisnewer "$1" "$pkgver-$pkgrel"; then
995 | checkumask "$dir"
996 | checkcapacity "$dir"
997 | cd "$dir"
998 | else
999 | [[ -d "$dir" ]] && rm -rf "$dir"
1000 | mkdir -p "$builddir"
1001 | checkumask "$builddir"
1002 | checkcapacity "$builddir"
1003 | cd "$builddir"
1004 | curl -Lfs "$(pkglink $1)" > "$1.tar.gz"
1005 | cstatus=$?; curlyq "$cstatus" "$1"
1006 | mkdir "$1"
1007 | tar -xf "$1.tar.gz" -C "$1" --strip-components=1
1008 | cd "$1"
1009 | if [[ $preview && -s "$tmpdir/$1.PKGBUILD" ]]; then
1010 | cp "$tmpdir/$1.PKGBUILD" PKGBUILD
1011 | fi
1012 | # customizepkg
1013 | if [[ -f "/etc/customizepkg.d/$1" ]] && deptest customizepkg; then
1014 | echo "Applying customizepkg instructions..."
1015 | customizepkg --modify
1016 | fi
1017 | fi
1018 |
1019 | # Check for split PKGBUILD
1020 | pkgbase=($(pkgbuildgrep pkgbase));
1021 | pkgname=($(pkgbuildgrep pkgname));
1022 | if [[ "${pkgbase[@]}" ]]; then
1023 | echo -e " ${COLOR5}->${ENDCOLOR}${COLOR1} Split package base: ${pkgbase[@]}${ENDCOLOR}";
1024 | if [[ "${#pkgname[@]}" -gt 1 ]]; then
1025 | echo -e " ${COLOR5}->${ENDCOLOR}${COLOR1} PKGBUILD contains: ${pkgname[@]}${ENDCOLOR}";
1026 | for split in ${pkgname[@]}; do
1027 | ln -s "${builddir}/$1" "${builddir}/$split" 2>/dev/null;
1028 | done
1029 | fi
1030 | fi
1031 |
1032 | # Check for missing arch
1033 | arch=($(pkgbuildgrep arch));
1034 | if [[ ! " ${arch[@]} " =~ " any " ]]; then
1035 | if [[ ! " ${arch[@]} " =~ " ${CARCH} " ]]; then
1036 | echo -e "${COLOR6}warning:$ENDCOLOR $CARCH missing from arch array"
1037 | fi
1038 | fi
1039 |
1040 | # Allow user to edit PKGBUILD
1041 | confirm_edit "${COLOR6}Edit $1 PKGBUILD with \$editor? [Y/n]${ENDCOLOR} " PKGBUILD
1042 | if ! [[ -f PKGBUILD ]]; then
1043 | err "No PKGBUILD found in directory."
1044 | fi
1045 |
1046 | # Allow user to edit .install
1047 | unset install
1048 | parser PKGBUILD
1049 | confirm_edit "${COLOR6}Edit $install with \$editor? [Y/n]${ENDCOLOR} " "$install"
1050 |
1051 | # Installation (makepkg and pacman)
1052 | rm -f *$PKGEXT
1053 | if [[ $UID -eq 0 ]]; then
1054 | id aurbuild >/dev/null 2>/dev/null || useradd -r -d /var/empty aurbuild
1055 | mkdir -p /var/empty/.gnupg
1056 | chown -R aurbuild:aurbuild . /var/empty/.gnupg
1057 |
1058 | if [[ $validpgpkeys ]]; then
1059 | su aurbuild -c "gpg --refresh-keys ${validpgpkeys[*]}"
1060 | keyfound=$(su aurbuild -c "checkpgpkeys ${validpgpkeys[*]}" 2>/dev/null)
1061 | if ! [[ $keyfound ]]; then
1062 | askpgpkeys "${validpgpkeys[*]}"
1063 | su aurbuild -c "addpgpkeys ${validpgpkeys[*]}"
1064 | fi
1065 | su aurbuild -c "makepkg $MAKEPKGOPTS -f"; buildcheck=$?
1066 | [[ $keyfound ]] || su aurbuild -c "removepgpkeys ${validpgpkeys[*]}"
1067 | [[ $purgekeys ]] && [[ $keyfound ]] && su aurbuild -c "removepgpkeys ${validpgpkeys[*]}"
1068 | else
1069 | su aurbuild -c "makepkg $MAKEPKGOPTS -f"; buildcheck=$?
1070 | fi
1071 | else
1072 | if [[ $validpgpkeys ]]; then
1073 | gpg --refresh-keys "${validpgpkeys[@]}"
1074 | keyfound=$(checkpgpkeys "${validpgpkeys[@]}" 2>/dev/null)
1075 | if ! [[ $keyfound ]]; then
1076 | askpgpkeys "${validpgpkeys[@]}"
1077 | addpgpkeys "${validpgpkeys[@]}"
1078 | fi
1079 | makepkg $MAKEPKGOPTS -f; buildcheck=$?
1080 | [[ $keyfound ]] || removepgpkeys "${validpgpkeys[@]}"
1081 | [[ $purgekeys ]] && [[ $keyfound ]] && removepgpkeys "${validpgpkeys[@]}"
1082 | else
1083 | makepkg $MAKEPKGOPTS -f; buildcheck=$?
1084 | fi
1085 | fi
1086 |
1087 | # Build check
1088 | remains=(${remains[@]/$1/});
1089 | if [[ $buildcheck -ne 0 ]]; then
1090 | failure+=("$1")
1091 | buildstatus 1
1092 | else
1093 | success+=("$1")
1094 | buildstatus 0
1095 | fi
1096 |
1097 | # Reparse PKGBUILD, possibly modified during build
1098 | parser PKGBUILD
1099 | # Save packages
1100 | [ ${epoch} ] && epoch=${epoch}:
1101 | pkgtar=$(ls $1-${epoch}${pkgver}*${PKGEXT} 2>/dev/null | tail -n 1)
1102 | if [[ $pkgtar ]]; then
1103 | [ -d $savedir ] || mkdir -p $savedir 2>/dev/null || runasroot mkdir -p $savedir
1104 | echo -e "${COLOR5} -> ${COLOR1}Saving package:${ENDCOLOR} ${pkgtar}"
1105 | cp ${pkgtar} $savedir/ 2>/dev/null || runasroot cp ${pkgtar} $savedir/
1106 | echo -e "${COLOR5} -> ${COLOR1}Installing ${1}${ENDCOLOR}"
1107 | buildinstall $1 $2 ${savedir}/$pkgtar
1108 | cleanbuild $1
1109 | elif [[ $nofail ]]; then
1110 | cleanbuild $1
1111 | fi
1112 | }
1113 |
1114 | # Passthrough for pkgfile
1115 | pkgfilehandling() {
1116 | if ! deptest pkgfile; then
1117 | err "${COLOR7}error:${ENDCOLOR} $1 requires \`pkgfile'"
1118 | return
1119 | fi
1120 |
1121 | if [[ ! -f $pacmandb ]]; then
1122 | echo -e "${COLOR7}warning:${ENDCOLOR} need to run ${COLOR1}apacman --gendb${ENDCOLOR}"
1123 | fi
1124 |
1125 | if [[ $1 = -P* ]] && [[ $1 != -P ]]; then
1126 | Parg=$(echo $1 | sed 's/P//g')
1127 | fi
1128 |
1129 | shift
1130 | pkgfile -C <(cat $pacmanconf | sed "$ a [$localrepo]") $Parg "$@"
1131 | exit $?
1132 | }
1133 |
1134 | # Install local packages (-U)
1135 | localhandling() {
1136 | pacmanarg="$1"
1137 | shift
1138 |
1139 | for arg in $@; do
1140 | if [ -f "$arg" ]; then
1141 | localpkg+=("$arg")
1142 | else
1143 | args+=("$arg")
1144 | fi
1145 | done
1146 |
1147 | for pkg in ${localpkg[@]}; do
1148 | scrapelocaldeps $pkg
1149 | echo -e "${COLOR3}notice:${ENDCOLOR} installing dependencies for $pkg"
1150 | if [[ $dependencies ]]; then
1151 | $0 -S "${args[@]}" ${dependencies[@]} --asdeps --localinstall --needed
1152 | fi
1153 | done
1154 | runasroot $pacmanbin $pacmanarg "${localpkg[@]}"
1155 | }
1156 |
1157 | # Goes through all of the install tests and execution ($@ is packages to be installed)
1158 | installhandling() {
1159 | packageargs=("$@")
1160 | getignoredpackages
1161 | sourcemakepkgconf
1162 | # Figure out all of the packages that need to be installed
1163 | for package in "${packageargs[@]}"; do
1164 | # Determine whether package is in pacman repos
1165 | if ! [[ $auronly ]] && existsinpacman "$package"; then
1166 | pacmanpackages+=("$package")
1167 | elif ! [[ $auronly ]] && existsinpacmangroup "$package"; then
1168 | pacmanpackages+=("$package")
1169 | elif ! [[ $auronly ]] && providedinpacman "$package"; then
1170 | pacmanpackages+=("$providepkg")
1171 | elif ! [[ $noaur ]] && existsinaur "$package" "package"; then
1172 | if finddeps "$package"; then
1173 | # here is where dep dupes are created
1174 | aurpackages+=("$package")
1175 | aurdepends=("${aurdeps[@]}" "${aurdepends[@]}")
1176 | pacmandepends+=("${pacmandeps[@]}")
1177 | fi
1178 | else
1179 | dne "Package \`$package' does not exist."
1180 | fi
1181 | done
1182 |
1183 | # Check if any aur target packages are ignored
1184 | for package in "${aurpackages[@]}"; do
1185 | if isignored "$package"; then
1186 | echo -ne "${COLOR5}:: ${COLOR1}$package is in IgnorePkg/IgnoreGroup. Install anyway?${ENDCOLOR} [Y/n] "
1187 | if ! [[ $noconfirm ]]; then
1188 | proceed || continue
1189 | else
1190 | echo
1191 | fi
1192 | fi
1193 | aurtargets+=("$package")
1194 | done
1195 |
1196 | # Check if any aur dependencies are ignored
1197 | for package in "${aurdepends[@]}"; do
1198 | if isignored "$package"; then
1199 | echo -ne "${COLOR5}:: ${COLOR1}$package is in IgnorePkg/IgnoreGroup. Install anyway?${ENDCOLOR} [Y/n] "
1200 | if ! [[ $noconfirm ]]; then
1201 | if ! proceed; then
1202 | echo "Unresolved dependency \`$package'"
1203 | unset aurtargets
1204 | break
1205 | fi
1206 | else
1207 | echo
1208 | fi
1209 | fi
1210 | done
1211 |
1212 | # First install the explicit pacman packages, let pacman prompt
1213 | if [[ $pacmanpackages ]]; then
1214 | echo -e "${COLOR6}Pacman Targets ($((${#pacmanpackages[@]}))):${ENDCOLOR} ${pacmanpackages[@]}"
1215 | echo
1216 | if [[ $buildonly = 1 ]]; then
1217 | downfile=$($PACMAN -Sp -- "${pacmanpackages[@]}" | awk -v dir=$downdir -F "/" '{print dir"/"$NF}')
1218 | bundle+=("${downfile}")
1219 | runasroot $PACMAN "${PACOPTS[@]}" -Sw --cachedir $downdir -- "${pacmanpackages[@]}"
1220 | else
1221 | runasroot $PACMAN "${PACOPTS[@]}" -S -- "${pacmanpackages[@]}"
1222 | fi
1223 | fi
1224 | if [[ -z $aurtargets ]]; then
1225 | listbundle
1226 | exit
1227 | fi
1228 |
1229 | # Test if aurpackages are already installed; echo warning if so
1230 | for pkg in "${aurtargets[@]}"; do
1231 | if existsinlocal "$pkg"; then
1232 | localversion="$($pacmanbin -Qs "$pkg" | grep -F "local/$pkg " | cut -d ' ' -f 2)"
1233 | if ! aurversionisnewer "$pkg" "$localversion"; then
1234 | if [ "$needed" = "1" ]; then
1235 | [[ $localinstall ]] ||
1236 | echo -e "${COLOR6}notice:$ENDCOLOR $pkg-$localversion is up to date -- skipping"
1237 | aurtargets=(${aurtargets[@]/$pkg/});
1238 | else
1239 | echo -e "${COLOR6}warning:$ENDCOLOR $pkg-$localversion is up to date -- reinstalling"
1240 | fi
1241 | fi
1242 | fi
1243 | done
1244 |
1245 | # Echo warning if packages are out of date
1246 | for pkg in "${aurtargets[@]}" "${aurdepends[@]}"; do
1247 | if isoutofdate "$pkg"; then
1248 | echo -e "${COLOR6}warning:$ENDCOLOR $pkg is flagged out of date"
1249 | fi
1250 | done
1251 |
1252 | # Prompt for aur packages and their dependencies
1253 | num="$((${#aurdepends[@]}+${#aurtargets[@]}))"
1254 | if [[ $num -eq 0 ]] && [[ $localinstall ]]; then
1255 | true
1256 | elif [[ $aurdepends ]]; then
1257 | echo
1258 | echo -e "${COLOR6}Aur Targets ($num):${ENDCOLOR} ${aurdepends[@]} ${aurtargets[@]}"
1259 | else
1260 | echo
1261 | echo -e "${COLOR6}Aur Targets ($((${#aurtargets[@]}))):${ENDCOLOR} ${aurtargets[@]}"
1262 | fi
1263 |
1264 | # Prompt for pacman dependencies
1265 | if [[ $pacmandepends ]]; then
1266 | IFS=$'\n' read -rd '' -a pacmandepends < \
1267 | <(printf "%s\n" "${pacmandepends[@]}" | sort -u)
1268 | echo -e "${COLOR6}Pacman Targets (${#pacmandepends[@]}):${ENDCOLOR} ${pacmandepends[@]}"
1269 | fi
1270 |
1271 | # Sanity check
1272 | pkgnum="${#pacmandepends[@]}"
1273 | totalcount="$((${#aurdepends[@]}+${#aurtargets[@]}+${#pacmandepends[@]}))"
1274 | remains=($(printf "%s\n" "${aurdepends[@]}" "${aurtargets[@]}" | sort -u))
1275 | if [ "$totalcount" = "0" ]; then
1276 | [[ $localinstall ]] ||
1277 | echo -e "${COLOR5}==>$ENDCOLOR nothing to do"
1278 | exit 0
1279 | fi
1280 |
1281 | # Prompt to proceed
1282 | [[ $buildonly = 1 ]] && phrasing="building" || phrasing="installation"
1283 | echo -en "\n${COLOR5}:: ${COLOR1}Proceed with ${phrasing}? [Y/n]${ENDCOLOR} "
1284 | if ! [[ $noconfirm ]]; then
1285 | proceed || exit
1286 | else
1287 | echo
1288 | fi
1289 |
1290 | # Install pacman dependencies
1291 | if [[ $pacmandepends ]]; then
1292 | if [[ $buildonly = 1 ]]; then
1293 | downfile=$($PACMAN -Sp -- "${pacmandepends[@]}" | awk -v dir=$downdir -F "/" '{print dir"/"$NF}')
1294 | bundle+=("${downfile}")
1295 | fi
1296 | progress "Installing ${pkgnum}/${totalcount} packages"
1297 | runasroot $PACMAN --noconfirm --asdeps -S -- "${pacmandepends[@]}" || err "Installation failed."
1298 | fi
1299 |
1300 | # Install aur dependencies
1301 | if [[ $aurdepends ]]; then
1302 | for dep in "${aurdepends[@]}"; do
1303 | checkcache "$dep" "dependency"
1304 | done
1305 | fi
1306 |
1307 | # Install the aur packages
1308 | for package in "${aurtargets[@]}"; do
1309 | scrapeaurdeps "$package"
1310 | if $pacmanbin -T "${dependencies[@]}" &>/dev/null; then
1311 | checkcache "$package" "explicit"
1312 | else
1313 | echo "Dependencies for \`$package' are not met, not building..."
1314 | fi
1315 | done
1316 |
1317 | # Remove build dependencies
1318 | if [[ $buildonly = 1 ]]; then
1319 | purgedeps+=("${pacmandepends[@]}")
1320 | fi
1321 | if [[ $purgedeps ]]; then
1322 | purgedepends=( $(echo -e "${purgedeps[*]}" | sort -u) )
1323 | progress "Removing ${#purgedepends[@]} build depends"
1324 | runasroot $pacmanbin --noconfirm -Ru -- "${purgedepends[@]}" 2>/dev/null
1325 | fi
1326 |
1327 | listbundle
1328 | exit $code
1329 | }
1330 |
1331 | run_quick_check() {
1332 | bigurl="$RPCURL=multiinfo"
1333 | for p in $($pacmanbin -Qqm); do
1334 | bigurl="$bigurl&arg\[\]=$p"
1335 | done
1336 | parsed_aur="$(curl -s "$bigurl" | \
1337 | jshon -e results -a -e Name -u -p -e Version -u | \
1338 | sed 's/^$/-/' | paste -s -d '\t\n' | sort)"
1339 | packages="$(expac -Q '%n\t%v' | sort)"
1340 | comm -23 <(echo "$parsed_aur") <(echo "$packages") | cut -f 1
1341 | if [[ $auronly == 1 ]]; then
1342 | return
1343 | fi
1344 | # see https://mailman.archlinux.org/pipermail/pacman-dev/2011-October/014673.html
1345 | # (note to self, get that merged already...)
1346 | if [[ -z $CHECKUPDATE_DB ]]; then
1347 | CHECKUPDATE_DB="${TMPDIR:-/tmp}/checkup-db-${USER}/"
1348 | fi
1349 | eval $(awk '/DBPath/ {print $1$2$3}' $pacmanconf)
1350 | DBPath="${DBPath:-/var/lib/pacman/}"
1351 | mkdir -p "$CHECKUPDATE_DB"
1352 | ln -s "${DBPath}/local" "$CHECKUPDATE_DB" &> /dev/null
1353 | fakeroot $pacmanbin -Sqy --dbpath "$CHECKUPDATE_DB" &> /dev/null
1354 | $pacmanbin -Qqu --dbpath "$CHECKUPDATE_DB" 2> /dev/null
1355 | }
1356 |
1357 | # proceed with installation prompt
1358 | proceed() {
1359 | read -n 1
1360 | echo
1361 | case "$REPLY" in
1362 | 'Y'|'y'|'') return 0 ;;
1363 | *) return 1 ;;
1364 | esac
1365 | }; export -f proceed
1366 |
1367 | # process busy loop
1368 | nap() {
1369 | while (( $(jobs | wc -l) >= 8 )); do
1370 | jobs > /dev/null
1371 | done
1372 | }
1373 |
1374 | # Parse --config parameter early
1375 | loadconfig() {
1376 | for flag in $@; do
1377 | if [[ $nextflag = 1 ]]; then
1378 | apacmanconf="$flag"
1379 | unset nextflag
1380 | return
1381 | elif [[ $flag = "--config" ]]; then
1382 | nextflag='1'
1383 | elif [[ $flag = --config* ]]; then
1384 | apacmanconf="$flag"
1385 | return
1386 | fi
1387 | done
1388 | }
1389 |
1390 | # Unit testing env
1391 | enabletesting() {
1392 | savedir="$testdir"
1393 | PACOPTS+=("-r" "$testdir")
1394 | PACOPTS+=("--cachedir" "${testdir}/var/cache/pacman/pkg")
1395 | PACOPTS+=("--dbpath" "${testdir}/var/lib/pacman")
1396 | }
1397 |
1398 |
1399 | # Wrap pacman parameters
1400 | pacwrap() {
1401 | if [[ $1 = -Q* ]]; then
1402 | $pacmanbin "$@";
1403 | elif [[ $1 = -T* ]]; then
1404 | $pacmanbin "$@";
1405 | elif [[ $1 = -U* ]]; then
1406 | localhandling "$@"
1407 | elif [[ $1 = -P* ]]; then
1408 | pkgfilehandling "$@";
1409 | elif [[ $1 = --pkgfile ]]; then
1410 | pkgfilehandling "$@";
1411 | else
1412 | runasroot $pacmanbin "$@";
1413 | fi;
1414 | exit $?
1415 | }
1416 |
1417 | # Override defaults
1418 | loadconfig $@
1419 | sourceapacmanconf
1420 |
1421 | # Argument parsing
1422 | [[ $1 ]] || usage
1423 | packageargs=()
1424 | while [[ $1 ]]; do
1425 | case "$1" in
1426 | '-S') option=install ;;
1427 | '-Ss') option=search ;;
1428 | '-Ssq'|'-Sqs') option=search ; quiet='1' ;;
1429 | '-Si') option=info ;;
1430 | -S*u*) option=update ; escaperope='1' ; pacmanarg="$1" ;;
1431 | '-G') option=download ;;
1432 | -L*) option=list ; escaperope='1' ; pacmanarg="${1//-L}" ;;
1433 | -W*) option=web ; pacmanarg="${1//-W}" ;;
1434 | '--asdeps') asdeps='1' PACOPTS+=("--asdeps") ; export asdeps; unset asexplicit ;;
1435 | '--asexplicit') asexplicit='1' PACOPTS+=("--asexplicit"); export asexplicit; unset asdeps ;;
1436 | '--auronly') auronly='1' ; unset noaur ;;
1437 | '--buildonly') buildonly='1' ;;
1438 | '--cachevcs') cachevcs='1' ;;
1439 | '--config') config='1' ; shift ;;
1440 | --config=*) config='1' ; equals+=("--config") ;;
1441 | '--devel') devel='1' ;;
1442 | '--edit') unset noedit ;;
1443 | '--force') force='1' PACOPTS+=("--force");;
1444 | '--gendb') gendb='1' ;;
1445 | '--ignore') ignorearg="$2" ; PACOPTS+=("--ignore" "$2") ; shift ;;
1446 | --ignore=*) ignorearg="$1" ; equals+=("--ignore") ;;
1447 | '--ignorearch') MAKEPKGOPTS+=("--ignorearch");;
1448 | '--keepkeys') keepkeys='1' ; export keepkeys ;;
1449 | '--legacy') legacy='1' ;;
1450 | '--localinstall') localinstall='1' ;;
1451 | '--needed') needed='1' PACOPTS+=("--needed");;
1452 | '--noaur') noaur='1' ; unset auronly ;;
1453 | '--noconfirm') noconfirm='1' PACOPTS+=("--noconfirm") ; export noconfirm ;;
1454 | '--nodatabase') nodatabase='1' ;;
1455 | '--noedit') noedit='1' ;;
1456 | '--nofail') nofail='1' ;;
1457 | '--noprogress') unset progress ;;
1458 | '--nosource') nosource='1' ;;
1459 | '--notify') progress='2' ;;
1460 | '--pkgfile') pacwrap "$@" ;;
1461 | '--preview') preview='1' ;;
1462 | '--progress') progress='1' ;;
1463 | '--purgebuild') purgebuild='1' ;;
1464 | '--purgekeys') purgekeys='1' ;;
1465 | '--quickcheck') quickcheck='1' ;;
1466 | '--quiet') quiet='1' ;;
1467 | '--savedir') savedir="$2" ; shift ;;
1468 | --savedir=*) savedir="$1"; equals+=("--savedir") ;;
1469 | '--skipcache') skipcache='1' ;;
1470 | '--skipinteg') skipinteg='1' ; MAKEPKGOPTS+=("--skipinteg");;
1471 | '--skiptest') skiptest='1' ; MAKEPKGOPTS+=("--nocheck");;
1472 | '--testing') testing='1' ; enabletesting ;;
1473 | '--warn') warn='1' ;;
1474 | '-h'|'--help') usage ;;
1475 | '-v'|'--verbose') verbose='1' ;;
1476 | '-V'|'--version') version ;;
1477 | '--') shift ; packageargs+=("$@") ; break ;;
1478 | -D*) pacwrap "$@" ;;
1479 | -P*) pacwrap "$@" ;;
1480 | -Q*) pacwrap "$@" ;;
1481 | -R*) pacwrap "$@" ;;
1482 | -S*) pacwrap "$@" ;;
1483 | -T*) pacwrap "$@" ;;
1484 | -U*) pacwrap "$@" ;;
1485 | -*) invalid "$@" ;;
1486 | *) packageargs+=("$1") ;;
1487 | esac
1488 | shift
1489 | done
1490 |
1491 | # Handles alternative syntax --flag=parameter
1492 | for eqvar in "${equals[@]}"; do
1493 | if [[ $eqvar = "--config" ]]; then
1494 | apacmanconf=$(echo "$apacmanconf" | awk -F "=" '{print $2}')
1495 | elif [[ $eqvar = "--ignore" ]]; then
1496 | ignorearg=$(echo "$ignorearg" | awk -F "=" '{print $2}')
1497 | PACOPTS+=("--ignore" "$ignorearg")
1498 | elif [[ $eqvar = "--savedir" ]]; then
1499 | savedir=$(echo "$savedir" | awk -F "=" '{print $2}')
1500 | fi
1501 | done
1502 |
1503 | # Set tmpfile stuff, clean tmpdir
1504 | rm -rf "$tmpdir" &>/dev/null
1505 | mkdir -p "$tmpdir"
1506 | olddir="$PWD"
1507 | cd
1508 |
1509 | # Determine architecture
1510 | makearch=$(grep ^CARCH= "$makepkgconf" 2>/dev/null | grep -o -e =.*[0-9A-Za-z] | sed 's/^="//');
1511 |
1512 | # Check for new packages
1513 | if [[ $quickcheck == 1 ]]; then
1514 | run_quick_check
1515 | exit
1516 | fi
1517 |
1518 | # Verbose mode
1519 | [[ $verbose || $debug ]] && infoconf
1520 |
1521 | # List (-L) handling
1522 | if [[ $option = list ]]; then
1523 | getlistpackages
1524 | fi
1525 |
1526 | # Generate DB (--gendb) handling
1527 | if [[ $gendb = 1 ]]; then
1528 | aurgendb
1529 | fi
1530 |
1531 | # Sanity checks
1532 | [[ $config && -z $apacmanconf ]] && err "${COLOR7}error:${ENDCOLOR} no config file specified (use -h for help)"
1533 | [[ $option ]] || option="searchinstall"
1534 | [[ $escaperope != 1 && -z $packageargs ]] && err "${COLOR7}error:${ENDCOLOR} must specify a package."
1535 | [[ $auronly && $noaur ]] && err "Parameters --auronly and --noaur conflict."
1536 |
1537 | # Install (-S) handling
1538 | if [[ $option = install ]]; then
1539 | for pkg in ${packageargs[@]}; do
1540 | regexmatch="$(echo $pkg | tr -dc '0-9a-z-.\n')"
1541 | if [[ "$pkg" =~ ^/ ]]; then
1542 | err "${COLOR7}error:${ENDCOLOR} invalid package name $pkg"
1543 | elif [[ $regex = 1 ]]; then
1544 | true
1545 | elif [[ "$pkg" != "$regexmatch" ]]; then
1546 | regex='1'
1547 | echo -e "${COLOR6}notice:${ENDCOLOR} enabling regex mode ($pkg)"
1548 | fi
1549 | done
1550 | installhandling "${packageargs[@]}"
1551 | exit $?
1552 | fi
1553 |
1554 | # Update (-Su) handling
1555 | if [[ $option = update ]]; then
1556 | getignoredpackages
1557 | sourcemakepkgconf
1558 | # Pacman update
1559 | if ! [[ $auronly ]]; then
1560 | runasroot $PACMAN "${PACOPTS[@]}" "$pacmanarg"
1561 | fi
1562 |
1563 | # Aur update
1564 | total=0
1565 | if ! [[ $noaur ]]; then
1566 | echo -e "${COLOR5}:: ${COLOR1}Synchronizing aur database...${ENDCOLOR}"
1567 | IFS=$'\n' read -rd '' -a packages < <($pacmanbin -Qm)
1568 | newpackages=()
1569 | checkignores=()
1570 | extinctpkgs=()
1571 | total="${#packages[@]}"
1572 | grep -q '^ *ILoveCandy' "$pacmanconf" && bartype='candy' || bartype='normal'
1573 | fi
1574 |
1575 | if [[ $devel ]]; then
1576 | for ((i=0; i<$total; i++)); do
1577 | aurbar "$((i+1))" "$total" "$bartype"
1578 | pkg="${packages[i]%% *}"
1579 | if isignored "$pkg"; then
1580 | checkignores+=("${packages[i]}")
1581 | continue
1582 | elif ! existsinaur "$pkg" "pkg"; then
1583 | extinctpkgs+=("${packages[i]}")
1584 | continue
1585 | fi
1586 | pkginfo "$pkg" &
1587 | nap
1588 | done
1589 | wait
1590 | for ((i=0; i<$total; i++)); do
1591 | pkg="${packages[i]%% *}"
1592 | ver="${packages[i]##* }"
1593 | if [[ ! -s "$tmpdir/$pkg.PKGBUILD" ]]; then
1594 | continue
1595 | fi
1596 | if isignored "$pkg"; then
1597 | continue
1598 | fi
1599 | unset _darcstrunk _cvsroot _gitroot _svntrunk _bzrtrunk _hgroot
1600 | parser "$tmpdir/$pkg.PKGBUILD"
1601 | if [[ "$(LC_ALL=C vercmp "$pkgver-$pkgrel" "$ver")" -gt 0 ]]; then
1602 | newpackages+=("$pkg")
1603 | elif [[ ${_darcstrunk} || ${_cvsroot} || ${_gitroot} || ${_svntrunk} || ${_bzrtrunk} || ${_hgroot} ]]; then
1604 | newpackages+=("$pkg")
1605 | fi
1606 | done
1607 | else
1608 | for ((i=0; i<$total; i++)); do
1609 | aurbar "$((i+1))" "$total" "$bartype"
1610 | pkg="${packages[i]%% *}"
1611 | rpcinfo "$pkg" &
1612 | nap
1613 | done
1614 | wait
1615 | for ((i=0; i<$total; i++)); do
1616 | pkg="${packages[i]%% *}"
1617 | ver="${packages[i]##* }"
1618 | if isignored "$pkg"; then
1619 | checkignores+=("${packages[i]}")
1620 | elif ! existsinaur "$pkg" "pkg"; then
1621 | extinctpkgs+=("${packages[i]}")
1622 | elif aurversionisnewer "$pkg" "$ver"; then
1623 | newpackages+=("$pkg")
1624 | fi
1625 | done
1626 | fi
1627 | echo
1628 |
1629 | [[ $noaur ]] || echo -e "${COLOR5}:: ${COLOR1}Starting full aur upgrade...${ENDCOLOR}"
1630 |
1631 | # Check and output ignored package update info
1632 | for package in "${checkignores[@]}"; do
1633 | if aurversionisnewer "${package%% *}" "${package##* }"; then
1634 | echo -e "${COLOR6}warning:${ENDCOLOR} ${package%% *}: ignoring package upgrade (${package##* } => $aurversion)"
1635 | fi
1636 | done
1637 |
1638 | # Alert packages no longer in AUR
1639 | if [[ $extinctpkgs ]]; then
1640 | for package in "${extinctpkgs[@]}"; do
1641 | listextinct+=("${package%% *}")
1642 | done
1643 | echo ""
1644 | echo -e "${COLOR6}Unresolvable (${#listextinct[@]}):${ENDCOLOR} ${listextinct[@]}"
1645 | echo ""
1646 | fi
1647 |
1648 | # Now for the installation part
1649 | if [[ $newpackages ]]; then
1650 | auronly='1'
1651 | installhandling "${newpackages[@]}"
1652 | fi
1653 | [[ $noaur ]] || echo " local database is up to date"
1654 | exit $code
1655 | fi
1656 |
1657 | # Download (-G) handling
1658 | if [[ $option = download ]]; then
1659 | cd "$olddir"
1660 |
1661 | for package in "${packageargs[@]}"; do
1662 | if ! [[ $noaur ]] && existsinaur "$package" "package"; then
1663 | pkglist+=("$package")
1664 | elif ! [[ $auronly ]] && existsinpacman "$package"; then
1665 | abslist+=("$package")
1666 | elif [[ $noaur ]]; then
1667 | dne "Package \`$package' does not exist in ABS."
1668 | elif [[ $auronly ]]; then
1669 | dne "Package \`$package' does not exist in AUR."
1670 | else
1671 | dne "Package \`$package' does not exist in ABS+AUR."
1672 | fi
1673 | done
1674 |
1675 | [[ $abslist ]] && echo -e "${COLOR6}notice:$ENDCOLOR sourcing from ${COLOR4}[ABS]$ENDCOLOR"
1676 | for package in "${abslist[@]}"; do
1677 | pkgrepo=$(absrepo "$package")
1678 | abslink "$pkgrepo" "$package"
1679 | [ -d "$package" ] && rm -r "$package"
1680 | if [ -d "$pkgrepo/$package" ]; then
1681 | mv "$pkgrepo/$package" "$package"
1682 | rmdir "$pkgrepo"
1683 | ls "$package" | awk -v package="$package" '{print package"/"$0}'
1684 | else
1685 | err "${COLOR7}error:${ENDCOLOR} failed to retrieve package \`$package'"
1686 | fi
1687 | done
1688 |
1689 | [[ $pkglist ]] && echo -e "${COLOR6}notice:$ENDCOLOR sourcing from ${COLOR3}[AUR]$ENDCOLOR"
1690 | for package in "${pkglist[@]}"; do
1691 | if [[ $package = *~ ]]; then
1692 | pkgname="${package%\~}"
1693 | [ -d "$pkgname" ] && rm -rf "${pkgname}/.git"
1694 | [ -d "$pkgname" ] && rm -r "$pkgname"
1695 | clonehistory "$pkgname"
1696 | if [ ! -f "PKGBUILD" ]; then
1697 | err "${COLOR7}error:${ENDCOLOR} failed to retrieve package \`$pkgname' release $pkgver"
1698 | fi
1699 | elif [[ $package = *==* ]]; then
1700 | pkgname=$(echo "$package" | awk -F "==" '{print $1}')
1701 | pkgver=$(echo "$package" | awk -F "==" '{print $2}')
1702 | [ -d "$pkgname" ] && rm -rf "${pkgname}/.git"
1703 | [ -d "$pkgname" ] && rm -r "$pkgname"
1704 | clonehistory "$pkgname" "$pkgver"
1705 | if [ ! -f "PKGBUILD" ]; then
1706 | err "${COLOR7}error:${ENDCOLOR} failed to retrieve package \`$pkgname' release"
1707 | fi
1708 | else
1709 | curl -Lfs "$(pkglink $package)" > "$package.tar.gz"
1710 | cstatus=$?; curlyq "$cstatus" "$package"
1711 | [ -d "$package" ] && rm -rf "${package}/.git"
1712 | [ -d "$package" ] && rm -r "$package"
1713 | if [ -f "$package.tar.gz" ]; then
1714 | mkdir "$package"
1715 | tar -xzvf "$package.tar.gz" -C "$package" --strip-components=1
1716 | else
1717 | err "${COLOR7}error:${ENDCOLOR} failed to retrieve package \`$package'"
1718 | fi
1719 | fi
1720 | done
1721 |
1722 | exit
1723 | fi
1724 |
1725 | # Search (-Ss) handling
1726 | if [[ $option = search || $option = searchinstall ]]; then
1727 | # Pacman searching
1728 | if ! [[ $auronly ]]; then
1729 | if [[ $quiet ]]; then
1730 | results="$($pacmanbin -Ssq -- "${packageargs[@]}")"
1731 | else
1732 | results="$($pacmanbin -Ss -- "${packageargs[@]}")"
1733 | results="$(sed -r "s|^[^ ][^/]*/|$S${COLOR3}&$S${COLOR1}|" <<< "$results")"
1734 | results="$(sed -r "s|^([^ ]+) ([^ ]+)(.*)$|\1 $S${COLOR2}\2$S${ENDCOLOR}\3|" <<< "$results")"
1735 | results="$(sed -e "s| \[|$S${COLOR4}&|" -e "s|\]|&$S${ENDCOLOR}|" <<< "$results")"
1736 | fi
1737 | if [[ $option = search ]]; then
1738 | echo -e "$results" | fmt -"$_WIDTH" -s
1739 | else # interactive
1740 | echo -e "$results" | fmt -"$_WIDTH" -s | nl -v 0 -w 1 -s ' ' -b 'p^[^ ]'
1741 | fi | sed '/^$/d'
1742 | pacname=( $($pacmanbin -Ssq -- "${packageargs[@]}") )
1743 | pactotal="${#pacname[@]}"
1744 | else
1745 | pactotal=0
1746 | fi
1747 |
1748 | # Aur searching and tmpfile preparation
1749 | if ! [[ $noaur ]]; then
1750 | for package in "${packageargs[@]}"; do
1751 | curl -LfGs --data-urlencode "arg=$package" "$RPCURL=search" | \
1752 | jshon -Q -e results -a -e Name -u -p -e Version -u -p -e NumVotes -u -p -e Description -u | \
1753 | sed 's/^$/-/' | paste -s -d "\t\t\t\n" | sort -nr -k 3 > "$tmpdir/$package.search" &
1754 | done
1755 | wait
1756 | cp "$tmpdir/${packageargs[0]}.search" "$tmpdir/search.results"
1757 | for ((i=1 ; i<${#packageargs[@]} ; i++)); do
1758 | regexmatch="$(echo ${packageargs[$i]} | tr -dc '0-9A-Za-z-.\n')"
1759 | if [[ ${packageargs[$i]} != $regexmatch ]]; then
1760 | echo -e "${COLOR6}notice:${ENDCOLOR} enabling regex mode (${packageargs[$i]})"
1761 | grep --color=always -E "${packageargs[$i]}" "$tmpdir/search.results" > "$tmpdir/search.results-2"
1762 | else
1763 | grep -xFf "$tmpdir/search.results" "$tmpdir/${packageargs[$i]}.search" > "$tmpdir/search.results-2"
1764 | fi
1765 | mv "$tmpdir/search.results-2" "$tmpdir/search.results"
1766 | done
1767 | sed -i '/^$/d' "$tmpdir/search.results"
1768 |
1769 | # Check versioning
1770 | localpkgs=$(pacman -Q)
1771 | for pkg in $(awk '{print $1}' "$tmpdir/search.results"); do
1772 | localver=$(echo "$localpkgs" | grep -E "^${pkg}[[:space:]]" 2>/dev/null | awk '{print $2}');
1773 | if [ ! -z "$localver" ]; then
1774 | searchver=$(grep -E "^${pkg}[[:space:]]" "$tmpdir/search.results" | awk '{print $2}')
1775 | if [ "$searchver" = "$localver" ]; then
1776 | sed -i "s|$pkg[[:space:]]$searchver|& [installed]|" "$tmpdir/search.results"
1777 | elif [[ "$(LC_ALL=C vercmp "$searchver" "$localver")" -gt 0 ]]; then
1778 | sed -i "s|$pkg[[:space:]]$searchver|& [installed: $localver]|" "$tmpdir/search.results"
1779 | else
1780 | sed -i "s|$pkg[[:space:]]$searchver|& [local: $localver]|" "$tmpdir/search.results"
1781 | fi
1782 | fi
1783 | done
1784 |
1785 | # Prepare tmp file and arrays
1786 | IFS=$'\n' read -rd '' -a aurname < <(cut -f 1 "$tmpdir/search.results")
1787 | aurtotal="${#aurname[@]}"
1788 | alltotal="$(($pactotal+$aurtotal))"
1789 | else
1790 | alltotal="$pactotal"
1791 | fi
1792 |
1793 | # Exit if there are no matches
1794 | if [[ $alltotal = 0 ]]; then
1795 | echo -e "${COLOR5}==>${COLOR7} no matches${ENDCOLOR}"
1796 | exit 4
1797 | fi
1798 |
1799 | # Echo out the -Ss formatted package information
1800 | IFS=$'\t\n'
1801 | if [[ $option = search ]]; then
1802 | if [[ $quiet ]]; then
1803 | printf "%s\n" ${aurname[@]}
1804 | elif [[ -s "$tmpdir/search.results" ]]; then
1805 | resultsaur="$(printf "${COLOR3}aur/${COLOR1}%s ${COLOR2}%s${ENDCOLOR} (%s)\n %s\n" $(cat "$tmpdir/search.results"))"
1806 | resultsaur="$(sed -e "s| \[|$S${COLOR4}&|" -e "s|\]|&$S${ENDCOLOR}|" <<< "$resultsaur")"
1807 | echo -e "$resultsaur"
1808 | fi
1809 | else
1810 | # interactive
1811 | if [[ $quiet ]]; then
1812 | nl -v ${pactotal:-0} -w 1 -s ' ' <(cut -f 1 "$tmpdir/search.results")
1813 | elif [[ -s "$tmpdir/search.results" ]]; then
1814 | resultsaur="$(printf "%d ${COLOR3}aur/${COLOR1}%s ${COLOR2}%s${ENDCOLOR} (%s)\n %s\n" $(nl -v ${pactotal:-0} -w 1 < "$tmpdir/search.results"))"
1815 | resultsaur="$(sed -e "s| \[|$S${COLOR4}&|" -e "s|\] |&$S${ENDCOLOR}|" <<< "$resultsaur")"
1816 | echo -e "$resultsaur"
1817 | fi
1818 | fi | fmt -"$_WIDTH" -s
1819 | unset IFS
1820 |
1821 | # Prompt and install selected numbers
1822 | if [[ $option = searchinstall ]]; then
1823 | pkglist=()
1824 | allpackages=( "${pacname[@]}" "${aurname[@]}" )
1825 |
1826 | # Prompt for numbers
1827 | echo
1828 | echo -e "${COLOR2}Type numbers to install. Separate each number with a space.${ENDCOLOR}"
1829 | echo -ne "${COLOR2}Numbers: ${ENDCOLOR}"
1830 | read -r
1831 |
1832 | # Parse answer
1833 | if [[ $REPLY ]]; then
1834 | for num in $REPLY; do
1835 | if [[ $num -lt $alltotal ]]; then
1836 | pkglist+=("${allpackages[$num]}")
1837 | else
1838 | err "Number \`$num' is not assigned to any of the packages."
1839 | fi
1840 | done
1841 | fi
1842 |
1843 | # Call installhandling to take care of the packages chosen
1844 | installhandling "${pkglist[@]}"
1845 | fi
1846 |
1847 | # Remove the tmpfiles
1848 | rm -f "$tmpdir/*search" &>/dev/null
1849 | rm -f "$tmpdir/search.results" &>/dev/null
1850 | rm -f "$tmpdir/packages.lst" &>/dev/null
1851 | exit
1852 | fi
1853 |
1854 | # Info (-Si) handling
1855 | if [[ $option = info ]]; then
1856 | # Pacman info check
1857 | sourcemakepkgconf
1858 | for package in "${packageargs[@]}"; do
1859 | if ! [[ $auronly ]] && existsinpacman "$package"; then
1860 | results="$($pacmanbin -Si -- "$package")"
1861 | results="$(sed -r "s|^(Repository[^:]*:)(.*)$|\1$S${COLOR3}\2$S${ENDCOLOR}|" <<< "$results")"
1862 | results="$(sed -r "s|^(Name[^:]*:)(.*)$|\1$S${COLOR1}\2$S${ENDCOLOR}|" <<< "$results")"
1863 | results="$(sed -r "s|^(Version[^:]*:)(.*)$|\1$S${COLOR2}\2$S${ENDCOLOR}|" <<< "$results")"
1864 | results="$(sed -r "s|^(URL[^:]*:)(.*)$|\1$S${COLOR4}\2$S${ENDCOLOR}|" <<< "$results")"
1865 | results="$(sed -r "s|^[^ ][^:]*:|$S${COLOR1}&$S${ENDCOLOR}|" <<< "$results")"
1866 | echo -e "$results"
1867 | exit
1868 | elif ! [[ $noaur ]]; then # Check to see if it is in the aur
1869 | pkginfo "$package" "$preview"
1870 | [[ -s "$tmpdir/$package.PKGBUILD" ]] || err "${COLOR7}error:${ENDCOLOR} package '$package' was not found"
1871 | parser "$tmpdir/$package.PKGBUILD"
1872 |
1873 | # Clean temp files
1874 | [[ $debug ]] || rm "$tmpdir/$package.PKGBUILD" "$tmpdir/$package.info"
1875 |
1876 | # Echo out the -Si formatted package information
1877 | # Retrieve each element in order and echo them immediately
1878 | echo -e "${COLOR1}Repository : ${COLOR3}aur"
1879 | echo -e "${COLOR1}Name : $pkgname"
1880 | echo -e "${COLOR1}Version : ${COLOR2}$pkgver-$pkgrel"
1881 | echo -e "${COLOR1}URL : ${COLOR4}$url"
1882 | echo -e "${COLOR1}AUR : ${COLOR4}$PKGURL/packages/$pkgname/"
1883 | echo -e "${COLOR1}Licenses : ${ENDCOLOR}${license[@]}"
1884 | echo -e "${COLOR1}Groups : ${ENDCOLOR}${groups[@]:-None}"
1885 | echo -e "${COLOR1}Provides : ${ENDCOLOR}${provides[@]:-None}"
1886 | echo -e "${COLOR1}Depends On : ${ENDCOLOR}${depends[@]}"
1887 | echo -e "${COLOR1}Make Depends : ${ENDCOLOR}${makedepends[@]}"
1888 | echo -e -n "${COLOR1}Optional Deps : ${ENDCOLOR}"
1889 |
1890 | len="${#optdepends[@]}"
1891 | if [[ $len -eq 0 ]]; then
1892 | echo "None"
1893 | else
1894 | for ((i=0 ; i<$len ; i++)); do
1895 | if [[ $i = 0 ]]; then
1896 | echo "${optdepends[$i]}"
1897 | else
1898 | echo -e " ${optdepends[$i]}"
1899 | fi
1900 | done
1901 | fi
1902 |
1903 | echo -e "${COLOR1}Conflicts With : ${ENDCOLOR}${conflicts[@]:-None}"
1904 | echo -e "${COLOR1}Replaces : ${ENDCOLOR}${replaces[@]:-None}"
1905 | echo -e "${COLOR1}Architecture : ${ENDCOLOR}${arch[@]}"
1906 | echo -e "${COLOR1}Description : ${ENDCOLOR}$pkgdesc"
1907 | echo
1908 | else
1909 | err "${COLOR7}error:${ENDCOLOR} package '$package' was not found"
1910 | fi
1911 | done
1912 | fi
1913 |
1914 | # Web Comments (-W) handling
1915 | if [[ $option = web ]]; then
1916 | sourcemakepkgconf
1917 | for package in "${packageargs[@]}"; do
1918 | if ! [[ $auronly ]] && existsinpacman "$package"; then
1919 | echo -e "${COLOR7}error:${ENDCOLOR} comments unavailable for non-AUR package '$package'"
1920 | elif ! [[ $noaur ]]; then # Check to see if it is in the aur
1921 | curl -Lfs "$PKGURL/packages/$package/?comments=all" > "$tmpdir/$package.html"
1922 | cstatus=$?; curlyq "$cstatus" "$package"
1923 | [[ -s "$tmpdir/$package.html" ]] || err "${COLOR7}error:${ENDCOLOR} package '$package' was not found"
1924 |
1925 | div="%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
1926 | separator="${COLOR3}${div}${div}${ENDCOLOR}"
1927 | header="${COLOR4}*******************************${ENDCOLOR}"
1928 | comments="$(sed '/