The local-cli is dead. Long live local-cli [A LocalWP Addon to resurrect local-cli].


Deprecated: pathinfo(): Passing null to parameter #1 ($path) of type string is deprecated in /data/sites/web/remonpelnl/www/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 84

Deprecated: pathinfo(): Passing null to parameter #1 ($path) of type string is deprecated in /data/sites/web/remonpelnl/www/wp-content/plugins/crayon-syntax-highlighter/crayon_langs.class.php on line 84

Some of you might remember lbl, my handy little “missing CLI for Local” script from a few years back. Starting, stopping and restarting sites in that script leaned on @getflywheel/local-cli, the official command line tool from the Local folks.

Leaned. Past tense.

Because that tool is deprecated. It talks to Local’s GraphQL server, and that conversation has become… let’s call it “unreliable”. And on the days it did work, it only worked if your shell happened to be on the right Node version. cd into a project with an .nvmrc, and poof; a stack trace, or a Node that runs in an x86 container and can’t even reach Local anymore.

I have a zsh function that starts the site of the folder I cd into. It has been throwing errors lately. I needed a fix … get it? … a f…. never mind, I’ll see myself out.

This is Addon number 8 of 7 ;)

The Problem

Local has no supported way to control sites from the command line. There is the deprecated local-cli, which is GraphQL and Node-based. Since Local-CLI is deprecated, there is nothing stopping the LocalWP team from silently discontinuing the GraphQL API. So I created my own.

And I am, as stated before, a terminal type of person. I want local-cli start-site mysite to just… start the site. From a shell script, from a cron job, from a CI runner, from that zsh function. Without caring which Node is active, or whether Node is active at all.

So what do we do about it?

Once again, everything needed is already in the pantry;

  • An addon runs inside Local’s own main process, and gets handed the same siteProcessManager the Start and Stop buttons in the UI use. No GraphQL required.
  • Node (the one inside Local, the only one that matters here) can open an HTTP server on a Unix domain socket. No TCP port, no token; the file permissions on the socket are the authentication. Only the user running Local can talk to it.
  • curl speaks Unix sockets. curl is everywhere. And curl has never once been broken by nvm.

So the client side doesn’t need Node at all. A plain POSIX shell script, a curl call, done. Glue was applied. ;)

The Solution

CLI Bridge: a Local addon that runs a tiny HTTP server on a Unix socket inside Local, plus a local-cli shell script that talks to it. It is a drop-in replacement for the deprecated tool; same command names, same ID | Name | Status table, so scripts written against the old local-cli keep working. Mine did, without changing a single line.

A site can be referenced by its ID, its domain or its name, case-insensitive. A unique prefix works too; an ambiguous prefix lists the candidates and refuses to guess.

The details that make it actually usable;

  • Add --json for the raw response (ideal for jq) or --plain for tab-separated ID Name Domain Status (ideal for cut/awk).
  • Starting a site that is already running, or stopping one that is already halted, is a successful no-op. Start/stop/restart return once Local reports the transition finished, typically within a few seconds.
  • Proper exit codes: 0 ok, 1 the command failed (unknown site, Local refused), 2 Local or the addon is not reachable, 64 you typed it wrong.
  • Start/stop go through Local’s own machinery, exactly the code path the buttons use. Local’s UI updates as if you clicked. Because, in a way, you did.
  • Don’t like the script? Talk to the bridge directly: curl --unix-socket ~/.local-cli-bridge/bridge.sock -X POST http://local/sites/wp/start
  • Socket and bookkeeping live in ~/.local-cli-bridge/ (mode 0700/0600) and are cleaned up when Local quits. On Windows it’s a named pipe; untested by me, so please, tell me what happens.

Adding a command later is one route in the addon and one line in the shell script’s case. PRs welcome, as always.

Full transparency on quality assurance; tested by 1 person on Local 10.1.2. The addon only touches siteData, siteProcessManager and localLogger, which are identical in Local 9, so it should work there too. Feel free to confirm or deny.

Get it

Source on GitHub: rmpel/Local-CLI-Bridge. Be sure to read the notes.

Install from source (MacOS and Linux);

Restart Local to make it visible in the Installed addons list, toggle on as usual, restart Local once more when it asks you to, and run local-cli ping.

Install from a dist file (All OS); grab the latest .tgz from the dist folder, or build it with ./scripts/build.sh, and use the “Install from disk” feature in LocalWP. You’ll still need the bin/local-cli script somewhere on your PATH.

One gotcha; if you still have the deprecated npm package installed, it usually sits earlier on your PATH and shadows the new command. The installer warns you about it. Get rid of it with npm uninstall -g @getflywheel/local-cli. You won’t miss it.

Beam my site up, Scotty. Copy complete Local sites between machines with Site Beam [A LocalWP Addon].

You might have noticed a pattern in my recent posts. First you hear nothing from me for years, and now all of a sudden, 7 posts in short succession…

And if you checked the imagery, you already seen what’s coming next.

Yes, here it is. Addon number 7, the biggest, the boldest.

This is my farewell gift, and I’m not even going anywhere.

Two laptops, one desk, one site that needs to move from A to B. The official route; export the site on machine A, watch a progress bar, find the zip, AirDrop-or-USB-stick it over, drag it into Local on machine B, watch another progress bar and move on.

For a transfer between two machines that are LITERALLY ON THE SAME NETWORK, half a meter apart. Continue reading “Beam my site up, Scotty. Copy complete Local sites between machines with Site Beam [A LocalWP Addon].”

There is a port conflict with this site’s domain. Sorry, what? No there isn’t [A LocalWP Addon].

Every Local user has seen it. The dreaded banner; “There is a port conflict with this site’s domain”. And every Local user has done the dance;

  • Restart Local
  • Restart Local again…
  • Reboot computer.

Or if you are up for it;

  • Quit Local
  • Check for lingering LocalWP processes
  • Forget nginx, restart Local
  • And problem still there.

The Problem

Local routes all your .local domains through its own bundled nginx on ports 80/443. When that router can’t bind its ports, you get the banner — with a shrug of a message and a “Use localhost” surrender-option. The banner blames a “conflict”, but conveniently never tells you with what. Helpful! Continue reading “There is a port conflict with this site’s domain. Sorry, what? No there isn’t [A LocalWP Addon].”

LocalWP and composer-based WordPress is not a good match, but we can fix that [A LocalWP Addon].

If you run modern composer-based WordPress projects, like Bedrock, or a company template with public_html/wp, WordPress as a package, config from a .env , etc. etc.; then you know that Local and composer projects go together like… well, like they don’t. Not without forcing them.

Import such a site into Local and behold the carnage; WordPress version: unknown. The Database tab: “Unable to find DB_HOST”. The multisite domain Sync button: does nothing. “Open Site Shell”: lands you nowhere useful. One-click admin: nope. Everything that makes Local pleasant is broken, and Local doesn’t even have the decency to tell you why. Continue reading “LocalWP and composer-based WordPress is not a good match, but we can fix that [A LocalWP Addon].”

Start my sites for me, LocalWP, don’t make me do it myself [A LocalWP Addon]

Every morning, the same ritual. Open Local. Wait. Click the site I work on every single day. Click Start. Wait. Realize I also need the second site, because of course the first one talks to it. Click. Start. Wait.

Computers were invented to automate boring repetitive tasks. So why am I the one doing the boring repetitive task here?!

No, this is not a TED Talk about AI, but about IA.

No, no, not Internal Affairs… Intelligent Automation. Continue reading “Start my sites for me, LocalWP, don’t make me do it myself [A LocalWP Addon]”

Set-up additional Apache modules in LocalWP – because sometimes, defaults aren’t good enough [A LocalWP Addon].

You know the drill; you add a couple of Header directives to your .htaccess (a cache-control here, an X-Frame-Options there) you reload the page, you check the response headers and… nothing. No error, no warning, no headers. Just… nothing.

Welcome to debugging something that isn’t broken. My favorite pastime! (It is not.) Continue reading “Set-up additional Apache modules in LocalWP – because sometimes, defaults aren’t good enough [A LocalWP Addon].”

Local’s SSL “Trust” button is BROKEN on macOS. Here’s why, and here’s the fix. [A LocalWP Addon].

Click Trust next to your site’s SSL certificate in Local. Enter your admin password like a good citizen. Watch it report success. Open https://mysite.local and… “Your connection is not private”. Click Trust again. Password again. Success again. Warning again.

Insanity, as the saying goes, is clicking the same button twice and expecting different results. Or something like that.

The Problem

On modern macOS, Local’s Trust button doesn’t work. Well it does, but not for you. It shows the password prompt, appears to succeed, and changes absolutely nothing; browsers keep screaming about your .local certificate forever. And because it looks like it worked, you naturally assume the problem is elsewhere; your browser cache, your cert, your karma. It isn’t. It’s the button. Continue reading “Local’s SSL “Trust” button is BROKEN on macOS. Here’s why, and here’s the fix. [A LocalWP Addon].”

Sequel Pro can’t connect to Local’s MySQL 8? MySQL Fixes AddOn to the rescue [A LocalWP Addon].

The Problem

Connect a classic client (for example Sequel Pro, older Sequel Ace, older JDBC tools) to a Local site running MySQL 8 and you’re greeted with authentication errors about caching_sha2_password.

(I talked about this already, here)

The classic clients speak mysql_native_password; MySQL 8 defaults to the new plugin, and on 8.4+ the old plugin isn’t just non-default, but (and in my opinion, this is a bug of omission) it ships disabled.

Meanwhile Local’s own connections work fine, so from Local’s point of view there is no bug. From MY point of view, sitting in front of a client that can’t connect to my own database; there very much is. Continue reading “Sequel Pro can’t connect to Local’s MySQL 8? MySQL Fixes AddOn to the rescue [A LocalWP Addon].”

Handy script: lbf

[Edit: This script is defunct since Local rebuilt the application and ditched the virtual machine. This script works only with the old “Local by Flywheel”  and not with the “Local Lightning” app. For the latter, see my lbl script]

Local (by Flywheel) is great, but for a terminal type of person as I am, I find it way more convenient to SSH into a VM and use the WP-CLI to perform WordPress tasks. With a platform like Vagrant, one has the

vagrant ssh
command to shell into the virtual environment.

With Local, you can do this with the push of a button in Local, but as said, I like the terminal better.

lbf ssh
is waaaaay faster than going to the Local app, find the site, click the SSH button.

But wait, there is much more ;) Continue reading “Handy script: lbf”

Out with the old, in with the new — Switching from built-in software to one awesome piece of engineering: Local (by Flywheel)

A multitude of recent developments have aided me to make a choice. Some of them are

  • Apple going for thinner, lighter instead of stronger performance, and
  • Microsoft integrating Bash into Windows 10 with WSL (Windows Subsystem for Linux)

While the new Macbook Pro is quite a feet of engineering, it is hardly “Pro”. Surely intel graphics are enough for typing letters and calculating spreadsheets, it’s not Pro. A 16GB memory limit (which with the compression tech used is like 24GB for any other OS) is great for battery life, but it’s not “Pro”. The keyboard is ultra thin and has good tactile feedback, but the keys need a firm press, and travel almost nothing. Great for thinning the device, but again, not “Pro”. For the same amount of money you can buy a portable powerhouse like the Asus ROG G752vy (seen in my post about this). This one has other issues, but at least it has got awesome graphics (nVidia 980), max 64 GB RAM and a “normal” laptop keyboard.

(Yeah, I know, I KNOW, I don’t need ‘awesome graphics’ for web development, but I like to game also, and to be honest; my favorite IDE – phpStorm – DOES prefer a sturdy GPU. Don’t know why, but it runs so much better on a discrete GPU than it does on intel Graphics)

Reasons to stay with macOS are rapidly diminishing, and reasons to start using Windows again are gaining support. Since the Windows 10 Anniversary Update, Windows offers Bash and all goodness that comes with Ubuntu linux, right at your fingertips. Well, not ALL goodness, but most of it.

Continue reading “Out with the old, in with the new — Switching from built-in software to one awesome piece of engineering: Local (by Flywheel)”

Confidental Infomation
stop spam mail