Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*~
build/
.flatpak-builder
.idea/
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@

Install, update, uninstall and view information about debian packages.

Eddy can also support other packaging formats such as .rpm thanks to it's PackageKit backend, although it's primary focus is managing debian packages and being designed for elementary OS.
Eddy can also support other packaging formats such as .rpm thanks to its PackageKit backend, although its primary focus
is managing debian packages and being designed for elementary OS.

## Installation

Expand All @@ -31,9 +32,12 @@ These dependencies must be present before building
- `packagekit-glib2`
- `unity`

You can install these on a Ubuntu-based system by executing this command:
You can install these on an Ubuntu-based system by executing this command:

`sudo apt install valac libgranite-dev libpackagekit-glib2-dev libunity-dev meson ninja-build libzeitgeist-2.0-dev gettext`
```
sudo apt install valac libgranite-dev libpackagekit-glib2-dev libunity-dev meson ninja-build \
libzeitgeist-2.0-dev gettext
```

### Building
```
Expand All @@ -48,9 +52,21 @@ sudo ninja install
com.github.donadigo.eddy
```

### Reporting bugs & debugging
When reporting a bug you should include as much information as possible, that is the system that you're running, what you did in order to have the bug appear and probably a simple list of steps on how to reproduce the issue, however it is not required as some issues are not easily reproducible.
## Running tests
After `meson build` is complete, run
```
ninja -C build
```
once, and after that each time there's a change in a unit test, run
```
meson test -C build
```

It should print OK on all the tests at the end of the output.

## Reporting bugs & debugging
When reporting a bug, you should include as much information as possible, that is the system that you're running, what you did in order to have the bug appear and probably a simple list of steps on how to reproduce the issue, however, it is not required as some issues are not easily reproducible.

Additionally you can include a debug log in the description of the issue. To get a full log of backend and application messages, you can execute Eddy in a terminal with the following command:
Additionally, you can include a debug log in the description of the issue. To get a full log of backend and application messages, you can execute Eddy in a terminal with the following command:
`G_MESSAGES_DEBUG=all com.github.donadigo.eddy --debug`, reproduce the bug in the application window and copy the terminal output to the issue's description.
This information could really help localizing and fixing the issue.
17 changes: 17 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ executable(
'src/AppSettings.vala',
'src/Constants.vala',
'src/DetailedView.vala',
'src/EddyUtils.vala',
'src/FolderLoader.vala',
'src/MainWindow.vala',
'src/MimeTypeHelper.vala',
Expand All @@ -51,7 +52,23 @@ executable(
install: true
)

#
# Build glue
#

valadoc = find_program('valadoc', required: false)

vala_unit_proj = subproject(
'vala-unit',
default_options: [
'install=false',
'valadoc=@0@'.format(valadoc.found())
]
)
vala_unit_dep = vala_unit_proj.get_variable('vala_unit_dep')

subdir('data')
subdir('po')
subdir('test')

meson.add_install_script('meson/post_install.py')
116 changes: 116 additions & 0 deletions src/EddyUtils.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
public class EddyUtils {
public static int compare_versions (string v1, string v2) {
// https://www.debian.org/doc/debian-policy/ch-controlfields.html#version

string a = v1;
string b = v2;

// check for empty strings - later we split the strings and it would break on an empty array
if (a == "")
return -1;
if (b == "")
return 1;

// check epochs
string[] atok = a.split(":");
string[] btok = b.split(":");

int a_epoch, b_epoch;
if (atok.length >= 2 ) {
bool a_is_epoch = int.try_parse(atok[0], out a_epoch);

if(!a_is_epoch)
a_epoch = 0;
} else {
a_epoch = 0;
}

if (btok.length >= 2) {
bool b_is_epoch = int.try_parse(btok[0], out b_epoch);

if(!b_is_epoch)
b_epoch = 0;
} else {
b_epoch = 0;
}

if (a_epoch != b_epoch)
return a_epoch - b_epoch;

// trim epochs when the same (including assumed 0 when none)
a = join_sliced_from_1(atok);
b = join_sliced_from_1(btok);

//check upstream version
Regex regex = new Regex("[+~-]");
atok = regex.split(a);
btok = regex.split(b);

string[] aparts = atok[0].split (".");
string[] bparts = btok[0].split (".");

int length = int.min (aparts.length, bparts.length);
for (int i = 0; i < length; i++) {
int a_num, b_num;
bool a_is_num = int.try_parse(aparts[i], out a_num);
bool b_is_num = int.try_parse(bparts[i], out b_num);

if (a_is_num && b_is_num) {
int diff = a_num - b_num;
if (diff != 0) {
return diff;
}
} else {
int rc = strcmp (aparts[i], bparts[i]);
if (rc != 0) {
return rc;
}
}
if (i == length - 1) {
if(aparts.length != bparts.length) {
return aparts.length - bparts.length;
}
}
}

// a tilde sorts before anything, even the end of a part
atok = a.split ("~");
btok = b.split ("~");

if (atok.length < 2 && btok.length >= 2) {
return 1;
} else if (atok.length >= 2 && btok.length < 2) {
return -1;
}

// check debian revision if present
atok = a.split("-");
btok = b.split("-");

int a_dr, b_dr;
bool a_dr_is_num = int.try_parse(atok[atok.length - 1], out a_dr);
bool b_dr_is_num = int.try_parse(btok[btok.length - 1], out b_dr);

if (a_dr_is_num && b_dr_is_num) {
if (a_dr != b_dr)
return a_dr - b_dr;
}

return strcmp(a, b);
}

private static string join_sliced_from_1(string[] arr) {
if (arr.length == 0)
return "";

if (arr.length == 1)
return arr[0];

string result = "";
for (int i = 1; i < arr.length; i++) {
result += arr[i];
}

return result;
}
}
65 changes: 12 additions & 53 deletions src/Package.vala
Original file line number Diff line number Diff line change
Expand Up @@ -32,31 +32,31 @@ public class Eddy.Package : Object {
public signal void state_updated ();

public string filename { public get; construct; }
public string name {
public string name {
get {
return target.get_name ();
}
}

public string summary {
public string summary {
get {
return target.summary;
}
}

public string version {
public string version {
get {
return target.get_version ();
}
}

public uint64 installed_size {
public uint64 installed_size {
get {
return target.size;
}
}

public string homepage {
public string homepage {
owned get {
return target.url;
}
Expand All @@ -76,8 +76,8 @@ public class Eddy.Package : Object {
public bool has_task { get; set; default = false; }

public StateFlags state_flags { public get; private set; default = StateFlags.NOT_INSTALLED; }
public bool is_installed {

public bool is_installed {
get {
return StateFlags.INSTALLED in state_flags;
}
Expand Down Expand Up @@ -178,7 +178,7 @@ public class Eddy.Package : Object {
foreach (var package in packages) {
yield package.reset ();
package.exit_code = exit_code;
}
}

return result;
}
Expand Down Expand Up @@ -260,47 +260,6 @@ public class Eddy.Package : Object {
}
}

private static int compare_versions (string a, string b) {
if (a == b) {
return 0;
}

string[] atok = a.split ("~");
string[] btok = b.split ("~");

if (atok.length < 2 && btok.length >= 2) {
return -1;
} else if (atok.length >= 2 && btok.length < 2) {
return 1;
}

string aver = atok[0];
string bver = btok[0];

string[] aparts = aver.split (".");
string[] bparts = bver.split (".");

int length = int.max (aparts.length, bparts.length);
for (int i = 0; i < length; i++) {
int rc = strcmp (aparts[i], bparts[i]);
if (i == length - 1) {
if (bparts[i] > aparts[i]) {
return 1;
}
else if (bparts[i] < aparts[i]) {
return -1;
}
}
if (rc < 0) {
return -1;
} else if (rc > 0) {
return 1;
}
}

return 0;
}

public Package (string filename) {
Object (filename: filename);
}
Expand Down Expand Up @@ -401,7 +360,7 @@ public class Eddy.Package : Object {
yield update_installed_state ();
return true;
}

} catch (Error e) {
throw e;
}
Expand All @@ -426,10 +385,10 @@ public class Eddy.Package : Object {
found = true;
state_flags = StateFlags.INSTALLED;

int rc = compare_versions (package.get_version (), version);
if (rc == 1) {
int rc = EddyUtils.compare_versions (version, package.get_version ());
if (rc < 0) {
state_flags |= StateFlags.CAN_DOWNGRADE;
} else if (rc == -1) {
} else if (rc > 0) {
state_flags |= StateFlags.CAN_UPDATE;
}
}
Expand Down
Loading