Compare commits
11 commits
Author | SHA1 | Date | |
---|---|---|---|
D. Moonfire | acca1e3ed4 | ||
400101da34 | |||
D. Moonfire | edb2f36b57 | ||
D. Moonfire | 872628fe05 | ||
D. Moonfire | a08ba9ad4c | ||
D. Moonfire | 875a0daeca | ||
D. Moonfire | b165698a97 | ||
D. Moonfire | 8723fe4842 | ||
dd321fea14 | |||
D. Moonfire | 9b15f8102f | ||
D. Moonfire | 137784dda6 |
47
.woodpecker.yml
Normal file
47
.woodpecker.yml
Normal file
|
@ -0,0 +1,47 @@
|
|||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
tags: true
|
||||
|
||||
pipeline:
|
||||
build:
|
||||
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
|
||||
commands:
|
||||
- nix develop --command scripts/build.sh
|
||||
when:
|
||||
event: [push, tag, manual]
|
||||
tag: v*
|
||||
branch: main
|
||||
|
||||
test:
|
||||
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
|
||||
commands:
|
||||
- nix develop --command scripts/test.sh
|
||||
when:
|
||||
event: [push, manual]
|
||||
branch: main
|
||||
|
||||
release-main:
|
||||
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
|
||||
commands:
|
||||
- nix develop --command scripts/release.sh
|
||||
secrets:
|
||||
- gitea_token
|
||||
- git_credentials
|
||||
when:
|
||||
event: [push, manual]
|
||||
branch: main
|
||||
|
||||
release-gitea:
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
base_url: https://src.mfgames.com
|
||||
files:
|
||||
- "*.pdf"
|
||||
- "*.epub"
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
when:
|
||||
event: tag
|
||||
tag: v*
|
|
@ -1,26 +0,0 @@
|
|||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
tags: true
|
||||
|
||||
pipeline:
|
||||
build:
|
||||
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
|
||||
commands:
|
||||
- nix develop --command scripts/build.sh
|
||||
- nix develop --command scripts/test.sh
|
||||
when:
|
||||
event: [push, pull_request]
|
||||
release:
|
||||
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
|
||||
commands:
|
||||
- export DRONE="true" # Required to convince `env-ci` that it is a known CI
|
||||
- git branch $DRONE_BRANCH origin/$DRONE_BRANCH # semantic-release needs this locally
|
||||
- nix develop --command scripts/release.sh
|
||||
secrets:
|
||||
- gitea_token
|
||||
- git_credentials
|
||||
when:
|
||||
event: [push]
|
||||
branch: main
|
|
@ -1,27 +0,0 @@
|
|||
clone:
|
||||
git:
|
||||
image: woodpeckerci/plugin-git
|
||||
settings:
|
||||
tags: true
|
||||
|
||||
pipeline:
|
||||
build:
|
||||
image: registry.gitlab.com/dmoonfire/nix-flake-docker:latest
|
||||
commands:
|
||||
- nix develop --command scripts/build.sh
|
||||
when:
|
||||
event: [tag]
|
||||
tag: v*
|
||||
gitea:
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
base_url: https://src.mfgames.com
|
||||
files:
|
||||
- "*.pdf"
|
||||
- "*.epub"
|
||||
secrets:
|
||||
- source: gitea_token
|
||||
target: plugin_api_key
|
||||
when:
|
||||
event: [tag]
|
||||
tag: v*
|
4
dmoonfire.json
Normal file
4
dmoonfire.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"categories": ["Development"],
|
||||
"summary": "Methods for working with projects that use different frameworks (such as C# and TypeScript) including how to handle the different build systems and processes."
|
||||
}
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "project-layout",
|
||||
"version": "3.0.2",
|
||||
"version": "3.1.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "project-layout",
|
||||
"version": "3.0.2",
|
||||
"version": "3.1.0",
|
||||
"dependencies": {
|
||||
"@mfgames-writing/clean-theme": "^4.0.2",
|
||||
"@mfgames-writing/contracts": "^4.2.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "project-layout",
|
||||
"description": "A method for organizing multiple polygot source projects.",
|
||||
"version": "3.0.2",
|
||||
"version": "3.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build:pdf": "mfgames-writing-format build pdf",
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
# !/usr/bin/env bash
|
||||
|
||||
#mfgames-project:setup@v0.0.0
|
||||
log() { echo "🚧 $(basename $0): $@"; }
|
||||
cd $(dirname $(dirname $0))
|
||||
#mfgames-project:setup
|
||||
|
||||
log "cleaning old files"
|
||||
rm -f *.epub *.pdf
|
||||
|
||||
log "installing NPM"
|
||||
npm install --ci
|
||||
|
||||
log "running build"
|
||||
npm run build
|
||||
|
|
66
scripts/mfgames-project-script-builder.sh
Executable file
66
scripts/mfgames-project-script-builder.sh
Executable file
|
@ -0,0 +1,66 @@
|
|||
# !/usr/bin/env bash
|
||||
|
||||
## mfgames-project:v0.0.0
|
||||
|
||||
## mfgames-project
|
||||
|
||||
# Variables
|
||||
version=0.0.0
|
||||
|
||||
# Make sure we have the proper parameters.
|
||||
usage() {
|
||||
echo "USAGE $0 script.sh [script2.sh]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "x$1" = "x" ]
|
||||
then
|
||||
usage
|
||||
fi
|
||||
|
||||
# Go through the script and look for each one.
|
||||
for script in "$@"
|
||||
do
|
||||
# Write out the file.
|
||||
echo '# !/usr/bin/env bash' > .mfgames-project.tmp
|
||||
|
||||
if [ -f $script ]
|
||||
then
|
||||
cat $script \
|
||||
| sed -n '/usr.bin.env bash/!p' \
|
||||
| sed '/^#mfgames-project:setup@/q' \
|
||||
| sed -n '/mfgames-project:setup/!p' \
|
||||
>> .mfgames-project.tmp
|
||||
else
|
||||
echo >> .mfgames-project.tmp
|
||||
fi
|
||||
|
||||
echo "#mfgames-project:setup@v$version" >> .mfgames-project.tmp
|
||||
|
||||
if [ -f $script ] && grep 'log() { echo' $script > /dev/null
|
||||
then
|
||||
grep 'log() { echo' $script >> .mfgames-project.tmp
|
||||
else
|
||||
case $script in
|
||||
build.sh) unicode="🚧" ;;
|
||||
release.sh) unicode="🚢" ;;
|
||||
setup.sh) unicode="🌱" ;;
|
||||
test.sh) unicode="🧪" ;;
|
||||
*) unicode=$(unipicker) ;;
|
||||
esac
|
||||
|
||||
echo "log() { echo \"$unicode \$(basename \$0): \$@\"; }" >> .mfgames-project.tmp
|
||||
fi
|
||||
|
||||
echo "cd \$(dirname \$(dirname \$0))" >> .mfgames-project.tmp
|
||||
echo "#mfgames-project:setup" >> .mfgames-project.tmp
|
||||
|
||||
if [ -f $script ]
|
||||
then
|
||||
sed '1,/^#mfgames-project:setup$/d' < $script >> .mfgames-project.tmp
|
||||
fi
|
||||
|
||||
# Finish up and make the script executable.
|
||||
mv .mfgames-project.tmp $script
|
||||
chmod a+x $script
|
||||
done
|
|
@ -1,4 +1,15 @@
|
|||
cd $(dirname $0)/..
|
||||
# !/usr/bin/env bash
|
||||
|
||||
#mfgames-project:setup@v0.0.0
|
||||
log() { echo "🚢 $(basename $0): $@"; }
|
||||
cd $(dirname $(dirname $0))
|
||||
#mfgames-project:setup
|
||||
|
||||
log "cleaning old old version"
|
||||
rm -f exit-planning*
|
||||
|
||||
log "installing NPM"
|
||||
npm install --ci
|
||||
|
||||
log "running release"
|
||||
npx semantic-release
|
||||
|
|
|
@ -1,2 +1,12 @@
|
|||
# !/usr/bin/env bash
|
||||
|
||||
#mfgames-project:setup@v0.0.0
|
||||
log() { echo "🧪 $(basename $0): $@"; }
|
||||
cd $(dirname $(dirname $0))
|
||||
#mfgames-project:setup
|
||||
|
||||
log "installing NPM"
|
||||
npm install --ci
|
||||
|
||||
log "verifying commits"
|
||||
npx commitlint-gitlab-ci -x @commitlint/config-conventional
|
||||
|
|
64
src/index.md
64
src/index.md
|
@ -1,8 +1,8 @@
|
|||
# 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#](/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 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.
|
||||
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.
|
||||
|
||||
## Tools Selection
|
||||
|
||||
|
@ -14,9 +14,11 @@ This means that most of my projects now have a `./flake.nix` and a `./flake.lock
|
|||
|
||||
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.
|
||||
|
||||
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).
|
||||
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).
|
||||
|
||||
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?
|
||||
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?
|
||||
|
||||
### Shell Scripts
|
||||
|
||||
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.
|
||||
|
||||
|
@ -27,3 +29,57 @@ This will give me room to experiment. If I decide I want to play with [Cake](/ta
|
|||
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.)
|
||||
|
||||
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.
|
||||
|
||||
### 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.
|
||||
|
|
Loading…
Reference in a new issue