Trying to install a php composer package declaratively

I’m attempting to setup a PHP development environment. Using nixvim and I’m pretty much set. Except when trying to install a coding standard for coroform. Unfortunately, I need to use the WordPress coding standard, which is not built in. This is where composer comes in… I guess I could manually install the standard and be done, but that would not be very declarative.

Looking into it I see buildComposerProject2 which may be what I need.

So two questions:

  1. Could you share how you would install a composer package in a declarative manner?
  2. If you already have a PHP, ideally WordPress development setup, would you be willing to share it?

I’m currently throwing spaghetti (plugins) at a wall (nixvim).

This is my coroform.nix file:

# https://github.com/labi-le/nixos/blob/1028c9c81bbba8015c7090858b65ae1cc1f0dae1/modules/nixvim/conform.nix
{ pkgs, ... }:
{
  programs.nixvim = {
    plugins = {
      conform-nvim = {
        enable = true;
        settings = {
          format_on_save = {
            lsp_format = "fallback";
          };
          formatters_by_ft = {
            php = [ "phpcbf" ];
          };
          formatters =
            let
              standard = builtins.fetchurl {
                url = "https://raw.githubusercontent.com/WordPress/wordpress-develop/refs/heads/trunk/phpcs.xml.dist";
                sha256 = "10v2i3c8lrc3wv1g9n8ql0h3m70nhcxcs5841zwvx6kfh9my49i6";
              };
            in
            {
              phpcbf = {
                command = "${pkgs.php83Packages.php-codesniffer}/bin/phpcbf";
                args = [
                  "--no-cache"
                  "--standard=${standard}"
                  "$FILENAME"
                ];
              };
            };
        };
      };
    };
  };
}

I get this error, which I’m pretty sure is because the standard/package isn’t actually installed?

Log file: /home/sergio/.local/state/nvim/conform.log
          ERROR: Referenced sniff "WordPress.DB.RestrictedFunctions" does not exist.
          ERROR: Referenced sniff "WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare" does not exist.
          ERROR: Referenced sniff "WordPress.DB.PreparedSQLPlaceholders.UnsupportedPlaceholder" does not exist.
          ERROR: Referenced sniff "WordPress.DB.PreparedSQLPlaceholders.UnescapedLiteral" does not exist.
          ERROR: Referenced sniff "WordPress.DB.PreparedSQL.NotPrepared" does not exist.
          ERROR: Referenced sniff "WordPress.Files.FileName" does not exist.
          ERROR: Referenced sniff "WordPress.Files.FileName.InvalidTemplateTagFileName" does not exist.
          ERROR: Referenced sniff "WordPress.Files.FileName.InvalidClassFileName" does not exist.
          ERROR: Referenced sniff "WordPress.Files.FileName.NotHyphenatedLowercase" does not exist.
          ERROR: Referenced sniff "WordPress.WP.I18n" does not exist.
          ERROR: Referenced sniff "WordPress.WP.I18n.MissingTranslatorsComment" does not exist.
          
          Run "phpcbf --help" for usage information

Formatters for this buffer:
phpcbf ready (php) /nix/store/yq2z6c32yy5746l26y88r1lql0i1rki2-php-codesniffer-3.13.0/bin/phpcbf

What makes you think so?
Working with composer usually means there’s a composer.json alongside which declares all dependencies, scripts, etc for the project for php related codebase.

It seems that you already made a post asking about it? Setting up a WordPress dev environment. AKA... Trying to run before I can walk

Not sure what you mean. I did ask about a PHP dev environment earlier and I’ve been developing happily. But I’m now asking about setting up something else within it. Are you meaning that I should be continuing that thread?

Regarding installing the PHP WordPress coding standard, I mean I could just run composer install through a composer.json file? But I’m thinking there is a better way.

That’s up to you. You’re asking twice the same thing and there are plenty of threads on that topic in the forum: Search results for 'wordpress' - NixOS Discourse

What value to “nixify” that? Sounds to me like overhead but maybe I’m misunderstanding the use case
You mentioned that “that would not be very declarative” while composer.json is a way to declare all php packages in 1 file, how is that not declarative?


That’s the base setup I’m using atm: templates/wp-env at main · JimJ92120/templates · GitHub (not polished and few changes to be done)

Fair point, I thougth this different, since I’m specifically asking about installing a composer package through nix. Not about a WordPress dev environment, which I have working. Buuut, yeah. I hear you.

My thought was to setup the tooling in one place, even if it’s using different packaging systems. Could be my use case is lame and I need to re-think it.

Thanks for sharing the wp-env link, as it will help me consider other, possibly better, options. Thought I don’t think it helps with installing the WordPress coding standard available through composer using nix. Again, this may be a bad idea…

wp-env is the WordPress recommended way to develop plugins, themes and it only requires docker and node / npm to run, you can run a WordPress dev environment with very little efforts, run different PHP and WP versions, etc (lots of flexibility and controls):

  • no need to manage DB
  • no need to manage apache or nginx
  • no need to manage php env
  • etc
    => wp-env docker image got it all covered and ready to use already

On composer packages, whether you should nixify that or not, it’s really gonna depends on the project and its requirements.
If you don’t work alone, are not project’s owner, etc then you can not guarantee and shouldn’t impose next developers, clients to use nix. That also depends on e.g CI / CD, servers, etc.

If going into that direction, then you’ll need to maintain:

  • the composer.json so other ppl, who aren’t using nix, can still run the project, use same packages, apply coding standards and so on
  • the nix config
    => so in that context, only value will be for you, to have all set and declared within nix and not even sure it has actual value: more to maintain, need to spend time to investigate how to nixify, etc

I’m not trying to turn down your idea but trying to give you a full picture.

The only thing I would nixify, would be a shell environment to run the project.
Then if need to set and install composer packages, just run composer install and done.
Keep It Simple, Stupid.

e.g from the templates/wp-env shared above:

{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    nodejs
    yarn
    docker
    php84Packages.composer
  ];

  buildInputs = with pkgs;[

  ];

  shellHook = ''
    export PATH="$PWD/node_modules/.bin/:$PATH"

    composer install
  '';
}
1 Like

Well, I won’t admit how many tabs or hours I spent on this but I did get it working! It may very well be a bad practice and I’d love for any input on how to better achieve getting this to work. However, I now have nixvim configured to use the WordPress php standards. :partying_face:

Here is the conform.nix file that activates the conform-nvim plugin with the needed settings:

{
  config,
  ...
}:
{
  home.sessionPath = [ "${config.home.homeDirectory}/.config/composer/vendor/bin" ];
  home.activation = {
    setCodingStandard = ''
      ${config.home.homeDirectory}/.nix-profile/bin/composer global config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
      ${config.home.homeDirectory}/.nix-profile/bin/composer global require "squizlabs/php_codesniffer=*"
      ${config.home.homeDirectory}/.nix-profile/bin/composer global require --dev wp-coding-standards/wpcs:"^3.0"
    '';
  };
  programs.nixvim = {
    plugins = {
      conform-nvim = {
        enable = true;
        settings = {
          format_on_save = {
            lsp_format = "fallback";
          };
          formatters_by_ft = {
            php = [ "phpcbf" ];
          };
          formatters = {
            phpcbf = {
              command = "${config.home.homeDirectory}/.config/composer/vendor/bin/phpcbf";
              args = [
                "--no-cache"
                "--standard=WordPress"
                "$FILENAME"
              ];
            };
          };
          log_level = "debug";
          notify_on_error = true;
        };
      };
    };
  };
}

Hope this helps somebody!

Now to see about a better way to have the other parts of the WordPress dev environment configured.

Just done my minimal dev setup, only using nix-shell to get required packages to run the environment: GitHub - JimJ92120/wordpress-dev: A minimal WordPress environment for development with wp-env.

Nice and clean! I’m looking at other examples, including yours, and thinking about integrating wp-now. Currently, I’m using a Caddy, PHP, MariaDB configuration that makes it very easy for me to spin up a new project. Buuuut, who knows.

wp-now is quite limited. wp-env does the same thing overall BUT allows you to declare your setup in a .wp-env.json but it runs on docker.
If you want more control over wp-env, then you can switch to a docker with docker-compose based environment (e.g if need to add a mail server or other containers to the env), that’ll gives you reproducibility as well, WordPress has their own docker image: wordpress-develop/.devcontainer/docker-compose.yml at 43b7ac10082e273e380df62e3cf9593c68254fa7 · WordPress/wordpress-develop · GitHub

If you’re just looking at running a PHP env, then you just need a db, php and either nginx or apache to serve PHP files.
Plenty of tools for that but keep in mind that these tools are just wrappers and you’ll have a lot less control over configurations, you can’t guarantee maintenance on the long term either.

IMHO there’s no need to re-invent the wheel and make things more complex.
Keep It Simple, Stupid.