Bug 314549 - Process more complex markings files
Summary: Process more complex markings files
Status: RESOLVED FIXED
Alias: None
Product: muon
Classification: Applications
Component: libqapt (show other bugs)
Version: 2.0.0
Platform: Ubuntu Linux
: NOR wishlist
Target Milestone: ---
Assignee: Jonathan Thomas
URL:
Keywords: investigated
Depends on:
Blocks:
 
Reported: 2013-02-06 19:49 UTC by Vassilis Palassopoulos
Modified: 2013-05-22 11:38 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed In: 2.1.0


Attachments
Patch to fix the bug (39.67 KB, patch)
2013-05-17 16:03 UTC, Vassilis Palassopoulos
Details
A minor fix on coding style (517 bytes, patch)
2013-05-22 11:38 UTC, Vassilis Palassopoulos
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Vassilis Palassopoulos 2013-02-06 19:49:41 UTC
For Muon to process a markings file it must be of the form: <package_name><tab><tab>install<end_of_line>

While Muon and Synaptic produce markings files of that form, a person might want to produce a more humanly readable markings file which also does more things than simply installing packages.

Synaptic is more flexible in processing more humanly readable markings files which do more than simply installing packages.
It would be nice if Muon would behave the same way.

Interoperability would be much appreciated.

Interoperability between Synaptic and Muon on how they act on markings files would be really helpful:
1. To people switching from a gtk-based distro to a qt-based and
2. To people who use markings files to install their programs after a fresh install.

Reproducible: Always

Steps to Reproduce:
1. Open Muon Package Manager
2. Go to File ---> Read Markings...
3. Select a Markings file
Actual Results:  
It shows a window with the message: 
Could not mark changes. Please make sure that the file is a markings file created by either the Muon Package Manager or the Synaptic Package Manager

Expected Results:  
Process the markings file and show the markings in the GUI as it happens with Synaptic or with automatically generated markings files

Synaptic 0.80 can process: 'install', 'deinstall', 'purge'
as well: 'remove', 'uninstall' which do the same as 'deinstall'

Also Synaptic can read files in more freely typed forms. Example: paste.kde.org/666338

Note:
'uninstall' isn't documented in man pages of apt-get. I asked one of the Synaptic developers about it and (as it turned out it was the same developer who introduced the keyword) he told me he introduced it because it seemed a reasonable keyword for the task for a new user.

Note 2:
Earlier versions of Synaptic couldn't process 'purge' and 'uninstall' which was inconsistent with the expected behavior (by being selective on which keywords to respond) and after reporting it, it was fixed in 0.80

Observation: Muon Software Center has the same menu option for reading markings files but it doesn't seem to (me to) work properly at all.
Comment 1 Vassilis Palassopoulos 2013-05-06 12:54:24 UTC
After navigating through the code, I find the issue has to do with the way the method: bool Backend::loadSelections(const QString &path) is implemented on backend.cpp on LibQApt (as can be seen here: https://projects.kde.org/projects/extragear/sysadmin/libqapt/repository/revisions/master/entry/src/backend.cpp)

It's clear that the reason Muon can only handle the beforementioned strict syntax ( <package_name><tab><tab>install<end_of_line>) on markings files is this line of code:
        int eqpos = line.indexOf("\t\t");

which basically identifies the position of the <tab><tab> in order to do the separation between package name and action acted upon it (as can be seen on the code that follows): 
        if (eqpos < 0) {
            // Invalid
            lineIndex++;
            continue;
        } else {
            aKey = line.left(eqpos);
            aValue = line.right(line.size() - eqpos -2);
        }

Also it's clear from the following code that the only checks are done for 'i' (install being the sane word expected there in a markings file in order to install the package) and 'd' or 'u' (deinstall or uninstall to deinstall the package)
        if (aValue.at(0) == 'i') {
            actionMap[aKey] = Package::ToInstall;
        } else if ((aValue.at(0) == 'd') || (aValue.at(0) == 'u')) {
            actionMap[aKey] = Package::ToRemove;
        }

P.S.: So the component affected by this bug is LibQApt (and it persists in 2.0.0 since this part of the code hasn't changed)

P.S.2: One can see how Synaptic reads markings files on method: bool RPackageLister::readSelections(istream &in) http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/raring/synaptic/raring/view/head:/common/rpackagelister.cc
Comment 2 Vassilis Palassopoulos 2013-05-17 16:03:00 UTC
Created attachment 79936 [details]
Patch to fix the bug

Synaptic can process markings files with a less strict syntax with the method: bool ParseQuoteWord(const char *&String,string &Res) from apt-pkg/strutl.h as can be seen from previous comment.

backend.cpp already imports strutl.h so I decided to create a proposed patch that uses tha same method (providing interoperability as well as code reuse)

Since line, aKey, aValue are QByteArrays I did the following: ParseQuoteWord(line.constData(), aKey.data())
In case this produces any problems maybe aKey, aValue could be defined as Strings or QStrings instead of QByteArrays? line shouldn't have any problem since ParseQuoteWord doesn't change its data.

Also I extended the cases to include 'r' (remove keyword used on synaptic for deinstall) and 'p' (purge) as well case Package::ToPurge
Comment 3 Jonathan Thomas 2013-05-17 16:32:35 UTC
Git commit 4ae0602d0f81f48f58395966a8bce8e57226cb8e by Jonathan Thomas.
Committed on 17/05/2013 at 18:31.
Pushed by jmthomas into branch 'master'.

Support newer Synaptic-style markings file formats, and restrict whitespace requirements a bit.
Thanks to Vassilis Palassopoulos for the patch!
FIXED-IN:2.1.0

M  +17   -11   src/backend.cpp

http://commits.kde.org/libqapt/4ae0602d0f81f48f58395966a8bce8e57226cb8e
Comment 4 Vassilis Palassopoulos 2013-05-17 17:33:22 UTC
Just noticed a small redundancy that originates from a mistake I did on my patch. I added an additional "("

line 1250:
} else if ((aValue.at(0) == 'p')) {
Can change to:
} else if (aValue.at(0) == 'p') {
Comment 5 Vassilis Palassopoulos 2013-05-22 11:38:27 UTC
Created attachment 80020 [details]
A minor fix on coding style

Just removing unneeded parentheses ()