Speedpills 4 Linting PHP Files in Parallel

B1x9217x1428-gimp

Quite some time ago I’ve already written about linting PHP files in the shell / build.

Even though parallel linting is fine, when the code-base is growing larger and larger, the build becomes slower and slower. A slow build sucks.

Git to the Rescue

One easy way to speed things up again is by reducing the number of files. So instead of linting all PHP files in directories, only linting the files that recently changed is a power-up.

For example if working with topic branches (e.g. bug-fixes or features) and having a main branch where changes are normally merged in (e.g. develop or master) the list of files to lint can be generated by listing all file-names changed (modified, added, deleted, …) between HEAD and the target branch (e.g. develop or master).

Let’s consider working on a topic-branch while having it checked out (HEAD) and the target branch is develop.

git log --no-decorate --pretty=format: --abbrev-commit \
        --no-merges --first-parent --name-only develop..

Explainshell

The output is not yet totally useful. First of all it contains empty lines but also deleted files. And it contains all files, when the change log was edited it will be also listed next to the php files interested for linting. And as this can span easily over multiple commits, files can be duplicated.

The answer to that are filters in the shell.

Streams all the Way Down

The first filter is to reduce the list already by file extension. Here is a filter w/ sed letting only pass .php and .phtml files:

sed -n '/\.ph\(p\|tml\)$/p'

Explainshell

Next is to remove the duplicates (if any), sort is suitable here:

sort -u

Explainshell

Last but not least only existing files (not the deleted ones) must be passed to PHP for linting as otherwise it would rightfully error out.

I had to crack a bit on this one as in my mindset there is a lot of find when it is about finding files, but this time there is no find. What I came up with is ls as it does no output (just errors) when a file (or directory) does not exists. With xargs it is easy to provide multiple arguments to ls at once so that there is not so much to spawn.

xargs ls -f1 -- 2>/dev/null

Explainshell

This ensures to only list existing files, one per line, and the error output goes to /dev/null. So the full filter first removes any files of unfitting type (sed), any duplicates (sort) and non-existing files (xargs, ls):

sed -n '/\.ph\(p\|tml\)$/p' \
  | sort -u | xargs ls -f1 -- 2>/dev/null

Explainshell

This then only needs to get wired up to the existing parallel lint command which is xargs to do the parallelism, php for linting and grep to detect any error (see as well the older blogpost).

But before taking a look at the command as a whole, as this is not so much about having it run far away like on Travis CI last time, let’s consider that not all changes are yet staged nor committed. So next to listing the files changed since branching from develop, there are also all the files currently dealing with:

    git diff --cached --name-only
    git diff --name-only

Explainshell

To wrap this all up a shell compound-list in curly brackets is handy to execute it in process.

  { git log --no-decorate --pretty=format: --abbrev-commit --no-merges --first-parent --name-only develop..
    git diff --cached --name-only
    git diff --name-only
  } | sed -n '/\.ph\(p\|tml\)$/p' \
    | sort -u | xargs ls -f1 -- 2>/dev/null \
    | 2>/dev/null xargs -n1 -P8 php -n -d short_open_tag=0 -l \
    | grep -v '^No syntax errors detected'

Exit status 1 means success, any other status a lint failure (requires set +e as in the earlier post).

Regardless how large the overall code-base is, this keeps linting speed fast. Especially for the local build.B1x9217x1428-gimp.png

Advertisements
Posted in Hakre's Tips, PHP Development, PHP Development, Pressed, Scripts, Tools, Uncategorized | Tagged , , , , , | Leave a comment

Sed Cheatsheet

Just a post about some of the sed lines I find scattered, to be extend in future edits.

Merge same Lines Together

$ sed '/^ \*$/{h;d};{H;s/.*//;x;s/^\n//}'

This sed example merges all “ *” lines that follow each other (e.g. empty lines in a class level Docblock comment in a PHP file). The pattern can be replaced with any pattern to describe the lines to merge together.

It copies each matching line into the hold buffer and drops the line.

On any other non matching line, the line is appended to the hold buffer, the read buffer emptied and exchanged w/ the hold buffer (clearing the hold buffer), any starting newline removed from the pattern space (as appending to an empty hod buffer would have created it but it’s unwanted).

Limitations: Won’t work when line pattern matches the last line / GNU sed

Indent all but first line

$  | sed '1{p;d}; s/^/  /'

1 applies to first line only, p prints and d deletes so there is no continuation to the second expression in which s searches for ^ start of line to replace it with two spaces. ; separates expressions, { and } group them.

switch -e has been left out.

Similar to

$  | sed '1p; 1d; s/^/  /'
Posted in Hakre's Tips, Uncategorized | Tagged | Leave a comment

Gnome Shell Quickfix Cheatsheet

Disable work-space up/down movers which block key bindings I use in Phpstorm. Important with that is that I don’t use these dynamic work-spaces at all, so making them static and only one:

dconf write /org/gnome/desktop/wm/preferences/num-workspaces 1
dconf write /org/gnome/mutter/dynamic-workspaces false
dconf write /org/gnome/desktop/wm/keybindings/switch-to-workspace-up "['disabled']"
dconf write /org/gnome/desktop/wm/keybindings/switch-to-workspace-down "['disabled']"

Just in case for restoring needs, these were my previous values (where not obvious):

switch-to-workspace-up=['<Control><Alt>Up']
switch-to-workspace-down=['<Control><Alt>Down']

More reference on searching for keyboard bindings on the command line is outlined in Hunting the Keyboard Shortcut (Dec 2018).

Posted in Hakre's Tips, Uncategorized | Tagged , , , , , | Leave a comment

Git – Set the Author Date to The Committer Date of a Recent Commit

hakre-git-committer-date-git-gone-1

Ah gosh that one commit has the author date just too far off, but if it
would be the same as the committer date, that would be fine…

  1. Locate the commit when rebase interactively and mark for edit. Then
    go there to edit [1].
  2. Extract and export that commits committer date as GIT_COMMITTER_DATE
    $ export GIT_COMMITTER_DATE="$(git log --format=%cD -1)"
  3. Amend w/ the author date then set to the committer date while preserving it via the exported environment parameter (variable)
    $ git commit --amend --date="$GIT_COMMITTER_DATE" -C HEAD
  4. Unset the GIT_COMMITTER_DATE
    $ unset GIT_COMMITTER_DATE
  5. Continue the rebase to finish
    $ git rebase --continue

hakre-git-committer-date-git-gone-2

[1] A date/time related intro to interactive rebase is also given in Change the date of a git commit (by Hugo Di Francesco; Aug 2018), the whole story in the git manual on interactive rebase which is always worth the read.

Images motive based on a visual excerpt from a TV series episode named “git gone” which is also the imaginary product name, the further text reads “kills bugs on contact” on the spray can label.

Posted in Hakre's Tips, Pressed | Tagged | Leave a comment

Install / Update Dbeaver Community on Ubuntu

Update: Turns out I was too eager to get the command line running. While it’s fine to have it perhaps for some systems, it is actually the case that Dbeaver has both a Debian repository and an Unbuntu PPA as I just learned:

sudo add-apt-repository ppa:serge-rider/dbeaver-ce
sudo apt-get update
sudo apt-get install dbeaver-ce

It’s all on the download page [2] and all you need is to have the patience to scroll down (or Ctrl+F).

Highly recommended as there are updates often, it’s perhaps worth to schedule the downloads in the background as the repository can be slow.


 

I recently started to use Dbeaver [1] on my Ubuntu system. It gets updated quite seriously and luckily there are releases with .deb packages, so the package manager can install and update them. And there is an URL redirecting always to the lastest version.

So her is my current state of the one-liner to run the upgrade when I get noticed:

$ sudo apt install "./$(
    curl -O "$(
      curl -sL -I -w '%{url_effective}' \
        https://dbeaver.io/files/dbeaver-ce_latest_amd64.deb \
    | tail -1 )" -w '%{filename_effective}'
  )"

Standard disclaimers apply, verify checksums and the yadda yadda, otherwise, you know, install as root from the internet has never let you down than once.

[1] https://dbeaver.io/

Posted in Hakre's Tips, Tools, Uncategorized | Leave a comment

Hunting the Keyboard Shortcut

Recently while in the mood I decided to upgrade my Thinkpad X280  from Ubuntu 16.04 LTS (for which it had the approval) to more current Ubuntu 18.04 LTS.

That also meant that I’m back on Gnome Shell which I’m not really a fan of, I was able to get my hands dirty on it when I was using Fedora a lot and it was new (“Gnome 3”) and well, I found it a bit rough.

However for the UI now – that is some years later – as it has been tailored for the Ubuntu flavor I find it quite acceptable (not because of Ubuntu but just the package is fine). I merely had some issues with the Laptop on Ubuntu 18.04 which most likely are not exactly related to Ubuntu 18.04 in specific, I’d like to write down about in this blog post:

ThinkPad Pro Docking Station with ThinkPad X280 on Ubuntu 18.04

First of all with the Lenovo ThinkPad Pro Docking Station (the USB-C one where you put the Laptop into and the USB-C docks from the left) I have in use there were some problems with my USB Keyboard on the docking station – it was just not enabled. This can be checked if it has a Num Lock LED and pressing Num Lock should toggle the light on and off. If you’ve got a keyboard with Num Lock LED at least in desktop mode this is a good check, while booting this is no check at all because there is no Num Lock LED going on, at least not for me. Apart from input devices via USB (I only have input devices on the dock at boot time normally) everything else worked with the docking station out of the box: Video via VGA port and Ethernet adapter.

It took me quite some time until I learned about having some BIOS settings influencing USB connectivity at boot time. Right now it works since some days in an acceptable manner (boot within dock and outside, suspend, take out, use out, suspend, put in etc.) and two BIOS settings I could identify I need to have for this working:

  1. Config / Thunderbolt (TM) 3 / Security Level: “No Security” (while having the Thunderbolt(TM) device “Disabled” for support in Pre Boot Environment)
  2. Config / USB / USB UEFI Bios Suppport: “Enabled”

As it was quite a bit of change here change there, this is perhaps not all settings, but I was using these. There is a warning to not enable a specific Linux one (which I had enabled to try it but disabled it quickly again as it is reported to brick Thinkpads on change (!)) and quite some users are reporting problems with the docking station regarding video which never was an issue for me from the beginning.

From my subjective impression, it was more an out-of-the-box experience while on Ubuntu 16.04, but it might be just since I upgraded the OS I perhaps wanted to finally get this into order, so this might be useful regardless of which Ubuntu version (or the underlying Kernel version).

Hunting the Keyboard Shortcut in the Dconf

While it was not enough to have actual keyboard connectivity problems (which really suck as the X280 has only one USB port left for use when in the dock, so I could only have mouse or keyboard working) with the Ubuntu upgrade to 18.04 I even “lost” one of the main keyboard shortcuts you have in browsers / editors / programming: CTRL+F to find in page / document / editor.

Finally I found a way to trouble-shoot this quickly, it works for any system that supports the dconf utility. With dconf dump it is possible to search for keyboard shortcut sequences, in my case CTRL+F is a “f” there, it can be quickly (and case independently) searched for:

$ dconf dump / | grep -i 'f'
move-to-workspace-9=['f']

Finally I could locate the culprit. Finding out under which configuration path needs a sed filter with a little “program” (examples of case insensitivity and hold buffer):

$ dconf dump / | sed -n '/^\[.*\]$/h;/f/I{x;p;x;p}'
[org/gnome/desktop/wm/keybindings]
move-to-workspace-9=['f']

It then shows the path to the setting above the match. The rest was merely straight forward to edit out that keyboard shortcut which I have no idea at all how it ended in there:

$ dconf write /org/gnome/desktop/wm/keybindings/move-to-workspace-9 "['disabled']"

I don’t know how I was finally able to check that one, I actually was trying out the Ubuntu Keyboard Shortcuts Troubleshooting guide in the Wiki which made a good impression to me as it allowed me to check if/what is actually working with my keyboard, however it’s more on the event level which turned out working for me. And then I needed to look further and with one of many shattered Stackoverflow postings, eventually another time the hint on Dconf Editor and that it has Keyboard Shortcut configuration “somewhere there” did let me fiddle with searching within the shell.

In my opinion a recommended utility to install on Ubuntu 18.04 LTS when using the Gnome Shell for sure is “gnome-tweaks” also known as Tweaks or Gnome Tweaks Tool.

Posted in Hakre's Tips | Tagged , , , , , , , , , | Leave a comment

Compile ripgreg (rp) on Ubuntu 16.04 LTS

Just a quick note to myself on how to compile the insanely fast rg utility from git sources w/ AVX and SIMD activated.

  1. Clone from sources: git clone git@github.com:BurntSushi/ripgrep.git --depth 1 && cd ripgrep
  2. Install rustup to be able to compile against nightly Rust releases: curl https://sh.rustup.rs -sSf | sh
  3. Enable the nightly rust release for the ripgrep project: rustup override set nightly
  4. Compile: ./compile
  5. The new binary can be found run from ./target/release/rg

Shell installer are quite fishy, so this is not the preferred way of installation, there is also the possibility to directly install it via (packaged) cargo command (cargo install ripgrep) but that version is w/o AVX/SIMD as both can not compile (currently) with the stable Rust version.

Additionally there is a home-/ linux- brew based installer, but I have not tried it.

References:

Posted in Uncategorized | Tagged , , , | Leave a comment

Using Assertions with (Legacy) PHP Code

hakre-pantheon-preserveWhile it was not much advised to use assertions (the assert PHP language construct) prior to PHP 7 due to the fact that it actually eval’ed a string’ed code, these days are gone. This is probably a lesser known fact with all the other immense improvements PHP 7 and 7.1 came with, so I’d like to take the opportunity with this post to highlight the PHP assertion feature that comes with zero run-time overhead and zero side-effects for production code. Continue reading

Posted in Developing, Hakre's Tips, PHP Development, PHP Development, Pressed, The Know Your Language Department, Tools | Tagged , , , , , , , | Leave a comment

Lazy Loading in PHP Object Composition

When it comes to nicely performing PHP scripts (yes in PHP these are all scripts as PHP code is run-time) there is a nice addition since PHP 7 named the Null coalescing operator which plays very well with the basic nature that PHP is loosely typed and unset variables are basically null when warnings are not in effect. You know what? Not set warnings (like with isset) are not in effect with the  ?? Null Coalescing Operator (PHP Manual).

So how about a simple and quick usage example for lazy-loading? By default all class members are null when defined:

class MyFoo
{
  /**
   * @var Config
   */
  private $config;
}

With any new MyFoo() that private property will be null. Now one thing could be to properly inject the Config in the constructor (__construct()) but while you’re writing code you might want to defer the details to later (dependency injection is not always useful but don’t get me wrong it’s generally the option to go on with constructor injection while you progress) one way to deal with the outcome is lazy loading (back to constructor injection, you might want to inject a ConfigFactory then).

So what is about lazy loading here? Let’s say MyFoo is used more centrally in an application (a primitive)  so might be some kind of service to your application, you only want to instantiate the Config in case it is actually used. You know that it is used when it is acquired from the service-like-acting MyFoo when the getter is called (mind the Law od Demeter and Getters and Setters can be a smell, too):

class MyFoo
{
    ...
    public function getConfig(): Config {
        return $this-&gt;config;
    }
}

Now when that getConfig() method is called, it will return null unless the Config has been set to private MyFoo::$config so far – which is not a case in our scenario. Also the Config of MyFoo is a singleton (not the (anti-) pattern) , so it is easy to implement it on the go:

class MyFoo
{
    ...

    public function getConfig(): Config {
        return $this-&gt;config ?? $this-&gt;config = new Config();
    }
}

Creating the Config object is here deferred to the point when getConfig() is called the first time. That is also the first time it is needed (by definition of this simplified example at least). The Null Coalescing Operator is helpful here to do this in a single line.

It is also easy to switch to constructor injection (eager loading) or even constructor injection based lazy loading when you inject a factory that will create (or a repository that providea) the Config at that time in place.

I hope this is a nice example to show how well the Null Coalescing Operator in PHP plays with non-initialized object properties (or even unset variables). Which reminds me I should not use it too often.

In the next PHP version (7.2) this can be shortened even more btw (see the PHP RFC: Null Coalescing Assignment Operator):

class MyFoo
{
    ...

    public function getConfig(): Config {
        return $this-&gt;config ??= new Config();
    }
}

The only thing missed for ?? addicts like me might be the sometimes unnecessary operand after the operator:

    $var = $unset ??; # expressing just null

This will spare isset() if conditionals but might also direct dealing with nulls to other places (which can add a lot of burden to consumers). But I’m just too little experienced in writing PHP wiki RFCs and I couldn’t even provide a patch, so with closing time for PHP 7.2 this is really future material (and perhaps just a sign I want “wrong” things).

/Edit: An RFC exists already: PHP RFC: Unary null coalescing operator


Read On:

Posted in Hakre's Tips, PHP Development, PHP Development, Pressed, The Know Your Language Department, Tools | Tagged , | Leave a comment

Make any Composer Command Segfault

This is from the shock your co-worker department: There is an easy one-liner to make any composer based project spit “Segmentation fault (core dumped)” regardless of the Composer command entered: Continue reading

Posted in Bugs and Features, PHP Development, Pressed, Tools | Tagged , , | Leave a comment

History of the PHP date timezone settings warning

Elephant and Duck

Now with the newborn elefant PHP 7 in the herd, there is a lift on the date timezone settings warning: it has just been removed. That means, it’s now that you need to take care in the server’s configuration that the proper default timezone value is set, otherwise it will fall-back to UTC with no more reminder spamming the log-files or screen. Alternatively, you can make use of the date_default_timezone_set() function within your application to configure the default value.

Continue reading

Posted in Pressed, The Know Your Language Department | Tagged , , , | Leave a comment

Linting PHP Files in Parallel on Travis

php-lint-travis-krita

With PHP 7 around the corner here is a small tip how you can at least lint the code in your project to be PHP 7 syntax compatible. That allows you to easier obtain forward-compatible PHP code with ease. So if you already integrate with Travis, all you need to do is to add some two-to-four lines to your .travis.yaml file and you’re done. Here is how: Continue reading

Posted in Hakre's Tips, PHP Development, Pressed, Tools | Tagged , , , , , , , , | Leave a comment

The SimpleXMLElement Magic Wonder World in PHP

PHP’s Simplexml ships with a lot of magic to simplify access to an XML documents element and attribute node values. Some criticize this and suggest to use the DOM library instead. The DOM library on the other hand, even it can do everything tend to be known with an XML document, it’s pretty verbose – and yes that’s some critique with XML as well, the verbosity. Sure there are many nice libraries around the DOM library and wrapping it and one of these libraries again is Simplexml.

From a data-type perspective, the SimpleXMLElement is quite an interesting one actually, literally I mean figuratively -what not. It’s something like a hierarchical data-structure. One that comes with it’s own query method via the xpath() method. It can be iterated, traversed, nodes added and leafs unset as if it would be an array or an std class. And it comes with a serializer built in – into XML – in both directions.

From it’s internals, it’s fully backed from C code below from libxml, it’s also pretty fast and perhaps also fine with the memory (at least I hope).

It speaks Unicode in the popular UTF-8 encoding you know from the web and if you need to, it can even convert to other encodings.

And one of it’s magic properties is that it’s such a class of classes in PHP that can be casted from one class to another. This works by converting one (subclass of a) SimpleXMLElement to another subclass of it by sending it through DOM (the besaid sister-library):

$foo  = new Foo("<doc/>");
$via  = dom_import_simplexml($foo);
$cast = simplexml_import_dom($via, 'Bar');
var_dump(get_class($cast)); # string(3) "Bar"

This is actually not only true for SimpleXMLElement but also to the node-classes in a DOMDocument to a certain degree but this post is about SimpleXMLElement so just saying.

I have to say it: With so much simplification and magic, there is a price to pay and there are limitations, too. The constructor is final, so you can’t override it. No way :). This hinders you in terms of “classic” object inheritance. One path out is to decorate the elements, but even I did this in the past, it doesn’t feel equally well as well. It might also be more work as first thought. But most often, extending SimpleXMLElement just more to sugar-in some methods, so it’s often not worth for a full-feature decoration. So this is a limitation. ERR_TOO_MUCH_MAGIC comes to mind.

And some argue as for the data-structure you can’t use it as array or object store as all class-properties or array-indexes represent either XML element or attribute nodes only accepting scalar types (actually stringy values).

Storing Arrays and Objects in a SimpleXMLElement

Let me elaborate on that last point a little. It’s normally not possible to store array or object data inside a SimpleXMLElement. As you couldn’t serialize it as XML, by default it’s fordidden to do:

class Foo extends SimpleXMLElement
{
}

$foo  = new Foo("<doc/>");
# Warning: It is not yet possible to assign complex types to properties
$foo->bar = $foo;

If you now think that creating a private field and assigning the data to the private field would be a solution, it will teach you about another limitation: there are no private fields with a SimpleXMLElement. It’s field are all exposed XML nodes so all you can store there are strings.

But wouldn’t it be nice to actually be able to store some objects therein? Let’s elaborate a bit on the internals which is how I discovered some nice properties of the document model in PHP and it’s use from within Simplexml.

The SimpleXMLElement is somewhat a shell around some other object only. It perhaps can be describben as a Flyweight (as in the pattern), an interface of factory and object manager of the underlying document nodes. And the document again can be represented as a DOMNode which again is a shell/interface around the underlying document node managed by libxml. This is the underlying structure of not only the SimpleXMLElements but also the tree structure of the DOM. The PHP SimpleXML/DOM extensions manage all these document nodes nicely for us.

If it is now possible to turn a SimpleXMLElement into a DOMNode it is then – because of the object model in PHP with the dynamic properties (every object in PHP is actually somewhat an array/hash) – possible to assing data to a document node without creating a new element as it would be the case on level of SimpleXMLElement:

class Foo extends SimpleXMLElement
{
    function setData($data) {
        $element = dom_import_simplexml($this);
        $element->data = $data;
    }
}

$foo = new Foo("<doc/>");
$foo->addChild('bar')->setData($foo);

This does actually work, but the data won’t yet persist. What is necessary to keep the dynamic property data here in memory within the DOM is to add as circular reference to the DOMNode, let’s call that one circref in this example. It’s then possible to write and read the data:

        ...

        function setData($data) {
            $element = dom_import_simplexml($this);            
            $element->data    = $data;
            $element->circref = $element;
        }

        function getData() {
            $element = dom_import_simplexml($this);
            return $element->data;
        }

        ...

The usage example demonstrates that it is now possible to store (or attach) an object to the document node accessed via Simplexml:

$foo = new Foo("<doc/>");
$foo->addChild('bar')->setData($foo);

var_dump($foo->bar->getData());

# class Foo#1 (1) {
#   public $bar =>
#   class Foo#2 (0) {
#   }
# }

For those who hate Simplexml but even read until here: As already written earlier, this same principle works with pure DOMDocument / DOMNode as well. Just in case you want to re-use the node based data-structure and you need to add (object) information to it. All you need is the circular reference to keep the association between the data and the node in memory. And it’s really within the same document:

# obtaining the data via DOMDocument
$doc = dom_import_simplexml($foo)->ownerDocument;

$bar = $doc->getElementsByTagName('bar')->item(0);
var_dump($bar->data);

As you can imagine same applies for xpath queries – both via DOMXPath or SimpleXMLElement.

Posted in Developing, Hakre's Tips, PHP Development, Pressed, The Know Your Language Department, Uncategorized | Tagged , , , , | Leave a comment

Kubuntu Default Browser

The system-settings don’t reflect the whole picture in Kubuntu. Settings can be done via the command-line. Here exemplary to chromium:

gvfs-mime --set x-scheme-handler/http chromium-browser.desktop
gvfs-mime --set x-scheme-handler/https chromium-browser.desktop

I had an issue with this for quite some time, I finally found the answer via “opening web link from evolution uses wrong browser”.

Posted in Hakre's Tips, Pressed, Uncategorized | Leave a comment

Installing PDF Printer under Kubuntu with AppArmor and Samba

It actually should be as little as installing cups-pdf (CUPS-PDF (Ubuntuusers German)):

$ sudo apt-get install cups-pdf

Then opening Printers in system preferences did show the new printer.

However printing a test-page didn’t work. I then just followed the tail of the syslog:

# tail -f /var/log/syslog

to find out that app-armor blocked something:

Feb  9 09:47:15 producer25 kernel: [43208.761736] type=1400 audit(1423471635.886:111): apparmor="DENIED" operation="connect" profile="/usr/lib/cups/backend/cups-pdf" name="/run/samba/winbindd/pipe" pid=14195 comm="cups-pdf" requested_mask="rw" denied_mask="rw" fsuid=0 ouid=0

With this error message at hand it was easy to find a bug-report which offered a solution that worked for me directly:

add this to your profile (in the cups-pdf section):

/run/samba/winbindd/pipe rw,

then do this:

$ sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.cupsd

After that I restarted cups.d and apparmor.d and it directly worked.

Printing the PDF

PDF files are stored under ~/PDF by default. If you print large files, it takes some time until the PDF file is written in full. Unless totally done, you (normally) can’t open it successfully. There is no notification given (like with compressing files for example) when the print job as been done and the PDF is fully written. There is also no temporary name. I didn’t look into the configuration of Cups-PDF deeply as I only wanted to get it to the run quickly, so just sharing the experiences, it’s probably worth a feature-request when I find the time.

Posted in Hakre's Tips | Tagged , , , | Leave a comment

Hide Folders in PhpStorm Project Pane

How can I hide a directory in a PHPStorm project, for example .sass-cache I just asked myself this morning.

Searching online didn’t reveal it to me and there are numerious options that were close but not about hiding the directory from the project panel.

Finally a co-worker pointed me into the right direction, there are two things to do under circumstances:

  1. Exclude the directory: Mark the directory itself as excluded (Right-Click -> Mark Directory As -> Excluded). It might then already disappear
  2. Hide excluded files: Tick the project pane option (under the Gear-Wheel symbol) and un-tick Show Excluded Files to hide excluded directories

and that’s it.

However: Showing the .idea folder doesn’t work this way (WI-26391).

Posted in Developing, Hakre's Tips, Pressed | Tagged | Leave a comment

Just linked: Learning OOP in PHP

Link | Posted on by | Tagged , | Leave a comment

Download NextGen Gallery WordPress Gallery with Wget

For a gallery download with Wget made by NextGen Gallery (at least this is what I read from then nggpage=2 query string), I had success with:

wget -nc -nd -A '*.jpg' -R 'thumbs_*,index.html*' \
    -I /wp-content/gallery/ -r -l 1 \
    http://www.example.com/category/2014/04/08/slug/

My example gallery with with all jpeg files. The switches are documented in the GNU Wget Manual.

Posted in Hakre's Tips, Pressed | Tagged , , , | Leave a comment

Commandline Source Fixes Foo

From time to time I need to cleanup source trees. Today I needed to do that again, here are some command liners to get some work done.

If you’re on Windows, all you need to do to get these running is to install git for windows which has git bash and all the commands used in these examples.

Convert Line Endings / Line Separators

First of all it’s good to review if the find command-line actually finds the file looking for. E.g. to exclude some directories (here exemplary .git for git version control and .idea for Phpstorm and other Idea IDEs) and then list the file extensions that would be find:

find . \( -name '.git' -o -name '.idea' \) -prune -o \
    -type f -printf '%f\n' | awk -F . '{print $NF}' | sort -u

Example: List of file extensions

$ find . \( -name '.git' -o -name '.idea' \) -prune -o \
>     -type f -printf '%f\n' | awk -F . '{print $NF}' | sort -u
gitattributes
gitignore
json
md
php
xml
yml

This shows it’s save to operate on these. Lets ensure all line-endings are unix and not dos:

find . \( -name '.git' -o -name '.idea' \) -prune -o \
    -type f -exec dos2unix -bUvt {} \; 2>&1

This executes dos2unix (here in test-mode, remove -t switch to apply changes) on each file (redirecting stderr to stdout so it’s easier to grep or less). Dos2unix allows more conversions, use dos2unix --help more more info.

Something new I tried today was to apply such a command only onto files that have been touched by the last commit. In a clean staging area after that commit, I could apply dos2unix with the help of git diff-tree and a Bash loop:

git diff-tree --no-commit-id --name-only -r HEAD \
    | while read line ; do dos2unix -bUvt "$line" ; done

So instead of the find operation, I create a list of files to operate on with git and then a while read line ; do ; done loop invokes the command.

\ No newline at end of file

Another common change to apply is to add newlines at the end of files. Some background information about why a newline at the end of file is useful is given in Sanitizing files with no trailing newline (May 2010; by waldner). This one was not so easy for me to find as I wanted to invoke it again via find, but I finally made it working like a charm with the help of sed and the nice Gnu extension of -i (edit file in place) it has – to great extend because of How to add a newline to the end of a file? (Unix & Linux SE):

find . \( -name '.git' -o -name '.idea' -o -name 'vendor' \) -prune -o \
    -type f -exec grep -Iq . {} \; -exec sed -i -e '$a\' {} \;

this does not produce any output, but you can review the changes then with git diff. All those \ No newline at end of file should be gone then.

As usual, keep a backup before running modifications over a whole directory tree automated. Take care to not traverse into directories where you don’t want to.

Posted in Developing, Hakre's Tips, Pressed, Tools | Tagged , , , , , , | Leave a comment

Composer Clear Cache

Composer The Cache

It’s one of the best kept secrets of popular PHP dependency manager Composer: How to flush composers cache.

You normally don’t need it, however if you create some composer.json and you want to put it to a test, this can be useful to know. Or let’s imagine your composer cache grows some gigabytes large. Here are two ways:

First, you can just nuke it from above:

$ rm -rf "`composer config cache-dir`"

(if you’re using Windows, use git-bash.)

The second way is to tell Composer where to find the cache via environment variables:

$ COMPOSER_CACHE_DIR=/dev/null composer install

This second method is perhaps better if in your tests you don’t want to influence the whole system.

The third but not yet available method is to make use of a composer command. This is discussed in the feature request Add command to clear composer cache which also exchanges some arguments pro and con. But I though I spare that for this little TLDR; type of blog-post.

Update 5 Jun: Just in a recent Pull-Request “Add clear cache command” (#3034) such a concrete command has been offered to merge by David Neilsen.

Update 14 Jul: See as well If all else fails Slide of Using composer correctly (confoo) (26 Feb 2014 by Igor Wiedler).

Posted in Developing, Hakre's Tips, PHP Development | Tagged , , , , , | 5 Comments