LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Slackware (http://www.linuxquestions.org/questions/slackware-14/)
-   -   package NAMING scheme (http://www.linuxquestions.org/questions/slackware-14/package-naming-scheme-4175479070/)

Skaperen 09-30-2013 09:17 AM

package NAMING scheme
 
I could not find a document that would confirm this, though I did see many examples by various individuals that contradicted this. But I'm basically interested in what is used by Slackware and maybe SBo. My purpose is so I can make a tool that will translate a package name with a version to a package name without a version, for matching a version-less reference.

The base version-less package name may have any number of "-" characters separating parts of the name. A version string is constructed that does not include any "-" characters. It is appended to the name separated by "-", followed by some kind of sequence number (what is this called, "packaging version"), also separated by "-".

I have seen package names with as many as 4 "-" separated parts before the version number, such as "font-adobe-utopia-100dpi".

So the following awk command could input the full versioned name and output the version-less name:
Code:

awk -F- '{m=NF-2;s="";for(i=1;i<m;++i){s=s "-" $i;};print substr(s,2);}'
Is this correct or do I need to know more about this than I figured so far?

NoStressHQ 09-30-2013 09:45 AM

Try using regular expressions instead of parsing the string with bare hands.

allend 09-30-2013 09:54 AM

If you google for slackware package naming convention, this is the top hit. http://www.slackware.com/~mozes/docs...esentation.pdf
Is this what you mean?
Code:

bash-4.2$ echo "icedtea-web-1.4-x86_64-2alien.txz" | rev | cut -d'-' -f4- | rev
icedtea-web


TommyC7 09-30-2013 10:01 AM

If I'm understanding this correctly, you're trying to get just the package name (or package name with version)?

I don't know a whole lot of awk, so I use this (for package name only):
Code:

rev | cut -f 4- -d "-" | rev
So if I wanted a list of installed packages without their version name:
Code:

ls -1 /var/log/packages | rev | cut -f 4- -d "-" | rev
Personally I'm not a huge fan of the whole: `rev | cut | rev' thing but I haven't figured out a way to do it without rev in shell so I've stuck with it.

If you want package names with version, you just need to change the field list to "3-" so it looks like:
Code:

ls -1 /var/log/packages | rev | cut -f 3- -d "-" | rev
You can of course, use the one with the package name and a version, then just take off the version with another `cut' probably.

Skaperen 09-30-2013 10:11 AM

Quote:

Originally Posted by NoStressHQ (Post 5037312)
Try using regular expressions instead of parsing the string with bare hands.

I could not figure out such an expression for this.

Didier Spaier 09-30-2013 10:15 AM

Why reinvent the wheel? Just have a look at functions package_base() and package_name() in /sbin/{install,remove,upgrade}pkg ;)

ERRATUM read pkgbase(), not package_base()

Skaperen 09-30-2013 10:18 AM

Quote:

Originally Posted by TommyC7 (Post 5037325)
If I'm understanding this correctly, you're trying to get just the package name (or package name with version)?

I don't know a whole lot of awk, so I use this (for package name only):
Code:

rev | cut -f 4- -d "-" | rev
So if I wanted a list of installed packages without their version name:
Code:

ls -1 /var/log/packages | rev | cut -f 4- -d "-" | rev
Personally I'm not a huge fan of the whole: `rev | cut | rev' thing but I haven't figured out a way to do it without rev in shell so I've stuck with it.

If you want package names with version, you just need to change the field list to "3-" so it looks like:
Code:

ls -1 /var/log/packages | rev | cut -f 3- -d "-" | rev
You can of course, use the one with the package name and a version, then just take off the version with another `cut' probably.

Actually, the "whole" 'rev | cut | rev' thing makes sense. For me "rev" just wasn't in my mental toolkit so I never thought to try it (I don't think I've ever used it for anything). I guess my background of lots of "by hand" parsing in C bent my mind in the direction of doing it "by hand" in shell with awk.

I was focused more on "is this really the naming scheme" (my google search just didn't come up with anything, perhaps because I did not use the term "convention"), rather than "how could one parse this" (I have no trouble with that ... I just do it by hand).

Skaperen 09-30-2013 10:25 AM

Quote:

Originally Posted by Didier Spaier (Post 5037336)
Why reinvent the wheel? Just have a look at functions package_base() and package_name() in /sbin/{install,remove,upgrade}pkg ;)

I didn't see "package_base()" in there. I did see "pkgbase()" but it's just removing the extension (not something I need ... at least not yet).

I did see "package_name()" but it seems to be more complex and I don't really follow it. Can the name scheme be described in English? (or French or German or Norwegian is OK)

gnashley 09-30-2013 10:32 AM

If you are using bash, then simply:
PKG=full-name-version-arch-build #(with or without *.txz)
echo NAME=${PKG%-*-*-*}
You are correct, the separator is the '-' character and fields should be viewed from right to left. In other words, if you have a version number(or arch or build) with a '-' in them, then installpkg will be confused. Names can have any number of '-' chars in them as you like.

Skaperen 09-30-2013 10:43 AM

Here is PART of what I am going to be doing with this. I want a search mechanism where an exact package can be found, rather than a prefix (that would be tempting but for what I'm doing would cause problems). If I did a prefix type search then "sysvinit" could match all of "sysvinit-2.88dsf-i486-3.txz" and "sysvinit-functions-8.53-i486-2.txz" and "sysvinit-scripts-2.0-noarch-15.txz". But I really want "sysvinit" to match "
sysvinit-2.88dsf-i486-3.txz". To get "sysvinit-functions-8.53-i486-2.txz" then "sysvinit-functions" should be used. This is because of the way I am building a list of packages that will be used to select package files for installation (it will also allow specifying the package with the version).

I don't need help on how this will be done. I was just looking for confirmation of the name scheme, that the last 3 parts separated by "-" are not part of the name itself.

Skaperen 09-30-2013 10:49 AM

Quote:

Originally Posted by gnashley (Post 5037347)
If you are using bash, then simply:
PKG=full-name-version-arch-build #(with or without *.txz)
echo NAME=${PKG%-*-*-*}
You are correct, the separator is the '-' character and fields should be viewed from right to left. In other words, if you have a version number(or arch or build) with a '-' in them, then installpkg will be confused. Names can have any number of '-' chars in them as you like.

At this point in my code development I'm taking the full file name and coming up with just the versionless name. See my awk script. See the "rev|cut|rev" method it seems most everyone else uses. Do you have something that would be better?

ruario 09-30-2013 11:00 AM

Quote:

Originally Posted by NoStressHQ (Post 5037312)
Try using regular expressions instead of parsing the string with bare hands.

Quote:

Originally Posted by Skaperen (Post 5037331)
I could not figure out such an expression for this.

Here it is as a possible regex:

Code:

$ ls /var/log/packages | sed -r 's/^([[:graph:]]+)(-[[:alnum:]\.\+_]+){3}$/\1/'
EDIT: P.S. I checked and it gives the same result as the earlier command with rev:

Code:

$ diff -s <(ls /var/log/packages | rev | cut -f 4- -d "-" | rev) <(ls /var/log/packages | sed -r 's/^([[:graph:]]+)(-[[:alnum:]\.\+_]+){3}$/\1/')
Files /dev/fd/63 and /dev/fd/62 are identical


GazL 09-30-2013 11:13 AM

This is what I use in one of my scripts. It generates a list of available packages using the following approach
Code:

gazl@ws1:~$ function reformat_available() {    sed -e 's:^\(.*/\)\(.*\)-\([^-]*\)-\([^-]*\)-\([0-9]\+\)\(.*\)\(\.t.z\)$:\2 \2-\3-\4-\5\6 \1\2-\3-\4-\5\6\7:'; }
gazl@ws1:~$ find /local/slackware/slackware64-current/slackware64/ -name "*.t?z" | sort | reformat_available

The output is formatted into 3 fields: base package name, versioned package name and the full filepath of the package on disk.

If you want to look-up a specific package it's just a case of tightening the grep using the appropriate anchors.
Code:

gazl@ws1:~$ find /local/slackware/slackware64-current/slackware64/ -name "*.t?z" | reformat_available | grep sysvinit
sysvinit-functions sysvinit-functions-8.53-x86_64-2 /local/slackware/slackware64-current/slackware64/a/sysvinit-functions-8.53-x86_64-2.txz
sysvinit-scripts sysvinit-scripts-2.0-noarch-15 /local/slackware/slackware64-current/slackware64/a/sysvinit-scripts-2.0-noarch-15.txz
sysvinit sysvinit-2.88dsf-x86_64-3 /local/slackware/slackware64-current/slackware64/a/sysvinit-2.88dsf-x86_64-3.txz
gazl@ws1:~$ find /local/slackware/slackware64-current/slackware64/ -name "*.t?z" | reformat_available | grep "^sysvinit "
sysvinit sysvinit-2.88dsf-x86_64-3 /local/slackware/slackware64-current/slackware64/a/sysvinit-2.88dsf-x86_64-3.txz
gazl@ws1:~$


Lennie 09-30-2013 11:43 AM

You need to store all candidates in an array, and loop through them until you find the package you want.
A simple example to illustrate it:
Code:

$ pkgs=$(find . -name "sysvinit*")
$ echo ${pkgs[@]}
./sysvinit-2.88dsf-x86_64-2 ./sysvinit-functions-8.53-x86_64-2 ./sysvinit-scripts-2.0-noarch-13
$ for i in ${pkgs[@]}; do
> i=${i##*/}
> i=${i%-*-*-*}
> echo $i
> if [[ "$i" == sysvinit ]]; then
> echo "found it: $i"
> fi
> done
sysvinit
found it: sysvinit
sysvinit-functions
sysvinit-scripts
$


Skaperen 09-30-2013 12:27 PM

Quote:

Originally Posted by GazL (Post 5037372)
This is what I use in one of my scripts. It generates a list of available packages using the following approach
Code:

gazl@ws1:~$ function reformat_available() {    sed -e 's:^\(.*/\)\(.*\)-\([^-]*\)-\([^-]*\)-\([0-9]\+\)\(.*\)\(\.t.z\)$:\2 \2-\3-\4-\5\6 \1\2-\3-\4-\5\6\7:'; }
gazl@ws1:~$ find /local/slackware/slackware64-current/slackware64/ -name "*.t?z" | sort | reformat_available

The output is formatted into 3 fields: base package name, versioned package name and the full filepath of the package on disk.

If you want to look-up a specific package it's just a case of tightening the grep using the appropriate anchors.
Code:

gazl@ws1:~$ find /local/slackware/slackware64-current/slackware64/ -name "*.t?z" | reformat_available | grep sysvinit
sysvinit-functions sysvinit-functions-8.53-x86_64-2 /local/slackware/slackware64-current/slackware64/a/sysvinit-functions-8.53-x86_64-2.txz
sysvinit-scripts sysvinit-scripts-2.0-noarch-15 /local/slackware/slackware64-current/slackware64/a/sysvinit-scripts-2.0-noarch-15.txz
sysvinit sysvinit-2.88dsf-x86_64-3 /local/slackware/slackware64-current/slackware64/a/sysvinit-2.88dsf-x86_64-3.txz
gazl@ws1:~$ find /local/slackware/slackware64-current/slackware64/ -name "*.t?z" | reformat_available | grep "^sysvinit "
sysvinit sysvinit-2.88dsf-x86_64-3 /local/slackware/slackware64-current/slackware64/a/sysvinit-2.88dsf-x86_64-3.txz
gazl@ws1:~$


This is very close to what I want to do. But this is going to be something that repeats the search for all packages from a given list. So my idea is to generate the list that maps the non-version basename and version basename to full path just once and store that in a file. Then I can run grep to do the search ... many times.


All times are GMT -5. The time now is 04:45 AM.