Merge ~jarnos/ppa-purge:master into ppa-purge:master

Proposed by Jarno Suni on 2016-12-12
Status: Needs review
Proposed branch: ~jarnos/ppa-purge:master
Merge into: ppa-purge:master
Diff against target: 1001 lines (+627/-214) (has conflicts)
9 files modified
debian/changelog (+25/-2)
debian/compat (+1/-1)
debian/control (+12/-12)
debian/copyright (+8/-10)
debian/ppa-purge.8 (+84/-0)
debian/ppa-purge.bash-completion (+86/-67)
debian/ppa-purge.manpages (+1/-1)
dev/null (+0/-33)
ppa-purge (+410/-88)
Conflict in ppa-purge
Reviewer Review Type Date Requested Status
ppa-purge 2016-12-12 Pending
Review via email: mp+313001@code.launchpad.net

Description of the change

Uses apt-get, not aptitude at all.

Aims to fix:
Under https://bugs.launchpad.net/ppa-purge
Bug #1614160
Bug #802853
Bug #1121325 (since it does not use aptitude)

Under https://bugs.launchpad.net/ubuntu/+source/ppa-purge
Bug #1408031
Bug #1548881
Bug #995113

+some fixes told in git log.

Please donate to me on contributing to this project: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YYXVNC3L8QSQA

To post a comment you must log in.
~jarnos/ppa-purge:master updated on 2016-12-15
f302251... by Jarno Suni on 2016-12-14

Move check for not removing this package.

Now allow downgrading, though.

41b8698... by Jarno Suni on 2016-12-14

Read package lists to /dev/shm to avoid writing to permanent storage.

Rename PPA_PKGS -> PKGS. Empty the files after use. Do not sort
while reading PKGS.

dcbd763... by Jarno Suni on 2016-12-14

Do not display revert list (=$REINSTALL).

Reverts will be shown as part of executing the apt-get install
command.

7d5a2cf... by Jarno Suni on 2016-12-15

Simplify by using bash regex and variable expansion.

Get rid of some variables at the same time.

Tim Lunn (darkxst) wrote :

Turns out this is pretty hard to review, launchpad doesnt help but you also have several commits that revert or fix changes you made in subsequent commits.

Have made a couple of inline comments below.

Will also go through and cherry-pick some of the more trivial commits, but you will need to rebase your branch once done.

Tim Lunn (darkxst) wrote :

s/subsequent/previous/ commits

Jarno Suni (jarnos) wrote :

Unfortunately development was not completely straight-forward.

Tim Lunn (darkxst) wrote :

there are still commits you could squash to clean things up a bit

&&
complete

you remove then add back

there 2 commits that deal with escaping ppa string?

etc

Jarno Suni (jarnos) wrote :

Is there an easy way to cancel the removing of && so that there is no mention of it in git log disturbing your mind?

Is it a problem that there are 2 commits that deal with escaping ppa string? If you want less commits I could just commit the final code as one commit. But you did not accept that either.

~jarnos/ppa-purge:master updated on 2016-12-18
65fb9fb... by Jarno Suni on 2016-12-18

Simplify messaging. No folding used.

5bece79... by Jarno Suni on 2016-12-18

Ask user whether to continue or not after changing repositories.

60a3ad1... by Jarno Suni on 2016-12-18

Make apt-get show version info on revert.

9e7bb54... by Jarno Suni on 2016-12-18

Add long opitions; new --version, --remove, --verbose, remove -dq

Use getopt to parse options. Add long options. Options may also be
after arguments.

Remove -d option, but user may set environment variable RELEASE to
override automaticly determined release name.

Remove -q, but new -v alias --verbose is used to control the same
thing.

New options:
--remove, -r: Remove repository entries or list files. LP: #945473
--verbose, -v: Control output of "apt-get update". LP: #1293507
--version, -V: Print standard GNU version information.

Manual page was generated by command
"help2man -N ./ppa-purge >debian/ppa-purge.1".

Tim Lunn (darkxst) wrote :
Download full text (9.9 KiB)

It is very easy

you need to use `git rebase -i HEAD~40` the last number is the amount of
commits to go back.

then you can group the commits you want to merge (cut and paste the line
and put it where it needs to go)

set the second commits action (first column) to s (squash)

It will then merge those commits, if there are any conflicts in the auto
merge it might leave little snippets in the code that you need to
manually correct. These will look something like

 >>>>>>>>>> HEAD

old code

========

new code

<<<<<<<<<< later commit

Fix those, then "git add <file>"

git rebase --continue

update the commit message for the merged commit and its done!

If you want to just remove commits (for example the commit that adds
check ubuntu dists, then the other that subsequently removes it)

use the same "git rebase -i" command and then just delete the lines for
any commits to remove.

you can also you the e (edit) action if you ever need to make any change
to a particular commit!

On 19/12/16 00:31, Jarno Suni wrote:
> Is there an easy way to cancel the removing of && so that there is no mention of it in git log disturbing your mind?
>
> Is it a problem that there are 2 commits that deal with escaping ppa string? If you want less commits I could just commit the final code as one commit. But you did not accept that either.
>
>
> Diff comments:
>
>> diff --git a/ppa-purge b/ppa-purge
>> index a0b5e42..f197c2c 100755
>> --- a/ppa-purge
>> +++ b/ppa-purge
>> @@ -23,116 +38,196 @@ warn() {
>> write_msg "Warning: $*" 1>&2
>> }
>>
>> +error() {
>> + write_msg "Error: $*" 1>&2
>> +}
>> +
>> +apt_update() {
>> + msg "Updating package lists. This might take a while..."
>> + $APT $quiet_arg update
>> + exit_status=$?
>> + [[ $exit_status -eq 0 ]] &&
>> + msg "Updating package lists finished successfully." || {
>> + local -r text="Updating package lists failed; error code $exit_status."
>> + if [[ $yes ]]; then
>> + error "$text"
>> + [[ $quit ]] || exit 5
>> + else
>> + warn "$text"
>> + [[ $quit ]] || {
>> + read -p "Continue anyway (y/n)? " -n 1 -r
> Yes, I could remove it, I suppose.
>
>> + echo
>> + [[ $REPLY =~ ^[Yy]$ ]] || exit 5
>> + }
>> + fi
>> + }
>> +}
>> +
>> +finish() {
>> + quit=t
>> + rm $PPA_PKGS $REVERTS
>> + if [[ $restore && ((${#lists[@]} > 0)) ]]; then
>> + msg 'Restoring .list file(s):'
>> + for file in "${lists[@]}"; do
>> + cp -va "$file".save "$file"
>> + done
>> + apt_update
>> + fi
>> +}
>> +
>> +trap finish 0
>> +
>> usage() {
>> - echo "Usage: sudo ppa-purge [options] <ppa:ppaowner>[/ppaname]"
>> - echo
>> - echo "ppa-purge will reset all packages from a PPA to the standard"
>> - echo "versions released for your distribution."
>> - echo
>> - echo "Options:"
>> - echo " -p [ppaname] PPA name to be disabled (default: ppa)"
>> - echo " -o [ppaowner] PPA owner"
>> - echo " -s [host] Repository server (default: ppa.launchpad.net)"
>> - echo " -d [distribution] Override the default distribution choice."
>> - echo " -y Pass "-y --force-yes" to apt-get or "-y" to aptitude"
>> - echo " -i Reverse preference of apt-get upon aptitude."
>> - echo " -h Display this help text"
>> -...

~jarnos/ppa-purge:master updated on 2016-12-23
2db960c... by Jarno Suni on 2016-12-20

Be more strict when checking, if apt-get fails to update all repositories.

Regard even warnings in "apt-get update" as fatal errors.
Fixes LP: #1514839

4744e12... by Jarno Suni on 2016-12-21

Add option --figure-soname-bumps to optionally enable old default.

Disable the explicit figuring by default; let apt-get handle
installing soname bumped packages automatically. If the option
is used, do the figuring, and display the list of packages that are
going to be explicitly installed due to (figured) soname bump.

b51c9e1... by Jarno Suni on 2016-12-22

Instead of matching all components, match only distribution name.

If source distribution name is given, purge repository only, if
the distribution name matches.

The previous approach of matching all components is tricky: The
first component in deb line is actually source distribution name
and it should be treated differently. If there is a deb line
containing many components, specifying one in command line would
purge all of them (in the respective repository), so removing
only that component in the respective deb line should be done
instead of disabling the whold line. Removing components can be
done relatively easy by other tools, so it was dropped here to
keep it simple.

3e937ff... by Jarno Suni on 2016-12-23

Fine-tune bash completions

Do not always complete options, except when the word begins with -.
As for other words, complete only what could be used to avoid long
lists.

Do not use "command" with sed. If you were paranoid, you would use
it with compgen and complete, too, but it is not usually done.

Jarno Suni (jarnos) wrote :

I did the changes you suggested, but I was in another branch, and to my surprise, the changes do not show in master. BTW I also changed the first commit to include (all?) remarkable authors, but that again does not show in master.

Jarno Suni (jarnos) wrote :

I thought the changes would go to each branch since all of them were same up to those commits before changing.

Tim Lunn (darkxst) wrote :

you need to push a new branch after rebasing!

Jarno Suni (jarnos) wrote :

On Sat, 24 Dec 2016 04:38:45 -0000
Tim <email address hidden> wrote:

> you need to push a new branch after rebasing!

You mean the feature branch I created for enabling long options and
removing distributions? Where could I push that one or do you mean I
merge it to my local master and then push?

--
Jarno Ilari Suni - http://www.iki.fi/8/

Tim Lunn (darkxst) wrote :

any branch in general, when you rebase it destroys the history and needs to be re-pushed. you can force overwrite an existing branch but if
anyone is using that, they will have issues!

On 25/12/16 07:12, Jarno Suni wrote:
> On Sat, 24 Dec 2016 04:38:45 -0000
> Tim <email address hidden> wrote:
>
>> you need to push a new branch after rebasing!
> You mean the feature branch I created for enabling long options and
> removing distributions? Where could I push that one or do you mean I
> merge it to my local master and then push?
>

~jarnos/ppa-purge:master updated on 2017-01-04
5f63cfe... by Jarno Suni on 2016-12-31

Improve regular expression matching, do not use [:space:]

Use [:blank:] instead.

abb9aa4... by Jarno Suni on 2016-12-31

Do not autocomplete PPAs as http://*

a14bb53... by Jarno Suni on 2016-12-31

Use temporary directory. Optimize creating REVERTS list for Precise.

Use temporaty directory for easy removing and creating of files.

fef559f... by Jarno Suni on 2017-01-03

Improve completing verbose option.

Besides do not be fooled to think that distribution argument is
given, if only an argument for verbose option is given as a separate
word.

89b15ea... by Jarno Suni on 2017-01-04

Update some debian files.

Jarno Suni (jarnos) wrote :

I have not succeeded in pushing the feature branch where the changes are made anywhere. I am afraid it is hard to merge to the master branch, but I could try.

Jarno Suni (jarnos) wrote :

Could I delete the current master, and make the feature branch new master somehow?

Tim Lunn (darkxst) wrote :

has it been rebased on master?

if so then that is fine.

On 21/02/17 22:55, Jarno Suni wrote:
> Could I delete the current master, and make the feature branch new master somehow?

Jarno Suni (jarnos) wrote :

I used this procedure to make the feature branch the new master: http://stackoverflow.com/a/2763118/4414935
Commits of the old master are shown in log, but they are not used if I understood correctly.

Jarno Suni (jarnos) wrote :

I wonder, if there are any issues, if I remove the commits of the old master?

Jarno Suni (jarnos) wrote :

This version may downgrade ppa-purge itself, but not purge it.

Jarno Suni (jarnos) wrote :

Hello,

How are you? Do you still miss a proper internet connection or what is
keeping you from reviewing the changes?

-Jarno

On Wed, 22 Feb 2017 07:15:44 -0000
Tim <email address hidden> wrote:

> has it been rebased on master?
>
> if so then that is fine.
>
>
>
> On 21/02/17 22:55, Jarno Suni wrote:
> > Could I delete the current master, and make the feature branch new
> > master somehow?
>
>

--
Jarno Ilari Suni - http://www.iki.fi/8/

Tim Lunn (darkxst) wrote :

Yes still without proper internet should have ADSL in a few weeks
so,will take a look then. Sorry about the delay

On Wed, Apr 26, 2017, at 07:06 AM, Jarno Suni wrote:
> Hello,
>
> How are you? Do you still miss a proper internet connection or what is
> keeping you from reviewing the changes?
>
> -Jarno
>
>
> On Wed, 22 Feb 2017 07:15:44 -0000
> Tim <email address hidden> wrote:
>
> > has it been rebased on master?
> >
> > if so then that is fine.
> >
> >
> >
> > On 21/02/17 22:55, Jarno Suni wrote:
> > > Could I delete the current master, and make the feature branch new
> > > master somehow?
> >
> >
>
>
>
> --
> Jarno Ilari Suni - http://www.iki.fi/8/
>
> https://code.launchpad.net/~jarnos/ppa-purge/+git/ppa-purge/+merge/313001
> Your team ppa-purge is requested to review the proposed merge of
> ~jarnos/ppa-purge:master into ppa-purge:master.

--
  Tim Lunn
  <email address hidden>

Jarno Suni (jarnos) wrote :

There seem to be some conflicts. Is it because you have added few commits in master after I made this merge proposal? My changes have parent commit 9dbd19d24294cd87bed43939a1a7366f5f2fcf4a in the target branch. I recently tried to simplify commit history by deleting some branches and force removing last merge commit push. My repository seems to be ok now.

~jarnos/ppa-purge:master updated on 2017-05-01
4b42b42... by Jarno Suni on 2017-05-01

Ubuntu 12.04 is no more supported

Jarno Suni (jarnos) wrote :

I force pushed some small changes.

Jarno Suni (jarnos) wrote :

It may be unnecessary to check for warnings in apt_update(). See https://bugs.launchpad.net/ubuntu/+source/apt/+bug/1693900

~jarnos/ppa-purge:master updated on 2017-08-05
cc0e6e1... by Jarno Suni on 2017-08-05

Give user an option to continue in case update from some irrelevant
source will fail.

Jarno Suni (jarnos) wrote :

My bash completion implementation is maybe too complicated as it shows '--verbose=0', '--verbose=1' and '--verbose=2' directly as completion of '--'. I could simplify that.

Jarno Suni (jarnos) wrote :

Tim, do you have ADSL now after more than 3 months? I do not see why ADSL connection is so critical to you and why it is so hard for you the get internet connection for this reviewing task. (I had ADSL in the past, but the over-head wire was taken away, and I have used 4G ever since.)

~jarnos/ppa-purge:master updated on 2019-11-24
332281e... by Jarno Suni on 2019-11-06

Improve bash completion; list --verbose= without arguments first

Use -s option with _init_completion() to ease handling --option=argument
syntax.

Rename private functions to have __ prefix.

Fix __ppa_purge_update_args to work better in some cases where cursor is in
the middle of command line.

Cut long lines to smaller ones.

Do not complete (redundant) short options.

Define options using arrays and associated arrays. Also wordlist is defined as
an array.

Use new function __make_opts_wordlist() to form wordlist of options. Arguments
for options are not listed at this stage. Only add space after completing
options that do not take arguments to be able to append the argument.
(IFS=$'\n' is needed to be able to have space after a word in completion.)

_ltrim_completions() not needed when the other modifications are done,
but given __ltrim_colon_completions() is used.

1c57b90... by Jarno Suni on 2019-11-07

Catch also errors in output of $APT update

..in case exit code might not be non-zero with some reported errors.

c541876... by Jarno Suni on 2019-11-07

Remove old middle verbose level

Besides, use process substitution instead of pipe in apt_update().

9cd87b2... by Jarno Suni on 2019-11-09

Support Hypertext Transfer Protocol Secure (HTTPS) for repositories.

fb75d53... by Jarno Suni on 2019-11-18

Name the files so that they are in the created directory

Finally the files are deleted in finish trap.

3728645... by Jarno Suni on 2019-11-18

Avoid subshell in reading a file. Use proper IFS.

78d7a9f... by Jarno Suni on 2019-11-18

realpath is preferred over readlink here

According to command
man 1 readlink

6668353... by Jarno Suni on 2019-11-18

Allow disabling/removing even if there are no matching packages.

Make reverting a separate function to make the script easier to read.

526e40b... by Jarno Suni on 2019-11-18

Complete finish even if apt_update fails on restore.

07396e3... by Jarno Suni on 2019-11-18

Do actions only, if a .list file was changed.

2af4440... by Jarno Suni on 2019-11-18

Remove option --no-initial-update (or -u) and make the behavior default.

Add option --initial-update (or -i), instead, to enable the old default.

fdd8c50... by Jarno Suni on 2019-11-18

Rename the bash completion file to ppa-purge.bash

That name can be used when installing the completion to a
recommended location.

ae83a36... by Jarno Suni on 2019-11-18

Use Bash parameter expansion instead of separate command.

13f35ec... by Jarno Suni on 2019-11-21

This is system administration command, so move the man page in section 8.

5c69632... by Jarno Suni on 2019-11-21

Update copyright file

d519615... by Jarno Suni on 2019-11-21

Update control file and compat file

539e9f4... by Jarno Suni on 2019-11-21

Update changelog

3743f7b... by Jarno Suni on 2019-11-21

dh_bash-completion helper script expects ppa-purge.bash-completion

25c532a... by Jarno Suni on 2019-11-22

Update version; properly move the manual page to section 8

To properly change the section of the manual page, and to provide
a meaningful description of the command in the NAME section, use
help2man with the following options:
-s 8 -N -n 'disable repository and remove/downgrade associated packages'

f4bc62b... by Jarno Suni on 2019-11-24

Only one distribution is allowed

Jarno Suni (jarnos) wrote :

I made PPA of my branch: https://launchpad.net/~jarnos/+archive/ubuntu/ppa-purge
I set version 0.5.0.0 for it as it has a lot of changes to 0.2.8+bzr63.

Unmerged commits

f4bc62b... by Jarno Suni on 2019-11-24

Only one distribution is allowed

539e9f4... by Jarno Suni on 2019-11-21

Update changelog

d519615... by Jarno Suni on 2019-11-21

Update control file and compat file

5c69632... by Jarno Suni on 2019-11-21

Update copyright file

25c532a... by Jarno Suni on 2019-11-22

Update version; properly move the manual page to section 8

To properly change the section of the manual page, and to provide
a meaningful description of the command in the NAME section, use
help2man with the following options:
-s 8 -N -n 'disable repository and remove/downgrade associated packages'

3743f7b... by Jarno Suni on 2019-11-21

dh_bash-completion helper script expects ppa-purge.bash-completion

13f35ec... by Jarno Suni on 2019-11-21

This is system administration command, so move the man page in section 8.

ae83a36... by Jarno Suni on 2019-11-18

Use Bash parameter expansion instead of separate command.

fdd8c50... by Jarno Suni on 2019-11-18

Rename the bash completion file to ppa-purge.bash

That name can be used when installing the completion to a
recommended location.

2af4440... by Jarno Suni on 2019-11-18

Remove option --no-initial-update (or -u) and make the behavior default.

Add option --initial-update (or -i), instead, to enable the old default.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 20dc4e4..bc3e9e8 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,9 +1,32 @@
6-ppa-purge (0.2.8.1) UNRELEASED; urgency=medium
7+ppa-purge (0.5.0.0) bionic; urgency=high
8
9+ [ Tim Lunn ]
10 * Merge soname code missing from last release
11 * Switch to git and fix Vcs- tags
12
13- -- Tim Lunn <tim@feathertop.org> Tue, 15 Mar 2016 11:18:05 +1100
14+ [ Jarno Suni ]
15+ * Fixes bug LP: #802853: ppa-purge should have "dryrun" option
16+ * Fixes bug LP: #821655: Removing xorg-edgers install KDE?
17+ * Fixes bug LP: #945473: [wishlist] add an option to remove PPA
18+ * Fixes bug LP: #995113: revert changes to sources.list.d when ppa-purge
19+ fails
20+ * Fixes bug LP: #1121325: Packages might get downgraded to stable release
21+ version ignoring active updates/security archives
22+ * Fixes bug LP: #1293507: Add a verbose option to the ppa-purge command (-v)
23+ * Fixes bug LP: #1408031: Requesting purge to abort fails.
24+ * Fixes bug LP: #1514839: ppa-purge misbehaves if repository update fails
25+ * Fixes bug LP: #1548881: ppa-purge fails to remove packages when ppa
26+ repository includes a plus in the name
27+ * Fixes bug LP: #1614160: Could not find package list
28+ * Fixes bug LP: #1617814: ppa-purge failed due to aptitude not being
29+ installed
30+ * Fixes bug LP: #1668660: ppa-purge package should require aptitude
31+ (Because of the fix it actually does not need aptitude)
32+ * Command line syntax is changed somewhat
33+ * Bash completion has been improved
34+ * Several other changes, refer to git log
35+
36+ -- Jarno Suni <sunijarno@gmail.com> Thu, 21 Nov 2019 18:24:17 +0200
37
38 ppa-purge (0.2.8+bzr63) xenial; urgency=low
39
40diff --git a/debian/compat b/debian/compat
41index 7f8f011..ec63514 100644
42--- a/debian/compat
43+++ b/debian/compat
44@@ -1 +1 @@
45-7
46+9
47diff --git a/debian/control b/debian/control
48index 9efef2a..a114bfc 100644
49--- a/debian/control
50+++ b/debian/control
51@@ -1,18 +1,18 @@
52 Source: ppa-purge
53 Section: utils
54 Priority: optional
55-Maintainer: Lorenzo De Liso <blackz@ubuntu.com>
56-Build-Depends: debhelper (>= 7.0.50~), bash-completion
57-Standards-Version: 3.9.3
58-Homepage: https://launchpad.net/ppa-purge
59-Vcs-Git: git://git.launchpad.net/ppa-purge
60-Vcs-Browser: https://git.launchpad.net/ppa-purge
61+Maintainer: Jarno Suni <sunijarno@gmail.com>
62+Build-Depends: debhelper (>= 9), bash-completion
63+Standards-Version: 3.9.8
64+Homepage: https://launchpad.net/~jarnos/+archive/ubuntu/ppa-purge
65+Vcs-Git: git+ssh://jarnos@git.launchpad.net/~jarnos/ppa-purge
66+Vcs-Browser: https://git.launchpad.net/~jarnos/ppa-purge
67
68 Package: ppa-purge
69 Architecture: all
70-Depends: ${misc:Depends}, dpkg (>= 1.16.1)
71-Suggests: aptitude (>= 0.6.6-1ubuntu1.2)
72-Description: disables a PPA and reverts to official packages
73- This program disables a PPA from your Software Sources and reverts your
74- system back to the official Ubuntu packages. You can use this to return your
75- system to normal after testing a new version from a PPA.
76+Depends: ${misc:Depends}, dpkg (>= 1.18.4)
77+Description: Disables a PPA or another APT repository and reverts pkgs.
78+ Use ppa-purge to remove a software source from your system and
79+ downgrade or remove the packages it provided. You can use this to e.g.
80+ return your system to normal after testing a new version from a PPA or
81+ to downgrade packages from e.g. proposed ones.
82diff --git a/debian/copyright b/debian/copyright
83index fc4a6a5..69bb3bb 100644
84--- a/debian/copyright
85+++ b/debian/copyright
86@@ -1,18 +1,16 @@
87-Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135
88-Name: ppa-purge
89-Maintainer: Robert Hooker <sarvatt@ubuntu.com>
90-Source: https://launchpad.net/ppa-purge
91+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
92+Source: https://code.launchpad.net/~jarnos/ppa-purge/+git/ppa-purge
93
94 Files: *
95-Copyright:
96- 2009, Robert Hooker <sarvatt@ubuntu.com>
97- 2009, Tormod Volden <debian.tormod@gmail.com>
98+Copyright: 2009, Robert Hooker <sarvatt@ubuntu.com>
99+ 2009, Tormod Volden <debian.tormod@gmail.com>
100+ 2019, Jarno Ilari Suni <8@iki.fi>
101 License: GPL-3
102
103 Files: debian/*
104-Copyright:
105- 2009, Robert Hooker <sarvatt@ubuntu.com>
106- 2010, Lorenzo De Liso <blackz@ubuntu.com>
107+Copyright: 2009, Robert Hooker <sarvatt@ubuntu.com>
108+ 2010, Lorenzo De Liso <blackz@ubuntu.com>
109+ 2019, Jarno Ilari Suni <8@iki.fi>
110 License: GPL-3
111
112 License: GPL-3
113diff --git a/debian/ppa-purge.1 b/debian/ppa-purge.1
114deleted file mode 100644
115index cc86fbf..0000000
116--- a/debian/ppa-purge.1
117+++ /dev/null
118@@ -1,33 +0,0 @@
119-.TH ppa-purge 1 2010-08-23 "ppa-purge"
120-.SH NAME
121-ppa-purge \- disables a PPA and reverts to official packages
122-
123-.SH SYNOPSIS
124-.B ppa-purge [-h | [-d <distribution>] [-s <host>] [-p <ppaname>] <ppa:<ppaowner[/ppaname>]>]
125-
126-.SH DESCRIPTION
127-This script provides a bash shell script capable of automatically downgrading all packages in a given PPA back to the ubuntu versions.
128-
129-.PP
130-You have to run it using root privileges because of the package manager.
131-
132-.SH OPTIONS
133-
134-.TP
135-.B -h
136-Display usage help.
137-.TP
138-
139-.TP
140-.B -p\fR \fIPPA name\fR
141-Name of the PPA to be reset, the default value is ppa.
142-.TP
143-
144-.B -s\fR \fIPPA host\fR
145-Address of the repository server, the default value is ppa.launchpad.net.
146-
147-.SH COPYRIGHT
148-This manual page is Copyright 2010 Lorenzo De Liso <blackz@ubuntu.com>.
149-Permission is granted to copy, distribute and/or modify this document
150-under the terms of the GNU General Public License, Version 3 or any later
151-version published by the Free Software Foundation.
152diff --git a/debian/ppa-purge.8 b/debian/ppa-purge.8
153new file mode 100644
154index 0000000..2dcbaf4
155--- /dev/null
156+++ b/debian/ppa-purge.8
157@@ -0,0 +1,84 @@
158+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
159+.TH PPA-PURGE "8" "November 2019" "ppa-purge APT Software Purger 0.5.0.0" "System Administration Utilities"
160+.SH NAME
161+ppa-purge \- disable repository and remove/downgrade associated packages
162+.SH SYNOPSIS
163+.B ppa-purge
164+[\fI\,options\/\fR] \fI\,ppa:<ppaowner>\/\fR[\fI\,/<ppaname>\/\fR]
165+.br
166+.B ppa-purge
167+[\fI\,options\/\fR] \fI\,<URL> \/\fR[\fI\,<distribution>\/\fR]
168+.br
169+.B ppa-purge
170+[\fI\,options\/\fR] \fI\,<distribution>\/\fR
171+.br
172+.B ppa-purge
173+\fI\,{ --help | --version }\/\fR
174+.SH DESCRIPTION
175+ppa\-purge will disable matching repository/repositories and revert packages to
176+versions available for target release. If a package is not available from any
177+remaining repositories, it will be removed, unless it is a package related to
178+current kernel or it is the package of this command. If <ppaname> is not given,
179+\&'ppa' is used as default. If a distribution (such as xenial\-proposed) is given,
180+repository must match it to be purged. Bash completion is supported.
181+.SS "Exit Status:"
182+.IP
183+0 on success; non\-zero integer on error
184+.SH OPTIONS
185+.TP
186+\fB\-\-figure\-soname\-bumps\fR
187+Explicitly install packages that are figured as soname
188+bumped version of a package to be removed. Display
189+list of these packages.
190+.TP
191+\fB\-s\fR, \fB\-\-simulate\fR
192+No action; do not downgrade or remove packages.
193+.TP
194+\fB\-i\fR, \fB\-\-initial\-update\fR
195+Do initial update of package lists. Use this, if you
196+are not sure the package lists are updated already.
197+.TP
198+\fB\-r\fR, \fB\-\-remove\fR
199+Remove unneeded .list files or repository entries
200+instead of leaving backups or commenting entries out,
201+respectively.
202+.TP
203+\fB\-v\fR <level>, \fB\-v\fR<level>, \fB\-\-verbose\fR <level>, \fB\-\-verbose=\fR<level>
204+Verbosity level of "apt\-get update" output.
205+0: only errors and warninings
206+1: normal output (default).
207+.TP
208+\fB\-y\fR, \fB\-\-yes\fR
209+Run non\-interactively; do not prompt for changes.
210+.TP
211+\fB\-h\fR, \fB\-\-help\fR
212+Display this help text and exit.
213+.TP
214+\fB\-V\fR, \fB\-\-version\fR
215+Show version and exit.
216+.SH ENVIRONMENT
217+.TP
218+RELEASE
219+Target release to be downgraded to. If not set, output of
220+"lsb_release \fB\-cs\fR" is used.
221+.SH EXAMPLES
222+.IP
223+sudo ppa\-purge ppa:ubuntu\-x\-swat/x\-updates
224+.IP
225+Purge the same PPA on Linux Mint 18.1 (based on Ubuntu 16.04):
226+.IP
227+sudo RELEASE=16.04 ppa\-purge ppa:ubuntu\-x\-swat/x\-updates
228+.IP
229+Purge Google Chrome repository:
230+.IP
231+sudo ppa\-purge http://dl.google.com/linux/chrome/deb
232+.IP
233+Downgrade packages from xenial\-proposed in Ubuntu 16.04:
234+.IP
235+sudo ppa\-purge xenial\-proposed
236+.SH COPYRIGHT
237+Copyright \(co authors.
238+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
239+.br
240+This is free software: you are free to change and redistribute it.
241+There is NO WARRANTY, to the extent permitted by law.
242diff --git a/debian/ppa-purge.bash-completion b/debian/ppa-purge.bash-completion
243index be8edde..c337fa4 100644
244--- a/debian/ppa-purge.bash-completion
245+++ b/debian/ppa-purge.bash-completion
246@@ -1,80 +1,99 @@
247 # /usr/share/bash-completion/completions/ppa-purge
248 # Debian ppa-purge(1) completion -*- shell-script -*-
249
250-_update_server(){
251- local i
252- for (( i=1; i < ${#words[@]}-1; i++)) ; do
253- case "${words[i]}" in
254- -s)
255- SERVER=${words[i+1]}
256- ;;
257- *)
258- ;;
259- esac
260- done
261-}
262+while true; do
263
264-_update_owner(){
265- local i
266- for (( i=1; i < ${#words[@]}-1; i++)) ; do
267- case "${words[i]}" in
268- -o)
269- OWNER=${words[i+1]}
270- ;;
271- *)
272- ;;
273- esac
274- done
275-}
276+# Check which arguments have been given already. This is used for
277+# deciding which completions will be offered.
278+__ppa_purge_update_args() {
279+ local i word last=${#words[@]} prevword=
280+ for (( i=1; i < $last; i++ )) ; do
281+ word=${words[i]}
282+ (( $i != $cword )) || [[ -z $cur ]] &&
283+ case "$word" in
284+ http?(s)://*) url=$word ;;
285+ ppa:*) ppa=$word ;;
286+ -*) ;;
287+ ?*) [[ $prevword =~ ^-([^-]*v|-verbose)$ ]] || dist=$word
288+ esac
289+ prevword=$word
290+ done
291+} || break
292
293-_ppa_names(){
294- _update_server
295- _update_owner
296- grep -hs "^deb\ .*$SERVER" /etc/apt/sources.list.d/*.list | grep "$OWNER" | command sed "s#.*$SERVER\/.*\/\(.*\)\/.*#\1#"
297-}
298+__repo_dist() {
299+ [[ $url ]] &&
300+ sed -rn \
301+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+'"$url"'/?[[:blank:]]+([^[:blank:]]+).*#\3#p' \
302+/etc/apt/sources.list.d/*.list /etc/apt/sources.list | sort -u ||
303+ sed -rn \
304+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://[^[:blank:]]+[[:blank:]]+([^[:blank:]]+).*#\3#p' \
305+/etc/apt/sources.list.d/*.list /etc/apt/sources.list | sort -u
306+} || break
307
308-_ppa_host(){
309- grep -hs "^deb\ .*tp\:\/\/.*\/.*\/.*" /etc/apt/sources.list.d/*.list | command sed "s#^deb.*\:\/\/\(.*\)\/.*\/.*/.*#\1#" | uniq
310-}
311+__repo_list() {
312+ [[ $dist ]] &&
313+ sed -rn \
314+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+(https?://[^[:blank:]]+)[[:blank:]]+'"$dist"'[[:blank:]]+.*#\3#p' \
315+/etc/apt/sources.list.d/*.list /etc/apt/sources.list \
316+| sed -e '/http:\/\/ppa\.launchpad\.net/d' -e 's#/$##' \
317+||
318+ sed -rn \
319+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+(https?://[^[:blank:]]+).*#\3#p' \
320+/etc/apt/sources.list.d/*.list /etc/apt/sources.list \
321+| sed -e '/http:\/\/ppa\.launchpad\.net/d' -e 's#/$##'
322+} || break
323
324-_ppa_owner(){
325- _update_server
326- grep -hs "^deb\ .*$SERVER" /etc/apt/sources.list.d/*.list | command sed "s#.*$SERVER\/\(.*\)\/.*\/.*#\1#"
327+__ppa_list() {
328+ sed -rn \
329+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://ppa\.launchpad\.net/([^/[:blank:]]+/[^/[:blank:]]+).*#\3#p' \
330+/etc/apt/sources.list.d/*.list /etc/apt/sources.list |
331+ sed -e 's#^[^/]*$#&/#' -e 's#.*#ppa:&#'
332+} || break
333+
334+__make_opts_wordlist() {
335+ local i
336+ for i in ${opts[*]}; do wordlist+=("--$i "); done
337+ for i in ${!args[*]}; do wordlist+=("--$i="); done
338+ compopt -o nospace
339 }
340
341-_ppa_list(){
342- _update_server
343- _update_owner
344- grep -hs "^deb\ .*$SERVER" /etc/apt/sources.list.d/*.list | grep "$OWNER" | command sed "s#.*$SERVER\/\(.*\/.*\)\/.*#\1#"
345+_ppa_purge() {
346+ local IFS=$'\n' # needed for handling trailing space of some options and all arguments
347+ local cur prev words cword split # set by _init_completion()
348
349-}
350-_ppa_purge(){
351- OWNER=""
352- SERVER="ppa.launchpad.net"
353- local cur prev words cword opts
354- _init_completion || return
355+ # Do not treat : and = as word breaks even if they are in $COMP_WORDBREAKS:
356+ # Split option=value into option in $prev and value in $cur
357+ _init_completion -n : -s || return
358+
359+ local opts=(help simulate initial-update yes version remove figure-soname-bumps)
360+ local -A args=([verbose]=$'0\n1')
361
362- opts="-p -s -o -d -y -i -h"
363+ local i
364+ for i in ${!args[*]}; do
365+ if [[ $prev = --$i ]]; then
366+ [[ "$COMP_WORDBREAKS" != *=* && $split == true ]] && prefix="--$i="
367+ COMPREPLY=( $( compgen -P "$prefix" -W "${args[$i]}" -- "$cur" ) )
368+ return 0
369+ fi
370+ done
371
372- case "${prev}" in
373- -p)
374- COMPREPLY=( $( compgen -W "$(_ppa_names)" -- $cur ) )
375- return 0
376- ;;
377- -s)
378- COMPREPLY=( $( compgen -W "$(_ppa_host)" -- $cur ) )
379- return 0
380- ;;
381- -o)
382- COMPREPLY=( $( compgen -W "$(_ppa_owner)" -- $cur ) )
383- return 0
384- ;;
385- *)
386- ;;
387- esac
388-
389- COMPREPLY=( $( compgen -W '${opts} $(_ppa_list)' -- "$cur" ) )
390+ local url= ppa= dist= prefix= wordlist=()
391+ [[ $cur = -* ]] && __make_opts_wordlist || {
392+ __ppa_purge_update_args
393+ if [[ $ppa ]]; then
394+ __make_opts_wordlist
395+ elif [[ $url ]]; then
396+ [[ $dist ]] && __make_opts_wordlist || wordlist=( $(__repo_dist) )
397+ elif [[ $dist ]]; then
398+ wordlist=( $(__repo_list) )
399+ else
400+ wordlist=( $(__ppa_list; __repo_list; __repo_dist) )
401+ fi
402+ }
403
404- return 0
405-} &&
406-complete -F _ppa_purge ppa-purge
407+ COMPREPLY=( $( compgen -W "${wordlist[*]}" -- "$cur" ) )
408+ __ltrim_colon_completions "$cur"
409+ return 0
410+} && complete -F _ppa_purge ppa-purge
411+break
412+done
413diff --git a/debian/ppa-purge.manpages b/debian/ppa-purge.manpages
414index 189ec3e..c31d87b 100644
415--- a/debian/ppa-purge.manpages
416+++ b/debian/ppa-purge.manpages
417@@ -1 +1 @@
418-debian/ppa-purge.1
419+debian/ppa-purge.8
420diff --git a/ppa-purge b/ppa-purge
421index 19ad281..9bf6f26 100755
422--- a/ppa-purge
423+++ b/ppa-purge
424@@ -1,29 +1,61 @@
425-#!/bin/bash
426-# A script to remove all packages in a PPA and revert back to the normal
427-# distribution ones.
428+#!/bin/bash -u
429+# A script to disable a repository and to remove all packages installed in your
430+# system from it and to revert back to the version (if any) available from a
431+# leftover repository.
432 #
433+<<<<<<< ppa-purge
434 # AUTHORS: Robert Hooker (Sarvatt), Tormod Volden, Darkxst, Jarno Suni (jarnos)
435+=======
436+# AUTHORS: Robert Hooker (Sarvatt), Lorenzo De Liso, Tormod Volden,
437+# Lorenzo De Liso, Tim Lunn (Darkxst), Jarno Ilari Suni (jarnos)
438+
439+export LC_ALL=C # Use C locale to get standard sorting and better regex
440+# performance.
441+export TMPDIR=/dev/shm # dir for mktemp to create files in
442+
443+# Constants
444+declare -r APT=apt-get \
445+yes_option='--force-yes' \
446+F_ARCHS=$(dpkg --print-foreign-architectures) \
447+mytmpdir=$(mktemp -d)
448+declare -r PKGS=${mytmpdir}/pkgs \
449+REVERTS=${mytmpdir}/reverts \
450+EXITCODE=${mytmpdir}/exitcode \
451+program_name=ppa-purge \
452+program_full_name='ppa-purge APT Software Purger' \
453+program_pkg_name=ppa-purge \
454+program_version=0.5.0.0 \
455+copyright='authors' \
456+copyright_year=
457+
458+# Initialize some variables
459+restore=t
460+declare -a lists=()
461+url=
462+no_update=
463+unset -v IFS
464+>>>>>>> ppa-purge
465
466 # Defaults
467-F_ARCHS=$(dpkg --print-foreign-architectures)
468-PPA_PKGS=$(mktemp)
469-REVERTS=$(mktemp)
470-trap "rm $PPA_PKGS $REVERTS" 0
471+# Default for RELEASE will be set below, if needed.
472+yes=
473+simulate=
474+initial_update=
475+remove=
476+verbose=1
477+figure_soname=
478
479 # Functions to write output nicely.
480-write_msg() {
481- echo "$*" | fold -s -w "${COLUMNS:-80}"
482-}
483-
484 msg() {
485- write_msg "$*"
486+ echo "[$program_name] $*"
487 }
488
489 warn() {
490- write_msg "Warning: $*" 1>&2
491+ msg "Warning: $*" 1>&2
492 }
493
494 error() {
495+<<<<<<< ppa-purge
496 write_msg "Error: $*" 1>&2
497 }
498
499@@ -59,10 +91,136 @@ usage() {
500 echo "(For example: you left synaptic open while attempting to run it) simply"
501 echo "uncomment the PPA from your sources, run apt-get update and try again."
502 echo
503+=======
504+ msg "Error: $1" 1>&2
505+ exit ${2:-1}
506+}
507+
508+apt_update() {
509+ msg "Updating package lists..."
510+ case $verbose in
511+ 0) exec 3>/dev/null ;;
512+ 1) exec 3>&1
513+ esac
514+ local exit_code=
515+ {
516+ # read and echo warning & error messages
517+ w=
518+ while IFS= read -r; do
519+ printf '%s\n' "$REPLY" >&2
520+ [[ $REPLY =~ ^[EW]: ]] && exit_code=0 # warning or error detected
521+ done
522+ } < <($APT update 2>&1 >&3 || printf $? >$EXITCODE)
523+ exec 3>&-
524+
525+ [[ -s $EXITCODE ]] && IFS= read -r exit_code <"$EXITCODE"
526+
527+ [[ $exit_code ]] && {
528+ no_update=t
529+ [[ $yes || $exit_code -ne 0 ]] || {
530+ read -r -p "$(msg 'Continue even if error or warning was detected (Y/n)? ')"
531+ [[ ! ( -z $REPLY || $REPLY =~ ^[Yy]$ ) ]]
532+ } && error "Updating package lists failed; error code ${exit_code}." 5
533+ }
534+ return 0
535+}
536+
537+finish() {
538+ set +o pipefail
539+ ((${#lists[@]} > 0)) && {
540+
541+ [[ $restore ]] && {
542+ msg 'Restoring .list file(s):'
543+ for file in "${lists[@]}"; do
544+ mv -fv "$file".save "$file"
545+ done
546+ [[ $no_update ]] || apt_update || :
547+ } || {
548+ [[ $remove ]] && {
549+ msg 'Removing .list file(s):'
550+ for file in "${lists[@]}"; do
551+ grep -Evq '^[[:blank:]]*(#.*)?$' "$file" || {
552+ # everything is commented out
553+ rm -rv "$file" "$file".save* || :
554+ }
555+ done
556+ }
557+ }
558+ }
559+ rm -rf "$mytmpdir"
560+}
561+
562+trap finish 0
563+
564+usage() {
565+fold -s -w "${COLUMNS:-80}" << EOF
566+Usage: $program_name [options] ppa:<ppaowner>[/<ppaname>]
567+or: $program_name [options] <URL> [<distribution>]
568+or: $program_name [options] <distribution>
569+or: $program_name { --help | --version }
570+
571+$program_name will disable matching repository/repositories and revert \
572+packages to versions available for target release. If a \
573+package is not available from any remaining repositories, it will be removed, \
574+unless it is a package related to current kernel or it is the package of this \
575+command. If <ppaname> is not given, 'ppa' is used as default. If a \
576+distribution (such as xenial-proposed) is given, repository must match it to \
577+be purged. Bash completion is supported.
578+
579+Exit Status:
580+ 0 on success; non-zero integer on error
581+
582+Options:
583+ --figure-soname-bumps Explicitly install packages that are figured as soname
584+ bumped version of a package to be removed. Display
585+ list of these packages.
586+ -s, --simulate No action; do not downgrade or remove packages.
587+ -i, --initial-update Do initial update of package lists. Use this, if you
588+ are not sure the package lists are updated already.
589+ -r, --remove Remove unneeded .list files or repository entries
590+ instead of leaving backups or commenting entries out,
591+ respectively.
592+ -v <level>, -v<level>, --verbose <level>, --verbose=<level>
593+ Verbosity level of "$APT update" output.
594+ 0: only errors and warninings
595+ 1: normal output (default).
596+ -y, --yes Run non-interactively; do not prompt for changes.
597+ -h, --help Display this help text and exit.
598+ -V, --version Show version and exit.
599+
600+Environment:
601+ RELEASE Target release to be downgraded to. If not set, output of
602+ "lsb_release -cs" is used.
603+
604+Examples:
605+ sudo $program_name ppa:ubuntu-x-swat/x-updates
606+
607+ Purge the same PPA on Linux Mint 18.1 (based on Ubuntu 16.04):
608+
609+ sudo RELEASE=16.04 $program_name ppa:ubuntu-x-swat/x-updates
610+
611+ Purge Google Chrome repository:
612+
613+ sudo $program_name http://dl.google.com/linux/chrome/deb
614+
615+ Downgrade packages from xenial-proposed in Ubuntu 16.04:
616+
617+ sudo $program_name xenial-proposed
618+
619+EOF
620+>>>>>>> ppa-purge
621 exit $1
622 }
623
624+show_version() {
625+printf "$program_full_name $program_version
626+Copyright (C) $copyright_year $copyright.
627+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
628+This is free software: you are free to change and redistribute it.
629+There is NO WARRANTY, to the extent permitted by law.\n"
630+}
631
632+<<<<<<< ppa-purge
633 # Command line options
634 while getopts ":p:o:s:d:yih" opt; do
635 case "$opt" in
636@@ -93,30 +251,34 @@ if [[ $1 ]]; then
637 usage 1
638 fi
639 fi
640+=======
641+suggest_usage() {
642+ echo "Run '$program_name -h' to get help."
643+}
644+
645+# escape special characters (http://unix.stackexchange.com/a/209744/111181)
646+escape_regex() {
647+ printf '%s' "$1" | sed 's/[.[\*^$()+?{|]/\\&/g'
648+}
649+>>>>>>> ppa-purge
650
651-APTARG=""
652-if [ ! -z "$APTALT" ]; then
653- if [ ! -z "$FORCEINSTALL" ]; then
654- APTARG="-y"
655- fi
656- APT=aptitude; APTALT=apt-get
657-else
658- if [ ! -z "$FORCEINSTALL" ]; then
659- APTARG="-y --force-yes"
660- fi
661- APT=apt-get; APTALT=aptitude
662-fi
663
664+<<<<<<< ppa-purge
665 if [ -z "$PPAOWNER" ]; then
666 error "Required ppa-name argument was not specified"
667 usage 1
668 fi
669+=======
670+revert() {
671+ msg "Generating revert list..."
672
673-# If not set, using defaults
674-[ -z "$PPAHOST" ] && PPAHOST="ppa.launchpad.net"
675-[ -z "$PPANAME" ] && PPANAME="ppa"
676-[ -z "$DIST" ] && DIST=$(lsb_release -c -s)
677+ # Create apt argument list for reverting packages
678+>>>>>>> ppa-purge
679
680+ # store available packages in a sorted variable for faster access.
681+ avail_pkgs=$(apt-cache dumpavail | grep '^Package:' | cut -d' ' -f2 | sort -urV)
682+
683+<<<<<<< ppa-purge
684 if [ "$(id -u)" != "0" ]; then
685 error "This script would need superuser privileges, use sudo"
686 usage 1
687@@ -127,90 +289,248 @@ if ! $APT update > /dev/null; then
688 error "$APT update failed for some reason"
689 exit 1
690 fi
691+=======
692+ # Create an associated array for fast checking of available packages.
693+ # Creating takes some time though, say 1s, but will save a lot if there are many
694+ # reverts.
695+ declare -A avail=()
696+ for PKG in $avail_pkgs; do avail[$PKG]=; done
697+
698+ # tag for current kernel version
699+ curkerversion=$(escape_regex $(uname -r | cut -d- -f1,2))
700+ # tag for current kernel flavor
701+ curkerflavor=$(escape_regex $(uname -r | cut -d- -f3-))
702+ REINSTALL=
703+ declare -a sonamepkg=()
704+ while IFS= read -r PACKAGE; do
705+ PKG=${PACKAGE%:*}
706+
707+ # Test if PKG is still available
708+ # if ! grep -xFq "$PKG" <<<"$avail_pkgs"; then
709+ if [[ -z ${avail[$PKG]+x} ]]; then
710+
711+ # Explicitly remove the package that does not exist in archive unless
712+ # it is versioned kernel package matching the current kernel or the
713+ # package of this program.
714+ [[ $PKG =~ ^linux-.+-${curkerversion}(-${curkerflavor})?$ ||
715+ $PKG == $program_pkg_name ]] &&
716+ msg "Note: Not removing $PKG package." ||
717+ {
718+ REINSTALL+=" $PACKAGE-"
719+
720+ [[ $figure_soname && $PKG != linux-* ]] && {
721+ # Maybe could even restrict to lib* ?
722+ # check if the package is availabe with another version tag
723+ pkg_regex=$(escape_regex "$PKG")
724+ soname_regex=$(sed -r \
725+ -e 's/[[:digit:]][[:lower:]]$/[[:digit:]][[:lower:]]/' \
726+ -e 's/[[:digit:]]+/[[:digit:]]+/g' <<<"$pkg_regex")
727+ [[ $soname_regex != $pkg_regex ]] && {
728+
729+ # get the greatest available version of the package
730+ APTAVAIL=$(grep -m 1 -E "^${soname_regex}$" \
731+ <<<"$avail_pkgs" || :)
732+
733+ # downgrade packages that have a soname bump
734+ [[ $APTAVAIL ]] && {
735+ newpkg=${APTAVAIL}${PACKAGE#$PKG}
736+ sonamepkg+=("$newpkg")
737+ REINSTALL+=" $newpkg/$RELEASE"
738+ }
739+ }
740+ }
741+ }
742+ else
743+ REINSTALL+=" $PACKAGE/$RELEASE"
744+ fi
745+ done <$REVERTS
746+ unset -v avail avail_pkgs
747+ >$REVERTS
748+
749+ [[ ${#sonamepkg[*]} -gt 0 ]] && {
750+ msg "Going to install these packages due to soname bump figuring:
751+ $(printf '%s\n' "${sonamepkg[@]}")"
752+ msg "These of them are installed already (but maybe different version):
753+ $(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' "${sonamepkg[@]}" \
754+ 2>/dev/null | awk '/^.i /{print $2}')"
755+>>>>>>> ppa-purge
756+
757+ [[ $yes ]] || {
758+ read -p "$(msg 'Continue (Y/n)? ')" -r
759+ [[ -z $REPLY || $REPLY =~ ^[Yy]$ ]] || exit
760+ }
761+ }
762
763-msg "PPA to be removed: $PPAOWNER $PPANAME"
764+ msg "Reverting..."
765+ $APT $simulate $yes -V install $REINSTALL || {
766+ exit_status=$?
767+ [[ $exit_status -eq 1 ]] &&
768+ # User aborted apt-get; no packages were downgraded or removed.
769+ exit 5 ||
770+ error "Something went wrong with $APT; error code $exit_status. \
771+ Packages may not have been reverted." 5
772+ }
773+ msg "Reverting packages finished successfully."
774+}
775+
776+# Command line options
777+env -u GETOPT_COMPATIBLE getopt --test >/dev/null || [[ $? -ne 4 ]] && {
778+ # This should not happen with util-linux's getopt.
779+ error '`getopt --test` failed in this environment.' 3
780+}
781+
782+# Option name followed by ':' denotes an option that has an argument.
783+# Options are separated by ','.
784+params=$(env -u GETOPT_COMPATIBLE getopt -o siyhrv:V \
785+-l simulate,initial-update,yes,help,version,remove,verbose:,\
786+figure-soname-bumps --name "[$program_name] Error" -- "$@") || {
787+ # If $? = 1, command line is invalid; getopt displays an error message
788+ [[ $? -eq 1 ]] && exit 1
789+ >&2 error 'getopt failed.' 3
790+}
791+# $params contains at least --
792+
793+eval set -- "$params"
794+unset -v params
795+while :; do
796+ case $1 in
797+ -s|--simulate ) simulate='-s' ;;
798+ -i|--initial-update ) initial_update=t ;;
799+ -y|--yes ) yes="$yes_option" ;;
800+ -V|--version ) show_version; exit ;;
801+ -h|--help ) usage 0 ;;
802+ -r|--remove ) remove=t ;;
803+ -v|--verbose )
804+ case $2 in
805+ 0|1) verbose="$2" ;;
806+ *) error "Invalid verbose level." 1 ;;
807+ esac
808+ shift 2; continue ;;
809+ --figure-soname-bumps ) figure_soname=t ;;
810+ -- ) # End of all options.
811+ shift; break
812+ esac
813+ shift
814+done
815
816-# Make list of all packages in PPA
817-PPA_LIST=/var/lib/apt/lists/${PPAHOST}_${PPAOWNER}_${PPANAME}_*_Packages
818-for LIST in $PPA_LIST; do
819- if [ -e $LIST ]; then
820- grep "^Package: " $LIST | cut -d " " -f2 | sort >> $PPA_PKGS
821+distro=
822+while [[ ${1-} ]]; do
823+ if [[ $1 =~ ^ppa:([^/[:blank:]]+)(/[^/[:blank:]]+)?$ ]]; then
824+ url=ppa.launchpad.net/${BASH_REMATCH[1]}${BASH_REMATCH[2]:-/ppa}/ubuntu
825+ elif [[ $1 =~ ^https?://([^[:blank:]]*[^/[:blank:]])/?$ ]]; then
826+ url=${BASH_REMATCH[1]}
827+ else
828+ distro=$1
829 fi
830+ shift
831 done
832
833+<<<<<<< ppa-purge
834 if [ ! -s $PPA_PKGS ]; then
835 error "Could not find package list for PPA: $PPAOWNER $PPANAME"
836 exit 1
837 fi
838+=======
839+[[ -z $url && -z $distro ]] && {
840+ error "No argument given. $(suggest_usage)"
841+}
842+>>>>>>> ppa-purge
843
844-# Ignore the ppa-purge package
845-if grep -q "ppa-purge" $PPA_PKGS; then
846- sed -i '/ppa-purge/d' $PPA_PKGS
847- msg "Note: Not removing ppa-purge package"
848+if [[ ${RELEASE+x} ]]; then
849+ [[ $RELEASE =~ ^[^/[:blank:]]+$ ]] || {
850+ error "Invalid target release name :" \'"$RELEASE"\'
851+ }
852+else
853+ RELEASE=$(lsb_release -c -s)
854 fi
855
856-# Get multi-arch package names for revert list
857-cat $PPA_PKGS | sort -u |
858- xargs dpkg-query -W -f='${binary:Package}\t${db:Status-Abbrev}\n' 2>/dev/null |
859- awk '/\tii $/{print $1}' > $REVERTS
860-# Fallback for Precise
861-if [ ! -s $REVERTS ]; then
862- for PACKAGE in $(cat $PPA_PKGS | sort -u); do
863- dpkg-query -W -f='${PackageSpec}\t${Status}\n' $PACKAGE 2>/dev/null |
864- awk '/\tinstall/{print $1}' >> $REVERTS
865- for F_ARCH in $F_ARCHS; do
866- dpkg-query -W -f='${PackageSpec}\t${Status}\n' "$PACKAGE:$F_ARCH" 2>/dev/null |
867- awk '/\tinstall/{print $1}' >> $REVERTS
868- done
869- done
870+if [ "$(id -u)" != "0" ]; then
871+ error "This script would need superuser privileges, use sudo" 2
872 fi
873
874-# Disable PPA from sources.list files
875-for LIST in $(find /etc/apt/ -name "*.list" -exec readlink -f '{}' \;); do
876- if [ -e $LIST ] && grep -q $PPAOWNER/$PPANAME $LIST; then
877- msg "Disabling $PPAOWNER PPA from $LIST"
878- sed -ri "\:^[^#]+/${PPAOWNER}/${PPANAME}/:s/^deb/# deb/" $LIST
879+[[ $initial_update ]] && apt_update
880+no_update=t
881+
882+msg "To be removed: ${url} ${distro}"
883+
884+# Make list of all packages available from the matching archive(s)
885+[[ $url ]] && _url=${url//\//_} || _url='*'
886+for LIST in /var/lib/apt/lists/${_url}_dists_*_Packages; do
887+ if [ -f $LIST ]; then
888+ nomatch=
889+ if [[ $distro ]]; then
890+ dist=${LIST##*_dists_}
891+ dist=${dist%%_*}
892+ [[ $dist == $distro ]] || nomatch=t
893+ fi
894+ [[ $nomatch ]] ||
895+ grep "^Package: " $LIST | cut -d " " -f2 >> $PKGS
896 fi
897 done
898
899-msg "Updating packages lists"
900-$APT update > /dev/null || warn "$APT update failed for some reason"
901-
902-# Create apt argument list for reverting packages, most of the foo here is to attempt
903-# to unroll soname bumps
904+no_pkgs=
905+if [ ! -s $PKGS ]; then
906+ warn "Could not find matching packages."
907+ no_pkgs=t
908+else
909+ # Get multi-arch package names for revert list
910+ sort -u $PKGS | xargs dpkg-query -W \
911+ -f='${binary:Package}\t${db:Status-Abbrev}\n' 2>/dev/null |
912+ awk '/\tii $/{print $1}' > $REVERTS
913+ >$PKGS
914+fi
915
916-REINSTALL=""
917-for PACKAGE in $(cat $REVERTS); do
918- PKG=$(echo $PACKAGE | cut -d ':' -f1)
919- [[ $PACKAGE == *:* ]] && D_ARCH=":"$(echo $PACKAGE | cut -d ':' -f2)
920+# Disable matching lines from sources.list files
921+[[ $url ]] &&
922+ regex='^deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://'"$(escape_regex "$url")"'/?[[:blank:]]+([^[:blank:]]+)' ||
923+ regex='^deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://[^[:blank:]]+ +([^[:blank:]]+)'
924+newlist=
925+for LIST in $(find /etc/apt/ -name "*.list" -exec realpath -e '{}' \;); do
926+ changed=
927+ while read -r; do
928+ nomatch=
929+ [[ "$REPLY" =~ $regex ]] && {
930+ if [[ $distro ]]; then
931+ [[ ${BASH_REMATCH[3]} == $distro ]] || nomatch=t;
932+ fi
933+ } || nomatch=t
934
935- if [ $(grep-aptavail -XPc -s Package $PKG) -eq 0 ]; then
936- PAT=$(echo $PKG | sed -e s/[0-9][a-z]\$/'..'/ -e s/[0-9]/'.'/g)
937+ [[ $nomatch ]] && newlist+="$REPLY"$'\n' || {
938+ [[ $remove ]] && msg "Remove entry: $REPLY" || {
939+ newlist+="# $REPLY"$'\n'
940+ msg "Disable entry: $REPLY"
941+ }
942+ changed=t
943+ }
944+ done <$LIST
945
946- APTAVAIL=$(grep-aptavail -eP --pattern='^'$PAT'$' -s Package -n | sort -uV | sed -e '$!d')
947+ [[ $changed ]] && {
948+ msg "Making backup of .list file:"
949+ mv -fvb "$LIST" "$LIST".save
950+ lists+=("$LIST")
951+ printf %s "$newlist" > "$LIST"
952+ }
953+ newlist=
954+done
955
956- #explicitly remove packages that don't exist in archive
957- if [ "x$APTAVAIL" != "x$PKG" ]; then
958- REINSTALL="$REINSTALL $PACKAGE-"
959- fi
960+(( ${#lists[@]} > 0 )) && {
961+ [[ $yes ]] || {
962+ read -p "$(msg 'Continue with these changes (Y/n)? ')" -r
963+ [[ -z $REPLY || $REPLY =~ ^[Yy]$ ]] || exit
964+ }
965
966- #downgrade packages that have a soname bump
967- if [ -n "$APTAVAIL" ]; then
968- REINSTALL="$REINSTALL $APTAVAIL$D_ARCH/$DIST"
969- fi
970- else
971- REINSTALL="$REINSTALL $PACKAGE/$DIST"
972- fi
973-done
974+ no_update=
975+ apt_update
976
977-msg "Package revert list generated:"
978-msg "$REINSTALL"
979-echo
980+ [[ $no_pkgs ]] || revert
981
982-# FIXME:
983-# Workaround for now in case APT fails. APTALT is a little more foregiving if the
984-# revert list isn't 100% correct.
985+ [[ $simulate ]] &&
986+ msg "Restoring repository entries, because this was just simulation:" \
987+ || restore=
988+ # successful operation; no need to restore, unless in simulation mode.
989+}
990
991+<<<<<<< ppa-purge
992 if $APT $APTARG install $REINSTALL; then
993 msg "PPA purged successfully"
994 elif $APTALT $APTARG install $REINSTALL; then
995@@ -219,4 +539,6 @@ else
996 error "Something went wrong, packages may not have been reverted"
997 exit 1
998 fi
999+=======
1000+>>>>>>> ppa-purge
1001 exit 0

Subscribers

People subscribed via source and target branches

to all changes: