feat: write new version
This commit is contained in:
parent
bbe0101817
commit
0d62ed5da4
8 changed files with 307 additions and 69 deletions
3
.envrc
3
.envrc
|
@ -1,3 +1,4 @@
|
|||
use flake || use nix
|
||||
|
||||
PATH_add node_modules/.bin
|
||||
dotenv_if_exists
|
||||
PATH_add node_modules/.bin
|
||||
|
|
2
Justfile
2
Justfile
|
@ -1,3 +1,5 @@
|
|||
set dotenv-load
|
||||
|
||||
_default:
|
||||
just --choose
|
||||
|
||||
|
|
75
src/directories.md
Normal file
75
src/directories.md
Normal file
|
@ -0,0 +1,75 @@
|
|||
# Directories
|
||||
|
||||
This is probably one of the more detailed areas of my project setup. The layout of a project has two purposes: organization and revealing information.
|
||||
|
||||
## Keep the Root Clean
|
||||
|
||||
Like my `$HOME` directory, I strive to keep my project roots as empty or clean as possible. The purpose is to give a high-level of the project.
|
||||
|
||||
But, even though many "dotfiles" such as `.prettier` and `.gitignore` are hidden when listing directories, they are not hidden in forge listings which gives a much longer list.
|
||||
|
||||
There are some things the root must have: read me, licenses, `.gitignore`, and other high-level.
|
||||
|
||||
## Source
|
||||
|
||||
Whenever possible, all source code should go into the `//src/`. It doesn't matter the language or multiple languages. Some languages, like C#, will result in a number of assemblies which can create a [large number of directories](https://src.mfgames.com/mfgames-cil/mfgames-cil/src/branch/main/src).
|
||||
|
||||
### Exceptions
|
||||
|
||||
There are times when I have exceptions. For example, in writing projects, I use `//src/` for code to support the project but `//chapters/` for the individual chapters. My gut feeling is that it should be `//src/chapters/` but I've resisted because I have 300+ projects that would need to be migrated.
|
||||
|
||||
## Tests
|
||||
|
||||
The exception to the source code are tests. One of the first things when I'm stuck with a project is look at the source files. Pulling them out of `//src/` and into `//tests/` makes it easier to do searches in the code, use wild cards for figuring out what needs to be packages, and general keeps them relatively isolated.
|
||||
|
||||
## Examples
|
||||
|
||||
A third category of source code are the examples. I put those in `//examples/` much for the same reason I pulled `//tests/` out.
|
||||
|
||||
Examples are stand-alone examples, basically CLI or applications. They will demonstrate an end-to-end implementation of a project. Since they are also built as part of the [build](./just.md) process and used in the testing, they are checked as part of the build to ensure they stay up to date.
|
||||
|
||||
## Documentation
|
||||
|
||||
I'm a strong believer in documentation [in the code instead of a separate wiki](./philosophy.md). To that regard, my "wiki" is part of the source code and put into `//docs/` folder. This is treated as a simple Markdown site with relative links pointing to the other Markdown files as `this is a [link](./just.md)`.
|
||||
|
||||
There are a couple reasons I do this. The main one is because I don't like when documentation doesn't match the source code. On the forges, there is a disconnect between the two projects and sometimes the wiki refers to code that "use to be" or "will be" but not always "currently is".
|
||||
|
||||
Another reason is if the root project is loaded, then doing a search on the project will also search the documentation (and example and tests).
|
||||
|
||||
For my websites that format these documentation, such as [my garden plots](//d.moonfire.us/garden/project-layout/) or [software documentation](//mfgames.com/mfgames-cil/docs/), the code that generates those sites knows to convert the relative `.md` links into the proper format.
|
||||
|
||||
## News and Blogs
|
||||
|
||||
Like the documentation, I found that putting the news and announcements in the wiki also coordinate it. It means that a pull request can have an announcement that will not go live until it is merged into the code. Also, I use this to track typos in the news and fix them via pull requests or feedback.
|
||||
|
||||
## XDG-Based Folders
|
||||
|
||||
Many of these directory suggestions are based on the [XDG Specification](https://specifications.freedesktop.org/basedir-spec/latest/) to store specifics parts of the system. This gives a semi-consistent location with known guidelines of what goes where.
|
||||
|
||||
### Configuration
|
||||
|
||||
Project configuration should go into `//.config/`. This is based on XDG's `XDG_CONFIG_HOME`. Some tools, like `dotnet` use that and it keeps the clutter of `.prettierignore` and `.editorconfig` and other files out of the root.
|
||||
|
||||
This is why I have site-specific configurations use `//.config/fedran.json` or `//.config/dmoonfire-website.json` placed there.
|
||||
|
||||
Sadly, most tools don't support this at this point, but as they do (or they can be configured via the Justfile), then I will move them into the `//.config/` directory. Unfortunately, sometimes this involves having to teach editors and other tools where it is, so I would rather have the individual tools also look in the `.config` folder for their settings.
|
||||
|
||||
### Cache
|
||||
|
||||
Caches. Many projects need a temporary store that is never checked in. XDG uses `XDG_CACHE_HOME` which defaults to `$HOME/.cache` so caches should be put into `//.cache/` in much the same manner.
|
||||
|
||||
I use this with [Fiss](//mfgames.com/fiss/) to store the database files which are only used to cache the results from the forges.
|
||||
|
||||
### Executables
|
||||
|
||||
Executables and scripts are put in `//.local/bin/` based on those conventions. These are also added to the `PATH` as part of the [setup](./setup.md).
|
||||
|
||||
### Data
|
||||
|
||||
For generated data for a project, that needs to be checked in but is not intended for user-editing, is put in the equivalent of the `XDG_DATA_DIR` which is `//.local/share/`.
|
||||
|
||||
This is where I would put tag files, automated analysis for my novels, or anything that needs to go with the project but is basically "noise".
|
||||
|
||||
### State
|
||||
|
||||
State, which is based on `XDG_STATE_DIR` is generated or user-state files that are not to be checked into the code. This can include things like window states, the current position of a program, or per-user settings.
|
7
src/history.md
Normal file
7
src/history.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# History
|
||||
|
||||
One of the earliest approaches I had to try getting a proper environment at the per-project level was [asdf](//d.moonfire.us/tags/asdf). It worked out fairly well for a few years, but then I noticed that my various novels and stories were getting fragile.
|
||||
|
||||
There were limitations that `asdf` couldn't handle easily which meant I needed something more reliable. That led me into [Nix](//d.moonfire.us/tags/nix/) which is my current setup because entering the directory sets up that project's settings while still giving me the reproducibility I need for my novels.
|
||||
|
||||
This means that most of my projects now have a `./flake.nix` and a `./flake.lock` in the root level.
|
90
src/index.md
90
src/index.md
|
@ -1,85 +1,39 @@
|
|||
# Project Layout
|
||||
|
||||
I'm a polyglot programmer. I work in a variety of languages but mostly in [C#](/tags/c-sharp/), [Typescript](/tags/typescript/), and [Rust](/tags/rust/). Every few years, I try a new language to see if I can pick up new ideas or if one "fits" my current mental state better. This is also why I've done a lot dozens of other languages; I would say I know over thirty languages but I'm only a "master" in a handful.
|
||||
I'm a polyglot programmer. I work in a variety of languages but mostly in [C#](//d.moonfire.us/tags/c-sharp/), [Typescript](//d.moonfire.us/tags/typescript/), and [Rust](//d.moonfire.us/tags/rust/). Every few years, I try a new language to see if I can pick up new ideas or if one "fits" my current mental state better. This is also why I've done a lot dozens of other languages; I would say I know over thirty languages but I'm only a "master" in a handful.
|
||||
|
||||
I also flit from project to project. I have my [writing](/categories/writing/) and games. I have little one-off programs and ones that I hope will become a major thing. But, like everything else in my life, I'm "gloriously unfocused" on my tasks which means I have to minimize the speed that I get into a project before the muse escapes me.
|
||||
I also flit from project to project. I have my [writing](//d.moonfire.us/categories/writing/) and games. I have little one-off programs and ones that I hope will become a major thing. But, like everything else in my life, I'm "gloriously unfocused" on my tasks which means I have to minimize the speed that I get into a project before the muse escapes me.
|
||||
|
||||
## Tools Selection
|
||||
Over the years, I've come up with a project structure that works across most languages. It is mostly "for me", but I think there are aspects of that others may enjoy.
|
||||
|
||||
One of the earliest approaches I had to try getting a proper environment at the per-project level was [asdf](/tags/asdf). It worked out fairly well for a few years, but then I noticed that my various novels and stories were getting fragile. There were limitations that `asdf` couldn't handle easily which meant I needed something more reliable. That led me into [Nix](/tags/nix/) which is my current setup because entering the directory sets up that project's settings while still giving me the reproducibility I need for my novels.
|
||||
## Conventions
|
||||
|
||||
This means that most of my projects now have a `./flake.nix` and a `./flake.lock` in the root level.
|
||||
Throughout this document, `//` represents the root of the Git repository. So, `//src/just/build.just` would be the `build.just` in the 'src/just' file under the root.
|
||||
|
||||
## Building, Releasing, and Actions
|
||||
When I'm referring to a directory, I will include a trailing lash such as `//src/` to make a distinct between that and `//Justfile` which is a file.
|
||||
|
||||
Because I've fallen in love with [Semantic Releases](/tags/semantic-release/) and [Conventional Commits](/tags/conventional-commits/), a lot of my processes are built around those. In earlier projects, that usually meant that almost every project _also_ included Node in some form so I could use [semantic-release](https://github.com/semantic-release/semantic-release). That also meant I could use `package.json` to handle versioning.
|
||||
Also, I use forward slashes regardless of the operating system, PowerShell can handle both and it doesn't require escaping in most languages.
|
||||
|
||||
Though, recent thoughts have suggested that I need to break that "one tool fits all" approach. Mostly it came while working on [Nitride](/tags/nitride/) and this website. I found myself trying to have "one build system" to create everything related to the site, including handling Javascript and CSS/SASS. Those are two very complicated projects in C#, so I realize it made sense that instead of creating a Nitride task to call [webpack](/tags/webpack/), I really should just call `webpack` directly. In other words, the [Unix philosophy](https://en.wikipedia.org/wiki/Unix_philosophy).
|
||||
With HTML paths, I will use `//` when a link has both a Gemini and HTML server associated with it or explictly say `https://` if it is an HTML-only site.
|
||||
|
||||
This is where being a polyglot and using different tools comes into play. I have a website that does C#, Typescript, and SASS at the same time. Which one is the "root", which command drives everything? What about a Rust project? Or something else?
|
||||
## Table of Contents
|
||||
|
||||
### Shell Scripts
|
||||
- [Philosophy](./philosophy.md) is the general guidelines for setting up a project.
|
||||
- [Just](./just.md) has the tool used to run scripts in projects.
|
||||
- [Directories](./directories.md) describes the preferred directory layout.
|
||||
- [Setup](./setup.md) for setting up a project to make it "easier" to get into it.
|
||||
- [History](./history.md) describes the historical evolution of my project layout.
|
||||
|
||||
That has kind of led me to my current approach. Instead of always packaging Node in my projects, I really should have a standard location to handle the various actions/targets that apply to any project. Right now, that seems to be shell scripts.
|
||||
## License
|
||||
|
||||
With shell scripts, I just have to know that `./scripts/build.sh` will do whatever is needed to build the target. Same with `./scripts/test.sh` and `./scripts/release.sh`. A Rust project may call Cargo, a .NET project will call `dotnet`, and polyglot will call any and all needed to build it.
|
||||
This book is distributed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International license. More info can be found at [https://creativecommons.org/licenses/by-nc-sa/4.0/](https://creativecommons.org/licenses/by-nc-sa/4.0/)
|
||||
|
||||
This will give me room to experiment. If I decide I want to play with [Cake](/tags/cake/) for my .NET projects, then it still works out because it is just a consistent place. If I want to use [Lefthook](/tags/lefthook/) instead of [Husky](/tags/husky/), I can.
|
||||
The preferred attribution for this novel is:
|
||||
|
||||
I also went with `.sh` suffixes on the files because while I mostly code in [Linux](/tags/linux/), I also want to support [Powershell](/tags/powershell/) and [Windows](/tags/windows/). That way, it is also clear that `build.sh` and `build.ps1` probably result in the same end-result, but specific for that language. (I know Powershell runs on Linux too.)
|
||||
> "Project Layout" by D. Moonfire is licensed under CC BY-NC-SA 4.0
|
||||
|
||||
Obviously, some documentation would be required, but that could be a `README.md` file in that directory. That will look nice in [GitLab](/tags/gitlab/) and give documentation.
|
||||
In the above attribution, use the following links:
|
||||
|
||||
### Paths
|
||||
|
||||
Fortunately, I use [direnv](https://direnv.net/) and [nix-direnv](https://github.com/nix-community/nix-direnv) frequently in my development. This loads the `flake.nix` file as soon as I enter the directory and sets up the tools I need. It also gives me a chance to modify the `PATH` variable but only for that directory which means I can add the `./scripts` folder into the path and have it available anywhere inside the project.
|
||||
|
||||
```shell
|
||||
export PATH=$PWD/scripts:$PATH
|
||||
use flake || use nix
|
||||
```
|
||||
|
||||
When working with packaging systems such as Node that also include scripts, I also add those into the path. In both cases, `$PWD` is always the directory with the `.envrc` file, even if I change directly into somewhere deeper into the proejct tree; using `$PWD/scripts` means that the `build.sh` command is available anywhere.
|
||||
|
||||
```shell
|
||||
export PATH=$PWD/scripts:$PWD/node-modules/.bin:$PATH
|
||||
use flake || use nix
|
||||
```
|
||||
|
||||
### Boilerplates
|
||||
|
||||
Over the half year or so that I've been using this, I found that I was introducing a few new patterns into my scripts. Mostly these were to support CI/CD environments but also because I like feedback that scripts are doing something.
|
||||
|
||||
The most notable aspects were to almost always move into the root directory of the project.
|
||||
|
||||
```shell
|
||||
#! /usr/bin/env bash
|
||||
cd $(dirname $(dirname $0))
|
||||
```
|
||||
|
||||
In the above case, `$0` is the name of the script. The first `dirname` gets me into the `./scripts` folder, the second gets me into the root. That means that even if I call this script from deep inside the project, the paths are always relative to the project root.
|
||||
|
||||
The other is to set up logging so I have something to see what is going on. This is useful for the CI process, but also just so I know something is working properly. I ended up using a consistent start to the scripts to help me identify where the build process was.
|
||||
|
||||
```shell
|
||||
log() { echo "️🧪 $(basename $0): $@"; }
|
||||
log "running tests/gregorian-tests.scm"
|
||||
some testing code
|
||||
```
|
||||
|
||||
When run, it looks like this:
|
||||
|
||||
```shell
|
||||
$ test.sh
|
||||
🧪 test.sh: running tests/gregorian-tests.scm
|
||||
......................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 38 tests in 0.001s
|
||||
|
||||
OK
|
||||
$
|
||||
```
|
||||
|
||||
Each script usually has their only Unicode character, which also gives the logs a nice colorful appearance and really makes it easier to see where things are going. I ended up using a Bash function for this because it simplifed the calls into a simple `log message` and made it easier to function.
|
||||
|
||||
Sadly, Bash doesn't have a good packaging story, so I just copy/paste this into the top of every script along with the `#! /usr/bin/env bash` shebang. Overall, it seems to work and I've been pretty happy with it since.
|
||||
- Project Layout: [https://d.moonfire.us/garden/project-layout/](https://d.moonfire.us/garden/project-layout/)
|
||||
- D. Moonfire: [https://d.moonfire.us/](https://d.moonfire.us/)
|
||||
- CC BY-NC-SA 4.0: [https://creativecommons.org/licenses/by-nc-sa/4.0/](https://creativecommons.org/licenses/by-nc-sa/4.0/)
|
||||
|
|
80
src/just.md
Normal file
80
src/just.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
# Just
|
||||
|
||||
Previous versions of my project layout suggested putting everything into a `//scripts/` folder and adding that to the path using the [project setup](./setup.md).
|
||||
|
||||
For the most part, that worked but I found it cumbersome after about a year. The scripts had to have extensions and I found myself obsessing about the logging prefixes to make things "pretty" even to go as far as to write a program to write a standard boilerplate for scripts to produce logging.
|
||||
|
||||
Realizing that I was losing the tree in the middle of the forest, I found another utility that did most of what I was looking for, was not maintained by me, and had cross-platform support: [Just](https://github.com/casey/just).
|
||||
|
||||
`just` is a pretty solid program, with the ability to have a chooser when one doesn't know the application, can chain commands together, and has the ability to pull in things like the `.env` file if present or chain to other just files.
|
||||
|
||||
The tool also has good [online documentation](https://just.systems/man/en/) and there is also a wonderful [cheat sheet](https://cheatography.com/linux-china/cheat-sheets/justfile/) that is good for referencing.
|
||||
|
||||
## Boilerplate
|
||||
|
||||
That isn't to say I don't have a standard boilerplate when it comes to just files. The main part is to make sure that running `just` by itself gives some form of documentation or possibility of what can be done. Since the bulk of the use of this is via a user console window, I use the "choose" command and put the following stanza at top:
|
||||
|
||||
```just
|
||||
set dotenv-load
|
||||
|
||||
_default:
|
||||
just --choose
|
||||
```
|
||||
|
||||
## Detailed Targets
|
||||
|
||||
For the most part, I'll set up a target such as `build` but there are times when I only want to run a specific part of the build, such as only building the JavaScript assets or only generating files. In those cases, I prefix a more detailed target with the name of the general one and then have the general call that.
|
||||
|
||||
```just
|
||||
build: build-client build-server
|
||||
|
||||
build-client:
|
||||
# Do stuff
|
||||
|
||||
build-server:
|
||||
# Do stuff
|
||||
```
|
||||
|
||||
## Imports
|
||||
|
||||
I like my files to be small and readable, usually a hundred lines or less. With some projects, such as Rust or Python, it can get longer, but I still want to break that into different files.
|
||||
|
||||
In Just, I use the `import` command to pull files from the `//src/just` directory.
|
||||
|
||||
```just
|
||||
import 'src/just/build.just'
|
||||
|
||||
build: build-client build-server
|
||||
```
|
||||
|
||||
## Common Targets
|
||||
|
||||
The most common targets I set up are:
|
||||
|
||||
### `setup`
|
||||
|
||||
Since I use CI servers for most of my work, I use the `setup` target to download assets, install SSH keys, or install NPM packages. In most cases, I look for the presence of those files or directory to avoid doing the work excessively (and it avoid blowing away my SSH keys on accident).
|
||||
|
||||
### `build`
|
||||
|
||||
Pretty much the most common target I'll create and use, `build` will build the project. In many cases, it will run `setup` first.
|
||||
|
||||
### `deploy`
|
||||
|
||||
I use for projects that need to be deployed, like websites.
|
||||
|
||||
### `release`
|
||||
|
||||
The `release` target is for pushing up packages or doing the release process. These are the targets that would do [semantic releases](//d.moonfire.us/tags/semantic-release/) based on [conventional commits](//d.moonfire.us/tags/conventional-commits/).
|
||||
|
||||
### `clean`
|
||||
|
||||
This is also a common task I use, `clean` basically wipes out the folder and gets rid of directories like `node_modules/` (for NPM) or `target/` (for Rust projects). In most cases, I also have a `clean-purge` that does a `git -xfd` but ignores things like my `.env` file to avoid blowing away my environment.
|
||||
|
||||
### `test`
|
||||
|
||||
Performs any tests on the project.
|
||||
|
||||
### `format`
|
||||
|
||||
I use code formatting a lot. In many cases, it is a dependency on `build` to ensure everything is consistent.
|
27
src/philosophy.md
Normal file
27
src/philosophy.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Philosophy
|
||||
|
||||
There are a number of guidelines for setting up the projects.
|
||||
|
||||
1. Reduce Trivia
|
||||
2. Keep it Tidy
|
||||
3. One Commit to Rule Them All
|
||||
|
||||
## Reduce Trivia
|
||||
|
||||
I'm really good at memorizing things, but as I get older, I find it harder to remember tiny little details like which program is needed to build a .NET projects, if I'm using `npm` or `yarn`, or which command is needed for my formatting tools.
|
||||
|
||||
The primary reason for using [Just](https://github.com/casey/just) as a [build tool](./just.md) is to make it easier to know there is always one command to get into the system, no matter what the language, no matter how it is arranged.
|
||||
|
||||
## Keep it Tidy
|
||||
|
||||
This ties a little into trivia, but basically when you look at a project in a forge (Foregejo, GitLab, or GitHub), there is usually a large list of files right there. You have source, lint and tool configurations, and the various supporting files like licenses.
|
||||
|
||||
It can get overwhelming. That is why there are merits in reducing how much information at the top level. That means putting source code in a consistent directory, moving configurations somewhere else, and putting documentation.
|
||||
|
||||
## One Commit to Rule Them All
|
||||
|
||||
This is a paraphrase of the _Lord of the Rings_ poem, but really it comes down to having everything in a commit. Too many times, I've gone to a project's wiki site and saw directions or instructions for a different version. Sometimes the project read me gives some details, other times I have to read the source.
|
||||
|
||||
Blog entries can also be part of this. The main reason is a blog entry might have source code that doesn't work after some refactoring. Being able to deprecate or update the code as part of the commit that requires that change makes it easier to keep everything in sync.
|
||||
|
||||
As much as reasonable for the project should be in the main repository and in well-known [directories](./directories.md). In my case, I put documentation in the `//docs/` folder and even news posts in the `//news/` folder because then everything is tied together.
|
92
src/setup.md
Normal file
92
src/setup.md
Normal file
|
@ -0,0 +1,92 @@
|
|||
# Setup
|
||||
|
||||
The [history](./history.md) of how I've gotten to this point is winding and many decades long. But the end result is that I use two major tools for setting up my projects in a consistent manner: [Direnv](https://direnv.net/) and [Nix Flakes](https://wiki.nixos.org/wiki/Flakes).
|
||||
|
||||
The main reason is history. I have projects that are twenty years old but they are based on languages that never stop changing. In some cases, such as the highly fluid NPM ecosystem, being off by a month can require days of refactoring to handle the current state of deprecations, shifting packages, and trying to get everything playing with each other again.
|
||||
|
||||
Nix Flakes help keep me "pinned" to specific versions and reduces the amount of refactoring I have to do to jump into a project, do a few changes, and finish up.
|
||||
|
||||
## Flakes
|
||||
|
||||
Since flakes give me the consistency I need, that means many of my more recent projects have a `flake.nix` and a `flake.lock` associated with them. These will have a `devShell` which makes sure the programs to use the project are available.
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-24.11";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, mfgames-project-setup, mfgames-writing-setup }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
devShell = pkgs.mkShell {
|
||||
packages = [ pkgs.scc ];
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
I try to avoid using the "unstable" branch for NixOS but sometimes that isn't avoidable.
|
||||
|
||||
### mfgames-project-setup
|
||||
|
||||
To simplify my common project layout, I created a [setup flake](//mfgames.com/mfgames-project-setup-flake/) that does some initial configuration including setting up commit linting (since I use[conventional commits](//d.moonfire.us/tags/conventional-commits/)), formatting, and set up some of the boilerplate files.
|
||||
|
||||
```
|
||||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "nixpkgs/nixos-24.11";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
mfgames-project-setup.url = "git+https://src.mfgames.com/nixos-contrib/mfgames-project-setup-flake.git";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, mfgames-project-setup }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
project-config = mfgames-project-setup.lib.mkConfig {
|
||||
inherit system;
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
prettier.proseWrap = "never";
|
||||
};
|
||||
in
|
||||
{
|
||||
devShell = pkgs.mkShell {
|
||||
packages = [ ]
|
||||
++ project-config.packages;
|
||||
|
||||
shellHook = project-config.shellHook;
|
||||
};
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
I'm pretty proud of that one, since it basically does 90% of my setup when starting a new project. There is also a second setup flake that [sets up my writing projects](//mfgames.com/mfgames-writing-setup-flake/) including getting the right tools installed.
|
||||
|
||||
## Direnv
|
||||
|
||||
To make it easier to get into the environment set up above, I use `direnv`. My shell is set up to automatically include this, and it sets up paths.
|
||||
|
||||
```sh
|
||||
use flake || use nix
|
||||
|
||||
dotenv_if_exists
|
||||
|
||||
PATH_add node_modules/.bin # NPM
|
||||
PATH_add target/debug # Rust
|
||||
PATH_add .local/bin
|
||||
```
|
||||
|
||||
The `use flake` command above will automatically enter the environment configured by `flake.nix` and makes sure I have access to all the tools I need for a given project.
|
||||
|
||||
## Environment
|
||||
|
||||
There are two places I set up environment variables.
|
||||
|
||||
For persisted ones, I put them into the `.envrc` file which is checked into the code. This is used by projects like Fiss to set the local cache file to the one inside the repository and to use the project-local configuration instead of using (and possibly corrupting) my day-to-day one.
|
||||
|
||||
For ones not checked in, I use `.env` to set those variables. This is where I put things like AWS authentication or Forgejo tokens. My [Justfile](./just.md) is set up to avoid removing those when I do a `just clean` and it also loads them using `set dotenv-load`.
|
Loading…
Add table
Add a link
Reference in a new issue