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

Proposed by Jarno Suni
Status: Needs review
Proposed branch: ~jarnos/ppa-purge:master
Merge into: ppa-purge:master
Diff against target: 1027 lines (+652/-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 (+98/-0)
debian/ppa-purge.bash-completion (+86/-67)
debian/ppa-purge.manpages (+1/-1)
dev/null (+0/-33)
ppa-purge (+421/-88)
Conflict in ppa-purge
Reviewer Review Type Date Requested Status
ppa-purge 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
f302251... by Jarno Suni

Move check for not removing this package.

Now allow downgrading, though.

41b8698... by Jarno Suni

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

Do not display revert list (=$REINSTALL).

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

7d5a2cf... by Jarno Suni

Simplify by using bash regex and variable expansion.

Get rid of some variables at the same time.

Revision history for this message
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.

Revision history for this message
Tim Lunn (darkxst) wrote :

s/subsequent/previous/ commits

Revision history for this message
Jarno Suni (jarnos) wrote :

Unfortunately development was not completely straight-forward.

Revision history for this message
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

Revision history for this message
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
65fb9fb... by Jarno Suni

Simplify messaging. No folding used.

5bece79... by Jarno Suni

Ask user whether to continue or not after changing repositories.

60a3ad1... by Jarno Suni

Make apt-get show version info on revert.

9e7bb54... by Jarno Suni

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".

Revision history for this message
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
2db960c... by Jarno Suni

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

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

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

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.

Revision history for this message
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.

Revision history for this message
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.

Revision history for this message
Tim Lunn (darkxst) wrote :

you need to push a new branch after rebasing!

Revision history for this message
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/

Revision history for this message
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
5f63cfe... by Jarno Suni

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

Use [:blank:] instead.

abb9aa4... by Jarno Suni

Do not autocomplete PPAs as http://*

a14bb53... by Jarno Suni

Use temporary directory. Optimize creating REVERTS list for Precise.

Use temporaty directory for easy removing and creating of files.

fef559f... by Jarno Suni

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

Update some debian files.

Revision history for this message
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.

Revision history for this message
Jarno Suni (jarnos) wrote :

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

Revision history for this message
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?

Revision history for this message
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.

Revision history for this message
Jarno Suni (jarnos) wrote :

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

Revision history for this message
Jarno Suni (jarnos) wrote :

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

Revision history for this message
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/

Revision history for this message
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>

Revision history for this message
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
4b42b42... by Jarno Suni

Ubuntu 12.04 is no more supported

Revision history for this message
Jarno Suni (jarnos) wrote :

I force pushed some small changes.

Revision history for this message
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
cc0e6e1... by Jarno Suni

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

Revision history for this message
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.

Revision history for this message
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
332281e... by Jarno Suni

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

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

Remove old middle verbose level

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

9cd87b2... by Jarno Suni

Support Hypertext Transfer Protocol Secure (HTTPS) for repositories.

fb75d53... by Jarno Suni

Name the files so that they are in the created directory

Finally the files are deleted in finish trap.

3728645... by Jarno Suni

Avoid subshell in reading a file. Use proper IFS.

78d7a9f... by Jarno Suni

realpath is preferred over readlink here

According to command
man 1 readlink

6668353... by Jarno Suni

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

Complete finish even if apt_update fails on restore.

07396e3... by Jarno Suni

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

2af4440... by Jarno Suni

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

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

Use Bash parameter expansion instead of separate command.

13f35ec... by Jarno Suni

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

5c69632... by Jarno Suni

Update copyright file

d519615... by Jarno Suni

Update control file and compat file

539e9f4... by Jarno Suni

Update changelog

3743f7b... by Jarno Suni

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

25c532a... by Jarno Suni

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

Only one distribution is allowed

Revision history for this message
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.

~jarnos/ppa-purge:master updated
4a21739... by Jarno Suni

Enable support for exact path

See man sources.list for more information. Note that this software still does
not support deb822 format for software sources, and it does not recognize
other URI types than http, https and ppa.

Unmerged commits

4a21739... by Jarno Suni

Enable support for exact path

See man sources.list for more information. Note that this software still does
not support deb822 format for software sources, and it does not recognize
other URI types than http, https and ppa.

f4bc62b... by Jarno Suni

Only one distribution is allowed

539e9f4... by Jarno Suni

Update changelog

d519615... by Jarno Suni

Update control file and compat file

5c69632... by Jarno Suni

Update copyright file

25c532a... by Jarno Suni

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

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

13f35ec... by Jarno Suni

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

ae83a36... by Jarno Suni

Use Bash parameter expansion instead of separate command.

fdd8c50... by Jarno Suni

Rename the bash completion file to ppa-purge.bash

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

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..b861b1d
155--- /dev/null
156+++ b/debian/ppa-purge.8
157@@ -0,0 +1,98 @@
158+.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13.
159+.TH PPA-PURGE APT SOFTWARE PURGER "1" "February 2023" "ppa-purge APT Software Purger 0.5.0.0" "User Commands"
160+.SH NAME
161+ppa-purge APT Software Purger \- manual page for ppa-purge APT Software Purger 0.5.0.0
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 the matching sources and revert packages to versions
176+available from the remaining sources. If a package is not available from any
177+remaining sources, 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 is given, a source must match it to
180+be disabled/removed. distribution can be a suite name like stable or a codename
181+like focal or an exact path in which case it must end with a slash (/). Bash
182+completion is supported.
183+.SS "Exit Status:"
184+.IP
185+0 on success; non\-zero integer on error
186+.SH OPTIONS
187+.TP
188+\fB\-\-figure\-soname\-bumps\fR
189+Explicitly install packages that are figured as soname
190+bumped version of a package to be removed. Display
191+list of these packages.
192+.TP
193+\fB\-s\fR, \fB\-\-simulate\fR
194+No action; do not downgrade or remove packages.
195+.TP
196+\fB\-i\fR, \fB\-\-initial\-update\fR
197+Do initial update of package lists. Use this, if you
198+are not sure the package lists are updated already.
199+.TP
200+\fB\-r\fR, \fB\-\-remove\fR
201+Remove unneeded .list files or repository entries
202+instead of leaving backups or commenting entries out,
203+respectively.
204+.TP
205+\fB\-v\fR <level>, \fB\-v\fR<level>, \fB\-\-verbose\fR <level>, \fB\-\-verbose=\fR<level>
206+Verbosity level of "apt\-get update" output.
207+0: only errors and warninings
208+1: normal output (default).
209+.TP
210+\fB\-y\fR, \fB\-\-yes\fR
211+Run non\-interactively; do not prompt for changes.
212+.TP
213+\fB\-h\fR, \fB\-\-help\fR
214+Display this help text and exit.
215+.TP
216+\fB\-V\fR, \fB\-\-version\fR
217+Show version and exit.
218+.SH ENVIRONMENT
219+.TP
220+RELEASE
221+Target release to be downgraded to. If not set, output of
222+"lsb_release \fB\-cs\fR" is used.
223+.SH EXAMPLES
224+.IP
225+sudo ppa\-purge ppa:ubuntu\-x\-swat/x\-updates
226+.IP
227+Purge the same PPA on Linux Mint 18.1 (based on Ubuntu 16.04):
228+.IP
229+sudo RELEASE=16.04 ppa\-purge ppa:ubuntu\-x\-swat/x\-updates
230+.IP
231+Purge Google Chrome repository:
232+.IP
233+sudo ppa\-purge http://dl.google.com/linux/chrome/deb
234+.IP
235+Downgrade packages from xenial\-proposed in Ubuntu 16.04:
236+.IP
237+sudo ppa\-purge xenial\-proposed
238+.SH COPYRIGHT
239+Copyright \(co authors.
240+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
241+.br
242+This is free software: you are free to change and redistribute it.
243+There is NO WARRANTY, to the extent permitted by law.
244+.SH "SEE ALSO"
245+The full documentation for
246+.B ppa-purge APT Software Purger
247+is maintained as a Texinfo manual. If the
248+.B info
249+and
250+.B ppa-purge APT Software Purger
251+programs are properly installed at your site, the command
252+.IP
253+.B info ppa-purge APT Software Purger
254+.PP
255+should give you access to the complete manual.
256diff --git a/debian/ppa-purge.bash-completion b/debian/ppa-purge.bash-completion
257index be8edde..c337fa4 100644
258--- a/debian/ppa-purge.bash-completion
259+++ b/debian/ppa-purge.bash-completion
260@@ -1,80 +1,99 @@
261 # /usr/share/bash-completion/completions/ppa-purge
262 # Debian ppa-purge(1) completion -*- shell-script -*-
263
264-_update_server(){
265- local i
266- for (( i=1; i < ${#words[@]}-1; i++)) ; do
267- case "${words[i]}" in
268- -s)
269- SERVER=${words[i+1]}
270- ;;
271- *)
272- ;;
273- esac
274- done
275-}
276+while true; do
277
278-_update_owner(){
279- local i
280- for (( i=1; i < ${#words[@]}-1; i++)) ; do
281- case "${words[i]}" in
282- -o)
283- OWNER=${words[i+1]}
284- ;;
285- *)
286- ;;
287- esac
288- done
289-}
290+# Check which arguments have been given already. This is used for
291+# deciding which completions will be offered.
292+__ppa_purge_update_args() {
293+ local i word last=${#words[@]} prevword=
294+ for (( i=1; i < $last; i++ )) ; do
295+ word=${words[i]}
296+ (( $i != $cword )) || [[ -z $cur ]] &&
297+ case "$word" in
298+ http?(s)://*) url=$word ;;
299+ ppa:*) ppa=$word ;;
300+ -*) ;;
301+ ?*) [[ $prevword =~ ^-([^-]*v|-verbose)$ ]] || dist=$word
302+ esac
303+ prevword=$word
304+ done
305+} || break
306
307-_ppa_names(){
308- _update_server
309- _update_owner
310- grep -hs "^deb\ .*$SERVER" /etc/apt/sources.list.d/*.list | grep "$OWNER" | command sed "s#.*$SERVER\/.*\/\(.*\)\/.*#\1#"
311-}
312+__repo_dist() {
313+ [[ $url ]] &&
314+ sed -rn \
315+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+'"$url"'/?[[:blank:]]+([^[:blank:]]+).*#\3#p' \
316+/etc/apt/sources.list.d/*.list /etc/apt/sources.list | sort -u ||
317+ sed -rn \
318+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://[^[:blank:]]+[[:blank:]]+([^[:blank:]]+).*#\3#p' \
319+/etc/apt/sources.list.d/*.list /etc/apt/sources.list | sort -u
320+} || break
321
322-_ppa_host(){
323- grep -hs "^deb\ .*tp\:\/\/.*\/.*\/.*" /etc/apt/sources.list.d/*.list | command sed "s#^deb.*\:\/\/\(.*\)\/.*\/.*/.*#\1#" | uniq
324-}
325+__repo_list() {
326+ [[ $dist ]] &&
327+ sed -rn \
328+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+(https?://[^[:blank:]]+)[[:blank:]]+'"$dist"'[[:blank:]]+.*#\3#p' \
329+/etc/apt/sources.list.d/*.list /etc/apt/sources.list \
330+| sed -e '/http:\/\/ppa\.launchpad\.net/d' -e 's#/$##' \
331+||
332+ sed -rn \
333+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+(https?://[^[:blank:]]+).*#\3#p' \
334+/etc/apt/sources.list.d/*.list /etc/apt/sources.list \
335+| sed -e '/http:\/\/ppa\.launchpad\.net/d' -e 's#/$##'
336+} || break
337
338-_ppa_owner(){
339- _update_server
340- grep -hs "^deb\ .*$SERVER" /etc/apt/sources.list.d/*.list | command sed "s#.*$SERVER\/\(.*\)\/.*\/.*#\1#"
341+__ppa_list() {
342+ sed -rn \
343+'s#^[[:blank:]]*deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://ppa\.launchpad\.net/([^/[:blank:]]+/[^/[:blank:]]+).*#\3#p' \
344+/etc/apt/sources.list.d/*.list /etc/apt/sources.list |
345+ sed -e 's#^[^/]*$#&/#' -e 's#.*#ppa:&#'
346+} || break
347+
348+__make_opts_wordlist() {
349+ local i
350+ for i in ${opts[*]}; do wordlist+=("--$i "); done
351+ for i in ${!args[*]}; do wordlist+=("--$i="); done
352+ compopt -o nospace
353 }
354
355-_ppa_list(){
356- _update_server
357- _update_owner
358- grep -hs "^deb\ .*$SERVER" /etc/apt/sources.list.d/*.list | grep "$OWNER" | command sed "s#.*$SERVER\/\(.*\/.*\)\/.*#\1#"
359+_ppa_purge() {
360+ local IFS=$'\n' # needed for handling trailing space of some options and all arguments
361+ local cur prev words cword split # set by _init_completion()
362
363-}
364-_ppa_purge(){
365- OWNER=""
366- SERVER="ppa.launchpad.net"
367- local cur prev words cword opts
368- _init_completion || return
369+ # Do not treat : and = as word breaks even if they are in $COMP_WORDBREAKS:
370+ # Split option=value into option in $prev and value in $cur
371+ _init_completion -n : -s || return
372+
373+ local opts=(help simulate initial-update yes version remove figure-soname-bumps)
374+ local -A args=([verbose]=$'0\n1')
375
376- opts="-p -s -o -d -y -i -h"
377+ local i
378+ for i in ${!args[*]}; do
379+ if [[ $prev = --$i ]]; then
380+ [[ "$COMP_WORDBREAKS" != *=* && $split == true ]] && prefix="--$i="
381+ COMPREPLY=( $( compgen -P "$prefix" -W "${args[$i]}" -- "$cur" ) )
382+ return 0
383+ fi
384+ done
385
386- case "${prev}" in
387- -p)
388- COMPREPLY=( $( compgen -W "$(_ppa_names)" -- $cur ) )
389- return 0
390- ;;
391- -s)
392- COMPREPLY=( $( compgen -W "$(_ppa_host)" -- $cur ) )
393- return 0
394- ;;
395- -o)
396- COMPREPLY=( $( compgen -W "$(_ppa_owner)" -- $cur ) )
397- return 0
398- ;;
399- *)
400- ;;
401- esac
402-
403- COMPREPLY=( $( compgen -W '${opts} $(_ppa_list)' -- "$cur" ) )
404+ local url= ppa= dist= prefix= wordlist=()
405+ [[ $cur = -* ]] && __make_opts_wordlist || {
406+ __ppa_purge_update_args
407+ if [[ $ppa ]]; then
408+ __make_opts_wordlist
409+ elif [[ $url ]]; then
410+ [[ $dist ]] && __make_opts_wordlist || wordlist=( $(__repo_dist) )
411+ elif [[ $dist ]]; then
412+ wordlist=( $(__repo_list) )
413+ else
414+ wordlist=( $(__ppa_list; __repo_list; __repo_dist) )
415+ fi
416+ }
417
418- return 0
419-} &&
420-complete -F _ppa_purge ppa-purge
421+ COMPREPLY=( $( compgen -W "${wordlist[*]}" -- "$cur" ) )
422+ __ltrim_colon_completions "$cur"
423+ return 0
424+} && complete -F _ppa_purge ppa-purge
425+break
426+done
427diff --git a/debian/ppa-purge.manpages b/debian/ppa-purge.manpages
428index 189ec3e..c31d87b 100644
429--- a/debian/ppa-purge.manpages
430+++ b/debian/ppa-purge.manpages
431@@ -1 +1 @@
432-debian/ppa-purge.1
433+debian/ppa-purge.8
434diff --git a/ppa-purge b/ppa-purge
435index 19ad281..f717ac5 100755
436--- a/ppa-purge
437+++ b/ppa-purge
438@@ -1,29 +1,61 @@
439-#!/bin/bash
440-# A script to remove all packages in a PPA and revert back to the normal
441-# distribution ones.
442+#!/bin/bash -u
443+# A script to disable a repository and to remove all packages installed in your
444+# system from it and to revert back to the version (if any) available from a
445+# leftover repository.
446 #
447+<<<<<<< ppa-purge
448 # AUTHORS: Robert Hooker (Sarvatt), Tormod Volden, Darkxst, Jarno Suni (jarnos)
449+=======
450+# AUTHORS: Robert Hooker (Sarvatt), Lorenzo De Liso, Tormod Volden,
451+# Lorenzo De Liso, Tim Lunn (Darkxst), Jarno Ilari Suni (jarnos)
452+
453+export LC_ALL=C # Use C locale to get standard sorting and better regex
454+# performance.
455+export TMPDIR=/dev/shm # dir for mktemp to create files in
456+
457+# Constants
458+declare -r APT=apt-get \
459+yes_option='--force-yes' \
460+F_ARCHS=$(dpkg --print-foreign-architectures) \
461+mytmpdir=$(mktemp -d)
462+declare -r PKGS=${mytmpdir}/pkgs \
463+REVERTS=${mytmpdir}/reverts \
464+EXITCODE=${mytmpdir}/exitcode \
465+program_name=ppa-purge \
466+program_full_name='ppa-purge APT Software Purger' \
467+program_pkg_name=ppa-purge \
468+program_version=0.5.0.0 \
469+copyright='authors' \
470+copyright_year=
471+
472+# Initialize some variables
473+restore=t
474+declare -a lists=()
475+url=
476+no_update=
477+unset -v IFS
478+>>>>>>> ppa-purge
479
480 # Defaults
481-F_ARCHS=$(dpkg --print-foreign-architectures)
482-PPA_PKGS=$(mktemp)
483-REVERTS=$(mktemp)
484-trap "rm $PPA_PKGS $REVERTS" 0
485+# Default for RELEASE will be set below, if needed.
486+yes=
487+simulate=
488+initial_update=
489+remove=
490+verbose=1
491+figure_soname=
492
493 # Functions to write output nicely.
494-write_msg() {
495- echo "$*" | fold -s -w "${COLUMNS:-80}"
496-}
497-
498 msg() {
499- write_msg "$*"
500+ echo "[$program_name] $*"
501 }
502
503 warn() {
504- write_msg "Warning: $*" 1>&2
505+ msg "Warning: $*" 1>&2
506 }
507
508 error() {
509+<<<<<<< ppa-purge
510 write_msg "Error: $*" 1>&2
511 }
512
513@@ -59,10 +91,138 @@ usage() {
514 echo "(For example: you left synaptic open while attempting to run it) simply"
515 echo "uncomment the PPA from your sources, run apt-get update and try again."
516 echo
517+=======
518+ msg "Error: $1" 1>&2
519+ exit ${2:-1}
520+}
521+
522+apt_update() {
523+ msg "Updating package lists..."
524+ case $verbose in
525+ 0) exec 3>/dev/null ;;
526+ 1) exec 3>&1
527+ esac
528+ local exit_code=
529+ {
530+ # read and echo warning & error messages
531+ w=
532+ while IFS= read -r; do
533+ printf '%s\n' "$REPLY" >&2
534+ [[ $REPLY =~ ^[EW]: ]] && exit_code=0 # warning or error detected
535+ done
536+ } < <($APT update 2>&1 >&3 || printf $? >$EXITCODE)
537+ exec 3>&-
538+
539+ [[ -s $EXITCODE ]] && IFS= read -r exit_code <"$EXITCODE"
540+
541+ [[ $exit_code ]] && {
542+ no_update=t
543+ [[ $yes || $exit_code -ne 0 ]] || {
544+ read -r -p "$(msg 'Continue even if error or warning was detected (Y/n)? ')"
545+ [[ ! ( -z $REPLY || $REPLY =~ ^[Yy]$ ) ]]
546+ } && error "Updating package lists failed; error code ${exit_code}." 5
547+ }
548+ return 0
549+}
550+
551+finish() {
552+ set +o pipefail
553+ ((${#lists[@]} > 0)) && {
554+
555+ [[ $restore ]] && {
556+ msg 'Restoring .list file(s):'
557+ for file in "${lists[@]}"; do
558+ mv -fv "$file".save "$file"
559+ done
560+ [[ $no_update ]] || apt_update || :
561+ } || {
562+ [[ $remove ]] && {
563+ msg 'Removing .list file(s):'
564+ for file in "${lists[@]}"; do
565+ grep -Evq '^[[:blank:]]*(#.*)?$' "$file" || {
566+ # everything is commented out
567+ rm -rv "$file" "$file".save* || :
568+ }
569+ done
570+ }
571+ }
572+ }
573+ rm -rf "$mytmpdir"
574+}
575+
576+trap finish 0
577+
578+usage() {
579+fold -s -w "${COLUMNS:-80}" << EOF
580+Usage: $program_name [options] ppa:<ppaowner>[/<ppaname>]
581+or: $program_name [options] <URL> [<distribution>]
582+or: $program_name [options] <distribution>
583+or: $program_name { --help | --version }
584+
585+$program_name will disable the matching sources and revert \
586+packages to versions available from the remaining sources. If a \
587+package is not available from any remaining sources, it will be \
588+removed, unless it is a package related to current kernel or it is the \
589+package of this command. If <ppaname> is not given, 'ppa' is used as \
590+default. If a distribution is given, a source must match it to be \
591+disabled/removed. distribution can be a suite name like stable or a \
592+codename like focal or an exact path in which case it must end with \
593+a slash (/). Bash completion is supported.
594+
595+Exit Status:
596+ 0 on success; non-zero integer on error
597+
598+Options:
599+ --figure-soname-bumps Explicitly install packages that are figured as soname
600+ bumped version of a package to be removed. Display
601+ list of these packages.
602+ -s, --simulate No action; do not downgrade or remove packages.
603+ -i, --initial-update Do initial update of package lists. Use this, if you
604+ are not sure the package lists are updated already.
605+ -r, --remove Remove unneeded .list files or repository entries
606+ instead of leaving backups or commenting entries out,
607+ respectively.
608+ -v <level>, -v<level>, --verbose <level>, --verbose=<level>
609+ Verbosity level of "$APT update" output.
610+ 0: only errors and warninings
611+ 1: normal output (default).
612+ -y, --yes Run non-interactively; do not prompt for changes.
613+ -h, --help Display this help text and exit.
614+ -V, --version Show version and exit.
615+
616+Environment:
617+ RELEASE Target release to be downgraded to. If not set, output of
618+ "lsb_release -cs" is used.
619+
620+Examples:
621+ sudo $program_name ppa:ubuntu-x-swat/x-updates
622+
623+ Purge the same PPA on Linux Mint 18.1 (based on Ubuntu 16.04):
624+
625+ sudo RELEASE=16.04 $program_name ppa:ubuntu-x-swat/x-updates
626+
627+ Purge Google Chrome repository:
628+
629+ sudo $program_name http://dl.google.com/linux/chrome/deb
630+
631+ Downgrade packages from xenial-proposed in Ubuntu 16.04:
632+
633+ sudo $program_name xenial-proposed
634+
635+EOF
636+>>>>>>> ppa-purge
637 exit $1
638 }
639
640+show_version() {
641+printf "$program_full_name $program_version
642+Copyright (C) $copyright_year $copyright.
643+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
644+This is free software: you are free to change and redistribute it.
645+There is NO WARRANTY, to the extent permitted by law.\n"
646+}
647
648+<<<<<<< ppa-purge
649 # Command line options
650 while getopts ":p:o:s:d:yih" opt; do
651 case "$opt" in
652@@ -93,30 +253,34 @@ if [[ $1 ]]; then
653 usage 1
654 fi
655 fi
656+=======
657+suggest_usage() {
658+ echo "Run '$program_name -h' to get help."
659+}
660
661-APTARG=""
662-if [ ! -z "$APTALT" ]; then
663- if [ ! -z "$FORCEINSTALL" ]; then
664- APTARG="-y"
665- fi
666- APT=aptitude; APTALT=apt-get
667-else
668- if [ ! -z "$FORCEINSTALL" ]; then
669- APTARG="-y --force-yes"
670- fi
671- APT=apt-get; APTALT=aptitude
672-fi
673+# escape special characters (http://unix.stackexchange.com/a/209744/111181)
674+escape_regex() {
675+ printf '%s' "$1" | sed 's/[.[\*^$()+?{|]/\\&/g'
676+}
677+>>>>>>> ppa-purge
678
679+
680+<<<<<<< ppa-purge
681 if [ -z "$PPAOWNER" ]; then
682 error "Required ppa-name argument was not specified"
683 usage 1
684 fi
685+=======
686+revert() {
687+ msg "Generating revert list..."
688+
689+ # Create apt argument list for reverting packages
690+>>>>>>> ppa-purge
691
692-# If not set, using defaults
693-[ -z "$PPAHOST" ] && PPAHOST="ppa.launchpad.net"
694-[ -z "$PPANAME" ] && PPANAME="ppa"
695-[ -z "$DIST" ] && DIST=$(lsb_release -c -s)
696+ # store available packages in a sorted variable for faster access.
697+ avail_pkgs=$(apt-cache dumpavail | grep '^Package:' | cut -d' ' -f2 | sort -urV)
698
699+<<<<<<< ppa-purge
700 if [ "$(id -u)" != "0" ]; then
701 error "This script would need superuser privileges, use sudo"
702 usage 1
703@@ -126,91 +290,258 @@ msg "Updating packages lists"
704 if ! $APT update > /dev/null; then
705 error "$APT update failed for some reason"
706 exit 1
707+=======
708+ # Create an associated array for fast checking of available packages.
709+ # Creating takes some time though, say 1s, but will save a lot if there are many
710+ # reverts.
711+ declare -A avail=()
712+ for PKG in $avail_pkgs; do avail[$PKG]=; done
713+
714+ # tag for current kernel version
715+ curkerversion=$(escape_regex $(uname -r | cut -d- -f1,2))
716+ # tag for current kernel flavor
717+ curkerflavor=$(escape_regex $(uname -r | cut -d- -f3-))
718+ REINSTALL=
719+ declare -a sonamepkg=()
720+ while IFS= read -r PACKAGE; do
721+ PKG=${PACKAGE%:*}
722+
723+ # Test if PKG is still available
724+ # if ! grep -xFq "$PKG" <<<"$avail_pkgs"; then
725+ if [[ -z ${avail[$PKG]+x} ]]; then
726+
727+ # Explicitly remove the package that does not exist in archive unless
728+ # it is versioned kernel package matching the current kernel or the
729+ # package of this program.
730+ [[ $PKG =~ ^linux-.+-${curkerversion}(-${curkerflavor})?$ ||
731+ $PKG == $program_pkg_name ]] &&
732+ msg "Note: Not removing $PKG package." ||
733+ {
734+ REINSTALL+=" $PACKAGE-"
735+
736+ [[ $figure_soname && $PKG != linux-* ]] && {
737+ # Maybe could even restrict to lib* ?
738+ # check if the package is availabe with another version tag
739+ pkg_regex=$(escape_regex "$PKG")
740+ soname_regex=$(sed -r \
741+ -e 's/[[:digit:]][[:lower:]]$/[[:digit:]][[:lower:]]/' \
742+ -e 's/[[:digit:]]+/[[:digit:]]+/g' <<<"$pkg_regex")
743+ [[ $soname_regex != $pkg_regex ]] && {
744+
745+ # get the greatest available version of the package
746+ APTAVAIL=$(grep -m 1 -E "^${soname_regex}$" \
747+ <<<"$avail_pkgs" || :)
748+
749+ # downgrade packages that have a soname bump
750+ [[ $APTAVAIL ]] && {
751+ newpkg=${APTAVAIL}${PACKAGE#$PKG}
752+ sonamepkg+=("$newpkg")
753+ REINSTALL+=" $newpkg/$RELEASE"
754+ }
755+ }
756+ }
757+ }
758+ else
759+ REINSTALL+=" $PACKAGE/$RELEASE"
760+ fi
761+ done <$REVERTS
762+ unset -v avail avail_pkgs
763+ >$REVERTS
764+
765+ [[ ${#sonamepkg[*]} -gt 0 ]] && {
766+ msg "Going to install these packages due to soname bump figuring:
767+ $(printf '%s\n' "${sonamepkg[@]}")"
768+ msg "These of them are installed already (but maybe different version):
769+ $(dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' "${sonamepkg[@]}" \
770+ 2>/dev/null | awk '/^.i /{print $2}')"
771+
772+ [[ $yes ]] || {
773+ read -p "$(msg 'Continue (Y/n)? ')" -r
774+ [[ -z $REPLY || $REPLY =~ ^[Yy]$ ]] || exit
775+ }
776+ }
777+
778+ msg "Reverting..."
779+ $APT $simulate $yes -V install $REINSTALL || {
780+ exit_status=$?
781+ [[ $exit_status -eq 1 ]] &&
782+ # User aborted apt-get; no packages were downgraded or removed.
783+ exit 5 ||
784+ error "Something went wrong with $APT; error code $exit_status. \
785+ Packages may not have been reverted." 5
786+ }
787+ msg "Reverting packages finished successfully."
788+}
789+
790+if [[ ${RELEASE+x} ]]; then
791+ [[ $RELEASE =~ ^[^/[:blank:]]+$ ]] || {
792+ error "Invalid target release name :" \'"$RELEASE"\'
793+ }
794+else
795+ RELEASE=$(lsb_release -c -s)
796+>>>>>>> ppa-purge
797 fi
798
799-msg "PPA to be removed: $PPAOWNER $PPANAME"
800+# Command line options
801+env -u GETOPT_COMPATIBLE getopt --test >/dev/null || [[ $? -ne 4 ]] && {
802+ # This should not happen with util-linux's getopt.
803+ error '`getopt --test` failed in this environment.' 3
804+}
805
806-# Make list of all packages in PPA
807-PPA_LIST=/var/lib/apt/lists/${PPAHOST}_${PPAOWNER}_${PPANAME}_*_Packages
808-for LIST in $PPA_LIST; do
809- if [ -e $LIST ]; then
810- grep "^Package: " $LIST | cut -d " " -f2 | sort >> $PPA_PKGS
811+# Option name followed by ':' denotes an option that has an argument.
812+# Options are separated by ','.
813+params=$(env -u GETOPT_COMPATIBLE getopt -o siyhrv:V \
814+-l simulate,initial-update,yes,help,version,remove,verbose:,\
815+figure-soname-bumps --name "[$program_name] Error" -- "$@") || {
816+ # If $? = 1, command line is invalid; getopt displays an error message
817+ [[ $? -eq 1 ]] && exit 1
818+ >&2 error 'getopt failed.' 3
819+}
820+# $params contains at least --
821+
822+eval set -- "$params"
823+unset -v params
824+while :; do
825+ case $1 in
826+ -s|--simulate ) simulate='-s' ;;
827+ -i|--initial-update ) initial_update=t ;;
828+ -y|--yes ) yes="$yes_option" ;;
829+ -V|--version ) show_version; exit ;;
830+ -h|--help ) usage 0 ;;
831+ -r|--remove ) remove=t ;;
832+ -v|--verbose )
833+ case $2 in
834+ 0|1) verbose="$2" ;;
835+ *) error "Invalid verbose level." 1 ;;
836+ esac
837+ shift 2; continue ;;
838+ --figure-soname-bumps ) figure_soname=t ;;
839+ -- ) # End of all options.
840+ shift; break
841+ esac
842+ shift
843+done
844+
845+distro=
846+while [[ ${1-} ]]; do
847+ if [[ $1 =~ ^ppa:([^/[:blank:]]+)(/[^/[:blank:]]+)?$ ]]; then
848+ url=ppa.launchpad.net/${BASH_REMATCH[1]}${BASH_REMATCH[2]:-/ppa}/ubuntu
849+ elif [[ $1 =~ ^https?://([^[:blank:]]*[^/[:blank:]])/?$ ]]; then
850+ url=${BASH_REMATCH[1]}
851+ else
852+ distro=$1
853 fi
854+ shift
855 done
856
857+<<<<<<< ppa-purge
858 if [ ! -s $PPA_PKGS ]; then
859 error "Could not find package list for PPA: $PPAOWNER $PPANAME"
860 exit 1
861 fi
862+=======
863+[[ -z $url && -z $distro ]] && {
864+ error "No argument given. $(suggest_usage)"
865+}
866+>>>>>>> ppa-purge
867
868-# Ignore the ppa-purge package
869-if grep -q "ppa-purge" $PPA_PKGS; then
870- sed -i '/ppa-purge/d' $PPA_PKGS
871- msg "Note: Not removing ppa-purge package"
872+# Make list of all packages available from the matching archive(s)
873+[[ $url ]] && _url=${url//\//_} || _url='*'
874+dir=
875+if [[ ${distro: -1} == / ]]; then
876+ [[ $url ]] || error 'No URL given'
877+ dir=${distro:0:-1}; _dir=${dir//\//_}
878 fi
879
880-# Get multi-arch package names for revert list
881-cat $PPA_PKGS | sort -u |
882- xargs dpkg-query -W -f='${binary:Package}\t${db:Status-Abbrev}\n' 2>/dev/null |
883- awk '/\tii $/{print $1}' > $REVERTS
884-# Fallback for Precise
885-if [ ! -s $REVERTS ]; then
886- for PACKAGE in $(cat $PPA_PKGS | sort -u); do
887- dpkg-query -W -f='${PackageSpec}\t${Status}\n' $PACKAGE 2>/dev/null |
888- awk '/\tinstall/{print $1}' >> $REVERTS
889- for F_ARCH in $F_ARCHS; do
890- dpkg-query -W -f='${PackageSpec}\t${Status}\n' "$PACKAGE:$F_ARCH" 2>/dev/null |
891- awk '/\tinstall/{print $1}' >> $REVERTS
892- done
893- done
894+if [ "$(id -u)" != "0" ]; then
895+ error "This script would need superuser privileges, use sudo" 2
896 fi
897
898-# Disable PPA from sources.list files
899-for LIST in $(find /etc/apt/ -name "*.list" -exec readlink -f '{}' \;); do
900- if [ -e $LIST ] && grep -q $PPAOWNER/$PPANAME $LIST; then
901- msg "Disabling $PPAOWNER PPA from $LIST"
902- sed -ri "\:^[^#]+/${PPAOWNER}/${PPANAME}/:s/^deb/# deb/" $LIST
903+[[ $initial_update ]] && apt_update
904+no_update=t
905+
906+msg "To be removed: ${url} ${distro}"
907+
908+for LIST in /var/lib/apt/lists/${_url}_*_Packages; do
909+ if [ -f $LIST ]; then
910+ nomatch=
911+ if [[ $distro ]]; then
912+ if [[ dir ]]; then
913+ d=${LIST%_*}; d=${d#*${_url}_}
914+ [[ $d == $_dir ]] || nomatch=t
915+ else
916+ d=${LIST##*_dists_}; d=${d%%_*}
917+ [[ $d == $distro ]] || nomatch=t
918+ fi
919+ fi
920+ [[ $nomatch ]] ||
921+ grep "^Package: " $LIST | cut -d " " -f2 >> $PKGS
922 fi
923 done
924
925-msg "Updating packages lists"
926-$APT update > /dev/null || warn "$APT update failed for some reason"
927-
928-# Create apt argument list for reverting packages, most of the foo here is to attempt
929-# to unroll soname bumps
930+no_pkgs=
931+if [ ! -s $PKGS ]; then
932+ warn "Could not find matching packages."
933+ no_pkgs=t
934+else
935+ # Get multi-arch package names for revert list
936+ sort -u $PKGS | xargs dpkg-query -W \
937+ -f='${binary:Package}\t${db:Status-Abbrev}\n' 2>/dev/null |
938+ awk '/\tii $/{print $1}' > $REVERTS
939+ >$PKGS
940+fi
941
942-REINSTALL=""
943-for PACKAGE in $(cat $REVERTS); do
944- PKG=$(echo $PACKAGE | cut -d ':' -f1)
945- [[ $PACKAGE == *:* ]] && D_ARCH=":"$(echo $PACKAGE | cut -d ':' -f2)
946+# Disable matching lines from sources.list files
947+[[ $url ]] &&
948+ regex='^deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://'"$(escape_regex "$url")"'/?[[:blank:]]+([^[:blank:]]+)' ||
949+ regex='^deb(-src)?([[:blank:]]+\[.+\])?[[:blank:]]+https?://[^[:blank:]]+ +([^[:blank:]]+)'
950+newlist=
951+for LIST in $(find /etc/apt/ -name "*.list" -exec realpath -e '{}' \;); do
952+ changed=
953+ while read -r; do
954+ nomatch=
955+ [[ "$REPLY" =~ $regex ]] && {
956+ if [[ $distro ]]; then
957+ [[ ${BASH_REMATCH[3]} == $distro ]] || nomatch=t;
958+ fi
959+ } || nomatch=t
960
961- if [ $(grep-aptavail -XPc -s Package $PKG) -eq 0 ]; then
962- PAT=$(echo $PKG | sed -e s/[0-9][a-z]\$/'..'/ -e s/[0-9]/'.'/g)
963+ [[ $nomatch ]] && newlist+="$REPLY"$'\n' || {
964+ [[ $remove ]] && msg "Remove entry: $REPLY" || {
965+ newlist+="# $REPLY"$'\n'
966+ msg "Disable entry: $REPLY"
967+ }
968+ changed=t
969+ }
970+ done <$LIST
971
972- APTAVAIL=$(grep-aptavail -eP --pattern='^'$PAT'$' -s Package -n | sort -uV | sed -e '$!d')
973+ [[ $changed ]] && {
974+ msg "Making backup of .list file:"
975+ mv -fvb "$LIST" "$LIST".save
976+ lists+=("$LIST")
977+ printf %s "$newlist" > "$LIST"
978+ }
979+ newlist=
980+done
981
982- #explicitly remove packages that don't exist in archive
983- if [ "x$APTAVAIL" != "x$PKG" ]; then
984- REINSTALL="$REINSTALL $PACKAGE-"
985- fi
986+(( ${#lists[@]} > 0 )) && {
987+ [[ $yes ]] || {
988+ read -p "$(msg 'Continue with these changes (Y/n)? ')" -r
989+ [[ -z $REPLY || $REPLY =~ ^[Yy]$ ]] || exit
990+ }
991
992- #downgrade packages that have a soname bump
993- if [ -n "$APTAVAIL" ]; then
994- REINSTALL="$REINSTALL $APTAVAIL$D_ARCH/$DIST"
995- fi
996- else
997- REINSTALL="$REINSTALL $PACKAGE/$DIST"
998- fi
999-done
1000+ no_update=
1001+ apt_update
1002
1003-msg "Package revert list generated:"
1004-msg "$REINSTALL"
1005-echo
1006+ [[ $no_pkgs ]] || revert
1007
1008-# FIXME:
1009-# Workaround for now in case APT fails. APTALT is a little more foregiving if the
1010-# revert list isn't 100% correct.
1011+ [[ $simulate ]] &&
1012+ msg "Restoring repository entries, because this was just simulation:" \
1013+ || restore=
1014+ # successful operation; no need to restore, unless in simulation mode.
1015+}
1016
1017+<<<<<<< ppa-purge
1018 if $APT $APTARG install $REINSTALL; then
1019 msg "PPA purged successfully"
1020 elif $APTALT $APTARG install $REINSTALL; then
1021@@ -219,4 +550,6 @@ else
1022 error "Something went wrong, packages may not have been reverted"
1023 exit 1
1024 fi
1025+=======
1026+>>>>>>> ppa-purge
1027 exit 0

Subscribers

People subscribed via source and target branches

to all changes: