VSCode-Based Extensions Can Be Taught! https://medium.com/p/vscode-based-extensions-can-be-taught-aba138fdbf0c?source=social.tw
#direnv #vscode #cursor #extensions #environmentvariables #sdkman #nvm #pyenv
VSCode-Based Extensions Can Be Taught! https://medium.com/p/vscode-based-extensions-can-be-taught-aba138fdbf0c?source=social.tw
#direnv #vscode #cursor #extensions #environmentvariables #sdkman #nvm #pyenv
Cool! Apparently direnv has a use guix command that can be added to .envrc. That's significantly simpler than what I usually put in my .envrc:
eval $(guix shell --manifest=manifest.scm --search-paths)
It also accepts packages to include ( use guix guile guile-hoot) although that's less interesting.
On the one hand this seems pretty clean, on the other this changes setting up a new project directory from:
direnv allow
to:
direnv allow
pwd >> ~/.config/guix/shell-authorized-directories
Not sure what I like better... I guess the second one is more easily scriptable than repeating the incantation in .envrc.
Local WordPress Development on NixOS with devenv
https://sfndesign.ca/local-wordpress-development-on-nixos-with-devenv
Two years ago I made my first attempt with NixOS and after a week of vacation spent spinning my wheels, I didn't have a fully working system so I went back to Fedora and what I knew while adding home manager to my workflow. Still using home manager and VVV on Fedora brought issues with certificate signing every time the kernel updated. Just before Christmas I had another round of certificate issues and decided that it was time to learn devenv. It worked and now I built my new computer fully on NixOS because the local development environment was worked out. What is devenv The whole deal with NixOS is that it's declarative. A basic install has configuration.nix and hardware-configuration.nix. The hardware configuration is specific to your machine, but configuration.nix is agnostic. That means you can install NixOS on any machine, copy your configuration.nix file over, run nixos-rebuild switch and after a few minutes your entire machine will be configured just like your old machine. devenv extends that to declarative development environments that don't pollute each other. I can have different versions of PHP or node or any other library that is isolated to only the folder for that project. direnv does something similar without spinning up servers. Using shell.nix or flake.nix you can load your project dependencies and they'll be isolated to that project. For my Laravel projects I still use php artisan serve for a server but define all the requirements for the project with direnv. But just like Fedora brought its own challenges with certificate signing, devenv on Nix has read only stores which means my setup on Fedora didn't work out of the box. Today we're going to take a look at my local WordPress development environment on NixOS. We'll get custom domains setup and trust the custom SSL certificate in Firefox so I don't get warnings for every site. Prerequisites To get started you're going to need NixOS installed and flake enabled. direnv and a project you want to spin up in devenv. Setting Up devenv on NixOS Installing devenv To start you're going to need to add devenv to your .pkgs and rebuild your system with sudo nixos-rebuild switch. Here is a full look at the devenv.nix file we'll be using to setup a local WordPress site. { pkgs, config, ... }: { packages = with pkgs;[ git wp-cli ]; enterShell = '' ./scripts/setup-wp-stubs.sh ''; languages.php.enable = true; languages.php.package = pkgs.php82.buildEnv { extensions = { all, enabled }: with all; enabled ++ [ redis pdo_mysql xdebug ]; extraConfig = '' memory_limit = -1 xdebug.mode = debug xdebug.start_with_request = yes xdebug.idekey = vscode xdebug.log_level = 0 max_execution_time = 0 ''; }; languages.php.fpm.pools.web = { settings = { "clear_env" = "no"; "pm" = "dynamic"; "pm.max_children" = 10; "pm.start_servers" = 2; "pm.min_spare_servers" = 1; "pm.max_spare_servers" = 10; }; }; # change the certificate to match your site certificates = [ "wp.localhost" ]; services.redis.enable = true; # Links to MariaDB internally services.mysql = { enable = true; settings.mysqld = { max_allowed_packet = "512M"; }; }; # change the database name and change ensurePermissions to match your site name services.mysql.initialDatabases = [{name = "wp"; }]; services.mysql.ensureUsers = [ { name = "admin"; password = "test"; ensurePermissions = { "wp.*" = "ALL PRIVILEGES"; }; } ]; services.caddy.enable = true; # change wp.localhost to <yoursite>.localhost and the .pem file names should match that services.caddy.virtualHosts."wp.localhost" = { extraConfig = '' tls ${config.env.DEVENV_STATE}/mkcert/wp.localhost.pem ${config.env.DEVENV_STATE}/mkcert/wp.localhost-key.pem root * . php_fastcgi unix/${config.languages.php.fpm.pools.web.socket} file_server ''; }; } Trusted Users for Cachix If you grabbed the file above and dropped it in your project right now you'd get a warning about not being a trusted user of the Nix store. The easiest way to fix this is to make yourself a trusted user of the Nix store. Add the following line to your configuration.nix file. nix.settings.trusted-users = [ "root" "<youruser>" ]; Then run sudo nixos-rebuild switch again to grant your user privileged access. Note: A common mistake is to put this in your home-manager files, but it's not a home-manager option and wouldn't be needed if you're using home-manager on other Linux systems. Binding Caddy to Port 443 on NixOS To get clean local URLs we need to allow caddy to bind to port 80/443 but Linux restricts that. For non-Nix environments we add this line above our redis declaration. # This lets Caddy bind to 443 scripts.caddy-setcap.exec = '' sudo setcap 'cap_net_bind_service=+ep' ${pkgs.caddy}/bin/caddy ''; Then use devenv shell to drop into the local shell with your defined environment loaded. Then run sudo setcap 'cap_net_bind_service=+ep' $(which caddy). But we're in Nix so that doesn't work because we can't write to our installed server files and caddy can't bind to ports under 1024 by default. The easiest way to accomplish this is to reset the limit on which ports we can bind to. Add this line to your Nix config. # Allow unprivileged processes to bind to ports 80+ (needed for devenv Caddy) boot.kernel.sysctl."net.ipv4.ip_unprivileged_port_start" = 80; Now caddy can bind to port 80 and above. If you go digging around the internet you'll find that ports were reserved but it doesn't really matter on your local machine so go for it. Even Kubernetes deploys may change this setting with no ill effects. Trusting the Local SSL Certificate in Firefox Next, if you check your site now you'll get a scary warning in your browser of choice about a non-trusted SSL. This happens because Firefox doesn't trust the root certificate we added with devenv. You have two choices here, just click the 'Accept Risk' button and move on or add the certificate to your root store. I opt to add the certificate by going to about:preferences#privacy then scrolling down to Certificates. Click 'View Certificates' and go to the Authorities Tab then click Import. You'll find the devenv root certificate at .devenv/state/mkcert/rootCA.pem. Since all devenv projects share the same root certificate this is a one time change. You should be able to do this in other browsers as well in their settings. Conclusion Now you've got a development environment setup that doesn't leak different versions of your libraries into other projects. Yes it required a few system level tweaks, but if you're on NixOS you make those tweaks once and then you don't make them on your next system because they're already made. Now I cd into my project directory and type devenv up and my development environment starts. Creating a new WordPress environment is as simple as copying the devenv.nix file into a new directory and changing a few values. No more messing with certificates every time my kernel updates.
My day job is all about #Python (which I love). Here are some personal rules, specific to working with Python projects:
* Do **not** install or modify global tools, especially Python itself or any packages. This means a given system might not even **have** a global Python
* Always use virtual environments (`uv` agrees with me, and doesn't need this but). I always set the global environment variable `PIP_REQUIRE_VIRTUALENV`.
* The two rules above mean my virtual environment contains (not via a link, it's really there) Python itself (and of course, of the right version)
* Virtual environments always live **inside** a project directory. Never global.
* Activate virtual environments only **inside** the project directory (`direnv` #direnv makes this easy)
* Don't install (let alone use) #Anaconda, #Miniconda, or #Mamba, because those violate all the rules above (but see the next rule)
* Anaconda-based packages implies a `pixi` #Pixi project (it's the same people, but a better answer, and you still get what you want -- the correct packages)
* No Anaconda-based packages implies a `uv` #UV project
* Always use `pyproject.toml` #pyprojecttoml over any other config file (e.g., `requirements.txt` #requirementstxt), except where things just don't work, such as needing `pyrefly.toml`
* `uv`, `pixi`, and `direnv` must exist outside of any project, so install them at the user level, or else globally if and only if that is appropriate and compelling enough to override rule one
That was a wall of text, but in practice doing it this way is trivial. It's probably **less** work than you have been doing. This post is just about managing your Python versions, environments, and projects. Not about, e.g., using `pre-commit` #precommit, or doing type checking, etc. But if you follow these rules, your work will be easier, faster, more adaptable, and encounter fewer obstacles.
As an alternative, you can follow the approach in the #guix #cookbook [1], which automagically takes care of everything for you. Even better, you may make use of #direnv [2] and its built-in "use guix" [3] to customise all project level related.
[1] https://guix.gnu.org/cookbook/en/html_node/Software-Development.html
[2] https://guix.gnu.org/cookbook/en/html_node/Environment-management.html
[3] https://raw.githubusercontent.com/direnv/direnv/refs/heads/master/stdlib.sh
I use #Git. A feature of Git I leverage heavily is #Worktree. I usually have at least four around at a time. For small tasks, sure, a simple branch and then switch back, but bigger things: a worktree.
Making a worktree is actually annoying for me: not just the upfront decisions about branches and start points and where to put the new directory (and also immediately `cd`ing there: but getting all the #submodules (submodules suck by the way), hooking up `.envrc` if you use #Direnv (and you should be), which should then set up your virtual environment and path and stuff. Clone isn’t quite as bad but has some of the same problems.
I do this so often, I wrote a script. It might be useful to others with this workflow. It’s opinionated, and therefore I could really use some feedback! What did I do right? What did I do that’s only right for me? What is totally missing?
The script is stand-alone, though you do need #UV. (You don’t even need Python! `uv` will transparently get you everything!) Just download this one Python file, and get it on your `$PATH`. If you want the additional `cd` behavior, then add the shell function, too as described in the `README`. Everything is tested. The tests are right there, too.
https://github.com/wolf/dotfiles/blob/main/git/dot-config/git/bin/make-worktree.py
The `README.md` is right next to it.
I **do** see one thing I’m missing: I need to provide a way to automatically copy in your custom stuff. I’ll add that today.
The more I learn about #Direnv, the happier I become. It **already** works with #Pixi. It **already** helps you with secrets (ignore `.envrc` in your `.gitignore` or equivalent). I grabbed a `layout_uv` from the direnv wiki (made some small modifications), and it works basically everywhere I want it.
If you're not using using `direnv` yet, you are doing yourself a disservice.