Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Portage Configuration File Editor
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
nihilo
Apprentice
Apprentice


Joined: 05 Nov 2002
Posts: 168
Location: berkeley, ca, usa

PostPosted: Wed May 21, 2008 5:48 am    Post subject: Portage Configuration File Editor Reply with quote

Here's a little script to edit the portage files in /etc/portage. Instead of

Code:
echo '=app-misc/foo-bar-0.1-r1' >> /etc/portage/package.keywords


You can do:

Code:
pa '=app-misc/foo-bar-0.1-r1' keywords


It saves a few keystrokes, but the main reason I made the script is so that I can safely allow a non-root user to do that (you can't give sudo privileges for echo), and so that I don't have to worry about forgetting a '>' and accidentally overwriting the file (yeah, I back them up, but I still might lose some changes since last backup).

Anyway, I hope this is of use to somebody else as well. Maybe there's an app in portage that does something like this, but I didn't see one when I searched. Thus the script.

I've used it for a few weeks, and it has yet to erase my hard-drive or blowup my machine, but YMMV and all that...

Edit: removed license from comments (BSD3).

Code:
#!/bin/sh

PROG="$(basename $0)"
PORT_CONF_DIR="/etc/portage"

usage() {
    cat <<EOF
NAME

    $PROG

LICENSE

    BSD3

SYNOPSIS

    $PROG -h | --help
    $PROG -e | --edit FILENAME+
    $PROG -a | --append "configuration line" FILENAME+
    $PROG -g | --grep "REGEX" FILENAME*

DESCRIPTION

    $PROG allows non-root admin users to edit and search the portage
    configuration files in $PORT_CONF_DIR.

OPTIONS

    -h, --help
        Display this help message.

    -e, --edit FILENAME+
        Edit one or more portage configuration files in $PORT_CONF_DIR.

    -a, --append CONFIG_LINE FILENAME+
        Append a single line of configuration text to one or more
        portage configuration files in $PORT_CONF_DIR.
        Be careful to quote CONFIG_LINE if necessary.

    -g, --grep REGEX FILENAME*
        Perform a search for the given extended regular expression in each
        FILENAME given. If no FILENAME is given, the search is performed
        on all files in the $PORT_CONF_DIR directory.
        Be careful to quote REGEX if necessary.

    FILENAME is always the name of a file in the $PORT_CONF_DIR
    configuration directory, NOT the full path to the file.

    If you use the append option, a backup of the file is made before
    appending to it. The backups go in $PORT_CONF_DIR/bak, which is created
    if necessary, and the file will have the same name with an additional
    extension of .old (e.g., $PORT_CONF_DIR/package.keywords will be backed up
    to $PORT_CONF_DIR/bak/package.keywords.old).

EXAMPLES

    $PROG -e package.keywords
        Edit the package.keywords file.

    $PROG -e package.unmask package.keywords
        Edit the package.unmask and package.keywords files.

    $PROG -a "=app-portage/vim-7.1.285" package.keywords
        Append "=app-portage/vim-7.1.285" to the package.keywords file.

    $PROG -a "x11-libs/cairo" package.unmask package.keywords
        Append "x11-libs/cairo" to both package.unmask and package.keywords.

    $PROG -g "cairo"
        Search all files in $PORT_CONF_DIR for the literal 'cairo'.

    $PROG -g "gcc|glibc" package.unmask package.keywords
        Search package.unmask and package.keywords for the given
        extended regex, which matches each line that contains either
        'gcc' or 'glibc'.

NOTES

    The purpose of this script is to make it easy to edit portage conf
    files in a reasonably secure manner as a non-root admin user via sudo.

    The root user can do things like

    $ echo 'x11-libs/cairo' >> $PORT_CONF_DIR/package.keywords

    in order to easily add a line to a portage configuration file, but
    non-root users can't do this, and you can't give sudo privileges for
    echo to a user without allowing them to overwrite anything (effectively
    making them root). Thus this script!

    The script should be saved somewhere that is on the PATH of all users,
    like /usr/local/bin, and it should have 755 permissions, so that no-one
    but the root user can edit it but all users can execute it.

    Using the --grep option works for all users and requires no further
    configuration.

    Using the --append option requires that you give the invoking user
    sudo privileges for this script.

    Using the --edit option requires that you additionally give the invoking
    user sudoedit privileges for each of the files in $PORT_CONF_DIR.

    For example, use the following (removing leading whitespace on the first line)
    to allow only appending to files by any user in the wheel group (without
    entering a password):

        %wheel          ALL=NOPASSWD: /usr/local/bin/$PROG

    And use the following to allow any user in the wheel group to both append
    to or edit portage configuration files:

        %wheel          ALL=NOPASSWD: /usr/local/bin/$PROG, \\
                                      sudoedit $PORT_CONF_DIR/package.keywords, \\
                                      sudoedit $PORT_CONF_DIR/package.use, \\
                                      sudoedit $PORT_CONF_DIR/package.unmask, \\
                                      sudoedit $PORT_CONF_DIR/package.mask

ALIASES

    You may find it helpful to define the following aliases for the user that
    will use this script:

    alias pa="sudo $PROG --append"
    alias pe="sudo $PROG --edit"
    alias pg="sudo $PROG --grep"
    alias ph="sudo $PROG --help"

    Unmasking and adding a package to package.keywords is then as simple as:

    pa x11-libs/cairo package.unmask package.keywords

SHORTCUTS

    This script also understands some shortcuts for filenames. On each of the
    following lines, the term on the left side can be used instead of the
    term on the right side:

    keywords  ->  package.keywords
    use       ->  package.use
    unmask    ->  package.unmask
    mask      ->  package.mask

EOF
}

# Print an error message to stderr.
err() {
    echo "$*" 1>&2
}

# Expand one or more filenames into the full path to that
# file in $PORT_CONF_DIR, failing if any path contains a slash,
# returning 0 on success and 1 on failure.
expandportageconfpaths() {
    if [ $# -eq 0 ]; then
        echo ""
        return 0
    fi
    conf_dir="$PORT_CONF_DIR"
    fullpaths=""
    for filename in $@
    do
        if expr match "$filename" ".*\/.*" > /dev/null ; then
            err "Invalid filename (contains '/'): $filename"
            err "File arg should be something like 'package.keywords'"
            return 1
        fi
        case "$filename" in
            keywords) full_filename="package.keywords" ;;
            use)      full_filename="package.use"      ;;
            unmask)   full_filename="package.unmask"   ;;
            mask)     full_filename="package.mask"     ;;
            *)        full_filename="$filename"        ;;
        esac
        fullpaths="$fullpaths $conf_dir/$full_filename"
    done
    # return the fullpaths without the extra initial space
    echo "$fullpaths" | cut -c 2-
    return 0
}

# Edit the configuration file(s) in $PORT_CONF_DIR given by the arguments
# using sudoedit. The arguments given should be just the filename,
# like "package.keywords", rather than the full path.
editconfs() {
    if [ $# -lt 1 ]; then
        err "Usage: editconfs FILENAME+"
        return 1
    fi
    filepaths="$(expandportageconfpaths $@)"
    if [ $? -ne 0 ]; then
        err "Error expanding filenames. Exiting."
        return 1
    fi
    # Open and edit the files one at a time, because I'm not sure that all
    # editors will be able to open multiple files in one process correctly.
    for filepath in $filepaths
    do
        # Run sudoedit via su as the SUDO_USER so that it is SUDO_USER
        # that is required to have edit privileges on the file rather
        # the root user that we are currently running as.
        su -c "sudoedit '$filepath'" ${SUDO_USER}
    done
    return 0
}

# Append a line given by $1 to the configuration file(s) in
# $PORT_CONF_DIR given the arguments after $1. The filename arguments
# should include just the filename, like "package.keywords",
# rather than the full path. The line to be added does not need to
# be terminated with a newline character, as it will be added automatically.
#
# Before appending to a file, the file will be backed up to a file with the same
# name plus ".old" in  $PORT_CONF_DIR/bak, which will be created if necessary.
appendconfs() {
    if [ $# -lt 2 ]; then
        err "Usage appendconfs \"line of conf text\" FILENAME+"
        return 1
    fi
    bak_dir="$PORT_CONF_DIR/bak"
    appendline="$1"
    shift
    filepaths="$(expandportageconfpaths $@)"
    if [ $? -ne 0 ]; then
        err "Error expanding filenames. Exiting."
        return 1
    fi
    [ -d "$bak_dir" ] || mkdir -p "$bak_dir"
    if [ $? -ne 0 ]; then
        err "Unable to create backup dir. Exiting."
        return 1
    fi
    for filepath in $filepaths
    do
        if [ -f "$filepath" ]; then
            bak_path="$bak_dir/$(basename $filepath).old"
            cp -f "$filepath" "$bak_path"
        fi
        echo "$appendline" >> $filepath
    done
    return 0
}

grepconfs() {
    if [ $# -lt 1 ]; then
        err "Usage: grepconfs REGEX FILENAME+"
        return 1
    fi
    grep_pat="$1"
    shift
    case $# in
        0)  # search all: include filename in results
            grep -H -E --color=always "$grep_pat" $PORT_CONF_DIR/package.*
            ;;
        1)  # search just the one file: no filename in results
            grep -h -E --color=always "$grep_pat" $(expandportageconfpaths $@)
            ;;
        *)  # search multiple filepaths: include filename in results
            grep -H -E --color=always "$grep_pat" $(expandportageconfpaths $@)
            ;;
    esac
    return $?
}

if [ $# -eq 0 ]; then
    usage
    exit 1
fi

case "$1" in
-h | --help)
    usage
    exit 0
    ;;
-a | --append)
    shift 1
    appendconfs $@
    exit $?
    ;;
-e | --edit)
    shift 1
    editconfs $@
    exit $?
    ;;
-g | --grep)
    shift 1
    grepconfs $@
    exit $?
    ;;
*)
    usage
    exit 1
    ;;
esac


Last edited by nihilo on Wed May 21, 2008 4:12 pm; edited 1 time in total
Back to top
View user's profile Send private message
anxt
Apprentice
Apprentice


Joined: 25 Feb 2003
Posts: 251
Location: Frozen Tundra, Canada

PostPosted: Wed May 21, 2008 7:30 am    Post subject: Reply with quote

Wow, that is documented and commented thoroughly. Not sure I will use it but good on all the comments. I don't even begin to understand licenses, they are more cryptic to me than perl!
Back to top
View user's profile Send private message
nihilo
Apprentice
Apprentice


Joined: 05 Nov 2002
Posts: 168
Location: berkeley, ca, usa

PostPosted: Wed May 21, 2008 4:11 pm    Post subject: Reply with quote

anxt wrote:
Wow, that is documented and commented thoroughly. Not sure I will use it but good on all the comments. I don't even begin to understand licenses, they are more cryptic to me than perl!


The license is just plain BSD, which I cut and pasted. It basically says you can do anything you want with it, and I'm not responsible, I think.

Actually, I'll remove it from here, because stuff here doesn't seem to have a license usually. I just copy-pasted it from my website, where a license is helpful for anybody who comes across it from google and wants to know if they may take it.
Back to top
View user's profile Send private message
DanPT
n00b
n00b


Joined: 16 Nov 2007
Posts: 14

PostPosted: Thu May 22, 2008 5:39 am    Post subject: Re: Portage Configuration File Editor Reply with quote

nihilo wrote:
Hi[...] Maybe there's an app in portage that does something like this, but I didn't see one when I searched. Thus the script.


I just use flagedit 8)

http://gentoo-wiki.com/Flagedit
http://damz.net/flagedit/

Great tools for quick USE and Keywords change, global and package specific.
Back to top
View user's profile Send private message
nihilo
Apprentice
Apprentice


Joined: 05 Nov 2002
Posts: 168
Location: berkeley, ca, usa

PostPosted: Thu May 22, 2008 4:11 pm    Post subject: Re: Portage Configuration File Editor Reply with quote

DanPT wrote:
I just use flagedit 8)


I use flagedit too for editing use flags, but unless I'm mistaken, it doesn't provide the other functionality my script provides: manipulating the package.unmask and package.mask files.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum