Posts tagged 'bash'

CLI command to whitelist Composer packages

published on December 04, 2017.

James asked this question the other day on Twitter:

#LazyWeb is there a way to do a composer update of everything except a specific package or two? like `composer update --exclude doctrine/orm --exclude doctrine/dbal` or something? I don't want to have to whitelist everything all the time (there's bigger problems ofc)

Given that Composer has no --exclude flag or similar, the only other option is to create a list of packages we allow to be updated, excluding the ones we don’t want to be updated. We need to create a whitelist.

Creating it manually would be a PITA though, especially if there’s a lot of packages to include or exclude.

CLI to the rescue!

composer info | grep -v ^doctrine | sed 's/  \+/:/g' | cut -d: -f1 | paste -sd\ 

Note: There’s a single whitespace after the last backslash \.

This would result in a list of packages in a single line, something like:

beberlei/assert composer/ca-bundle container-interop/container-interop guzzlehttp/guzzle mockery/mockery

Let’s break it down

The composer info command shows information about the installed packages. The output is in the format of:

vendor1/package1      vx.y.z      Package 1 description
vendor1/package2      vx.y.z      Package 2 description
vendor2/package       vx.y.z      Package description

It’s all text so we can work with that.

The next step is to remove the packages we don’t want to be in our whitelist. We do that with grep -v ^package1 — search for and output anything that does not start with package1.

We are only interested in the vendor/package parts of the composer info output as that’s all we’ll need eventually for the composer update command.

When we have text that is formatted in columns, we can use the cut command to split these columns by a delimiter. There is a delimiter in the above output from composer info, but the delimiter is a varying number of whitespaces. That’s not really helpful.

What can we do now? Using sed we can replace those whitespaces to something that’s easier to use as a delimiter in cut, a colon : for example. sed 's/ \+/:/g' searches for two or more consecutive spaces and replaces them with a single : (not really visible, but the / \+/ part has two space characters between / and \).

The output at this point would look something like this:

vendor1/package1:vx.y.z:Package 1 description
vendor1/package2:vx.y.z:Package 2 description
vendor2/package:vx.y.z:Package description

Now we can use the cut command, tell it to use the colon as a delimiter with -d: and to take only the first field with -f1.

Finally, we use the paste command to merge lines together to get the final output. The s option is to merge horizontally and the d\ tells it to join using a single space character (again, it’s not really visible, but there is a single space character after the \ character).

Feel free to convert this one liner to a shell script that takes the package names as arguments so it’s a bit more reusable for future uses :)

Happy hackin’!

Tags: cli, shell, bash, composer.
Categories: Development, Software.

Automatically upload screenshots in XFCE4

published on February 13, 2012.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

XFCE4 has a nice little tool for making screenshots - xfce4-screenshooter. My only gripe with it is that it can’t automatically upload the images to a server and give me the URL to the image (to be honest, it can, but it uploads the images to a shady looking website, and I don’t like that). And then one day I saw Evan Coury’s GtkGrab - a set of scripts which does exactly what I want! But, sadly, that’s for Gnome. So, based on Evan’s work, I put together this little script:

#!/bin/bash
# based on GtkGrab by @EvanDotPro https://github.com/EvanDotPro/GtkGrab
function rename_file()
{
    NEWFILE=$(echo $1 | md5sum | cut -c-5)'.png'
}
REMOTE=user@domain.tld:/home/user/screens/
DOMAIN=http://i.domain.tld/
LOCALPATH=/home/user/Pictures/screenshots/
xfce4-screenshooter -r --save=$LOCALPATH
LOCALFILE=$(ls -tr $LOCALPATH | tail -n 1)
rename_file $LOCALFILE
I=0
LIMIT=10
while [ "$I" -lt "$LIMIT" -a -f "$LOCALPATH$NEWFILE" ]
do
    rename_file $NEWFILE
    I=`expr $I + 1`
done
mv "$LOCALPATH$LOCALFILE" "$LOCALPATH$NEWFILE"
scp "$LOCALPATH$NEWFILE" "$REMOTE$NEWFILE"
echo "$DOMAIN$NEWFILE" | xclip -selection clipboard
notify-send "Screenshot uploaded, URL in clipboard"

Save this script somewhere on your computer, configure the DOMAIN, LOCALPATH and REMOTE variables, set the script to be executable and then create a shortcut combination for it via Settings -> Keyboard -> Application Shortcuts. Programs you’ll need to have installed for this to work are xfce4-screenshooter, xclip and notify-send. If you don’t want to be prompted for the password/passphrase for the scp command each time, set up a passwordless login for your user on your remote server.

Happy hackin’!

Notes on shell scripting

published on December 29, 2011.
Heads-up! You're reading an old post and the information in it is quite probably outdated.

Yesterday I did some shell scripting and thought about writing down the few things learned along the way. Amazing how little needs to be done to learn a lot :)

Result of a command to a variable

First thing I learned is how to “save” the result of a shell command to a local variable:

PHP_BINPATH=$(which php)

By enclosing the command in parenthesis and putting a dollar sign in front of it, will put the result of that command in the variable.

An empty variable

Turns out, a variable can be empty, null. Nothing strange with that, until one tries to do something with that variable. For example:

PHP_BINPATH=
if [ $PHP_BINPATH == "foo" ]
  then
    echo "It's foo"
fi

will die with a strange error: “line 2: [: =: unary operator expected”. Problem is that when evaluating it will see if [ == “foo” ] and turns out [ is some reserved command or some such. The fix is to wrap $PHP_BINPATH in double quotes:

PHP_BINPATH=
if [ "$PHP_BINPATH" == "foo" ]
  then
    echo "It's foo"
fi

Pass all the arguments!

When calling some other command from within the shell script, and all the arguments which are passed to the shell script need to be passed to that other command, use ”$@” for that:

$PHP_BINPATH usher.php "$@"

This will pass all the arguments to the PHP script which is called from within the shell script.

Happy hackin’!

Robert Basic

Robert Basic

Software engineer, consultant, open source contributor.

Let's work together!

If you require outsourcing or consulting help on your projects, I'm available!

Robert Basic © 2008 — 2019
Get the feed