mirror of
https://github.com/dwinkler1/np.git
synced 2026-02-19 22:40:57 -05:00
Compare commits
132 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
be5572e84d |
|||
|
274972e8a4 |
|||
|
35e550c477 |
|||
|
|
1fca4c0330 | ||
|
|
4662b867bd | ||
|
d8fb361e76 |
|||
|
|
a1e803a023 | ||
|
|
b362614076 | ||
|
341c830c87 |
|||
|
|
1376f8ddc5 | ||
|
|
2863733742 | ||
|
|
5646308c21 | ||
|
|
0d7caccf06 | ||
|
|
a337a9cf1e | ||
|
|
785cdaaa91 | ||
|
5acc6c196e |
|||
|
47260db047 |
|||
|
|
338a5a38dc | ||
|
|
94b25e5b5c | ||
|
f561def1a6 |
|||
|
|
8d6ea0b0d5 | ||
|
d22cc8f331 |
|||
|
4dc39abc1c |
|||
|
|
0f7687bc39 | ||
|
f76c289185 |
|||
|
|
bb7dfcbb56 |
||
|
272d6b5898 |
|||
|
|
c703bf420a | ||
|
dd81600b75 |
|||
|
9ec42ad1e9 |
|||
| c3bc8f74a6 | |||
| 39311f1822 | |||
|
beda7e9069 |
|||
|
4a9b9a094a |
|||
|
|
3787de151c | ||
|
|
8efae381e9 | ||
|
|
703690472a | ||
|
|
3777ab0c91 | ||
|
|
ca5642d51f | ||
|
|
4cd5a343e6 | ||
|
|
0514ba1283 | ||
|
|
cfccd9a010 | ||
|
|
849225e22e | ||
|
|
0e775e8259 | ||
|
79665dd77e |
|||
|
|
0273515951 | ||
|
|
8fc712be60 | ||
|
|
2a5a1acd62 | ||
|
|
40095ac868 | ||
|
|
c19248f706 | ||
|
|
cc69aa34f8 | ||
|
|
496c238a12 | ||
|
|
eaecb56186 | ||
|
c29efd219c |
|||
|
|
3398a72241 | ||
|
|
42619ade95 | ||
|
|
3259b58a2e | ||
|
|
5e8f07c560 | ||
|
2a7530817e |
|||
|
|
52594bfec2 | ||
| 7bb988ef7d | |||
| 5c22c25853 | |||
|
|
dc44024b1a |
||
|
|
c28df1df7d |
||
|
3d5cddab45 |
|||
|
|
8a1f4683e9 | ||
|
497776759e |
|||
|
|
c70cb27d3d | ||
|
1deb1b02ff |
|||
|
|
8c6f283cde | ||
|
e4f74dedf4 |
|||
|
|
6e4902ab96 | ||
|
6a4c78453c |
|||
|
|
0c2ccb0d4a | ||
|
57e2e03d4e |
|||
|
|
8bae293da4 | ||
|
6d7384424f |
|||
|
|
ef83c56fde | ||
|
d2c6f18e54 |
|||
|
|
14a8607392 | ||
|
aaa2996a67 |
|||
|
|
2a1f500f39 | ||
|
6fc3e1a52e |
|||
|
|
b30d239c2a | ||
|
47d480dc63 |
|||
|
|
77f0408435 | ||
|
df9d53a033 |
|||
|
|
8afc72cda7 | ||
|
fca8dbd2e8 |
|||
|
|
c526b5d753 | ||
|
97eea5e6e8 |
|||
|
c46dc25eae |
|||
|
|
491da07860 | ||
|
aaa81f9ab4 |
|||
|
|
22efe17864 |
||
|
e2de945cd2 |
|||
| a72562371a | |||
| f0b60b014a | |||
| 790c9ed1c8 | |||
|
489d326dc3 |
|||
|
|
cdf034d455 | ||
|
8ad62e2708 |
|||
|
|
d8c600888e | ||
|
cb0e4bfb41 |
|||
|
|
eafd4d608a | ||
|
2a38363866 |
|||
|
|
7b3831e01e | ||
|
e4497d06da |
|||
|
|
0ee79f5340 | ||
|
03c4194f9a |
|||
|
|
8264dbb3f1 | ||
| 77de361e53 | |||
| 66bde1c473 | |||
| 7d7f9aff73 | |||
| 32ed13ca57 | |||
| 08e48987d4 | |||
| dcc5a73ee4 | |||
| df0a95b35a | |||
| d034d1a299 | |||
| 99614a96af | |||
| af32e7a267 | |||
| eb6493192f | |||
| 7499da9b92 | |||
| 49fce77750 | |||
| 35df7b482f | |||
| 7f8b3a491a | |||
| 46ef4ce5f1 | |||
|
b2b325f16a |
|||
|
b171648c44 |
|||
|
a0e2cd046e |
|||
|
1c17367ab7 |
|||
|
|
ebe1c9e4a2 |
31 changed files with 2173 additions and 500 deletions
194
.github/copilot-instructions.md
vendored
Normal file
194
.github/copilot-instructions.md
vendored
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
# GitHub Copilot Instructions for np Repository
|
||||
|
||||
## Repository Overview
|
||||
|
||||
This repository provides Nix flake templates for setting up Research Development Environments (RDE). The primary template is located in `templates/rde/` and is designed for data science and research projects supporting R, Python, and Julia.
|
||||
|
||||
## Project Structure
|
||||
|
||||
- `flake.nix` - Root flake defining available templates
|
||||
- `templates/rde/` - Main RDE template with Neovim-based development environment
|
||||
- `flake.nix` - Template flake configuration with language support and tooling
|
||||
- `flake.lock` - Locked dependencies for reproducibility
|
||||
- `.envrc` - direnv configuration for automatic environment loading
|
||||
- `.github/workflows/` - CI/CD workflows for testing and updates
|
||||
- `check.yml` - Tests RDE template on Ubuntu
|
||||
- `check_macos.yml` - Tests RDE template on macOS
|
||||
- `update.yml` - Automated daily dependency updates
|
||||
|
||||
## Key Technologies
|
||||
|
||||
- **Nix Flakes**: Reproducible development environments
|
||||
- **nixCats**: Custom Neovim configuration framework
|
||||
- **direnv**: Automatic environment loading
|
||||
- **Cachix**: Binary cache for faster builds (using `rde`, `rstats-on-nix`, and `nix-community` caches)
|
||||
|
||||
## Language Support
|
||||
|
||||
The RDE template supports multiple languages, controlled via `config.enabledLanguages` in `templates/rde/flake.nix`:
|
||||
|
||||
- **R**: R wrapper, Quarto, air-formatter, language server, and custom R packages via overlays
|
||||
- **Python**: Python 3, basedpyright LSP, UV package manager
|
||||
- **Julia**: Julia REPL with Pluto.jl support
|
||||
|
||||
## Development Commands
|
||||
|
||||
The template provides project-specific commands (prefix with package name, default is `p`):
|
||||
|
||||
- `p` - Launch Neovim
|
||||
- `p-g` - Launch Neovide GUI
|
||||
- `p-initProject` - Initialize project structure (data/, src/, docs/)
|
||||
- `p-updateDeps` - Update all dependencies (flake inputs, R packages, Python packages)
|
||||
- `p-r` - Launch R console
|
||||
- `p-py` / `p-ipy` - Launch Python/IPython REPL
|
||||
- `p-marimo` - Launch Marimo notebook
|
||||
- `p-jl` - Launch Julia REPL
|
||||
- `p-pluto` - Launch Pluto.jl notebook
|
||||
- `p-devenv` - Devenv integration (when enabled)
|
||||
|
||||
## Nix Flake Conventions
|
||||
|
||||
### Configuration Structure
|
||||
|
||||
The RDE template uses a centralized `config` object at the top of `flake.nix`:
|
||||
|
||||
```nix
|
||||
config = rec {
|
||||
defaultPackageName = "p";
|
||||
enabledLanguages = { julia = false; python = false; r = true; };
|
||||
enabledPackages = { gitPlugins = enabledLanguages.r; devenv = false; };
|
||||
theme = { colorscheme = "kanagawa"; background = "dark"; };
|
||||
};
|
||||
```
|
||||
|
||||
### Overlays Pattern
|
||||
|
||||
The template uses multiple overlays to extend nixpkgs:
|
||||
|
||||
- `rOverlay` - Adds R packages via rix/rstats-on-nix
|
||||
- `pythonOverlay` - Configures Python packages
|
||||
- `rixOverlay` - Integrates R package snapshots from rstats-on-nix
|
||||
- `projectScriptsOverlay` - Custom shell scripts for project management
|
||||
- `extraPkgOverlay` - Additional theme and plugin configuration
|
||||
|
||||
### Package Categories
|
||||
|
||||
nixCats uses categories to organize functionality:
|
||||
|
||||
- `lspsAndRuntimeDeps` - Language servers and runtime dependencies
|
||||
- `startupPlugins` - Neovim plugins loaded at startup
|
||||
- `optionalPlugins` - Plugins loaded on demand
|
||||
- `environmentVariables` - Language-specific environment setup
|
||||
- `extraWrapperArgs` - Additional wrapper arguments (e.g., unset PYTHONPATH for Python)
|
||||
|
||||
## Testing & CI/CD
|
||||
|
||||
### Local Testing
|
||||
|
||||
```bash
|
||||
# Build the RDE template
|
||||
nix build ./templates/rde
|
||||
|
||||
# Check the RDE template
|
||||
nix flake check ./templates/rde
|
||||
|
||||
# Enter development shell
|
||||
nix develop ./templates/rde
|
||||
```
|
||||
|
||||
### CI Workflows
|
||||
|
||||
- **check.yml**: Runs on pushes to `templates/rde/flake.lock`, builds and checks the template on Ubuntu
|
||||
- **check_macos.yml**: Tests on macOS when `update_rde` branch is pushed
|
||||
- **update.yml**: Daily cron job that updates dependencies via `p-updateDeps` and creates PRs
|
||||
|
||||
## Dependency Management
|
||||
|
||||
### R Packages
|
||||
|
||||
R packages are managed through rstats-on-nix pinned snapshots. The date is specified in the `rixpkgs.url` input:
|
||||
|
||||
```nix
|
||||
rixpkgs.url = "github:rstats-on-nix/nixpkgs/2025-12-15";
|
||||
```
|
||||
|
||||
Custom R packages can be added in `rOverlay` or via `r-packages.nix` file.
|
||||
|
||||
### Python Packages
|
||||
|
||||
Python packages use UV for management with nixpkgs Python as the interpreter:
|
||||
|
||||
- Environment variables force UV to use nix Python: `UV_PYTHON_DOWNLOADS = "never"` and `UV_PYTHON = pkgs.python.interpreter`
|
||||
- PYTHONPATH is explicitly unset via `extraWrapperArgs`
|
||||
|
||||
### Flake Inputs
|
||||
|
||||
Dependencies are tracked in `flake.lock`. Key inputs include:
|
||||
|
||||
- `nixpkgs` - NixOS 25.11
|
||||
- `rixpkgs` - R package snapshots from rstats-on-nix
|
||||
- `nixCats` - Custom Neovim configuration framework
|
||||
- `fran` - Extra R packages overlay
|
||||
- Plugin inputs for R.nvim ecosystem
|
||||
|
||||
## Coding Style & Conventions
|
||||
|
||||
1. **Nix Code**:
|
||||
- Use `rec` for recursive attribute sets when needed
|
||||
- Prefer `let...in` for local bindings
|
||||
- Use `lib.optional` and `lib.optionalString` for conditional inclusion
|
||||
- Keep configuration at the top of the file for easy customization
|
||||
|
||||
2. **Shell Scripts** (in overlays):
|
||||
- Always use `set -euo pipefail` for safety
|
||||
- Provide user-friendly output with emojis and clear messages
|
||||
- Check for existing files/directories before creating
|
||||
|
||||
3. **Workflows**:
|
||||
- Use `workflow_dispatch` for manual triggering
|
||||
- Configure concurrency to cancel in-progress runs
|
||||
- Use Cachix for binary caching with multiple caches
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Adding a New Language
|
||||
|
||||
1. Add to `config.enabledLanguages`
|
||||
2. Create overlay for language-specific packages
|
||||
3. Add to `categoryDefinitions.lspsAndRuntimeDeps`
|
||||
4. Add command aliases in `packageDefinitions.hosts`
|
||||
5. Update `shellHook` with available commands
|
||||
|
||||
### Adding Custom Scripts
|
||||
|
||||
Add to `projectScriptsOverlay`:
|
||||
|
||||
```nix
|
||||
myScript = prev.writeShellScriptBin "myScript" ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
# script content
|
||||
'';
|
||||
```
|
||||
|
||||
### Plugin Integration
|
||||
|
||||
For git-based plugins:
|
||||
1. Add flake input with `flake = false`
|
||||
2. Reference in nixCats inputs
|
||||
3. Add to `startupPlugins` or `optionalPlugins` categories
|
||||
|
||||
## Important Notes
|
||||
|
||||
- The template creates a `.gitignore` that excludes data files by default
|
||||
- R packages are installed to project-local `.Rlibs/` directory
|
||||
- Python UV is configured to never download Python, always using nixpkgs version
|
||||
- The template supports multiple platforms: x86_64-linux, aarch64-linux, aarch64-darwin
|
||||
- Neovim is wrapped with language-specific environment variables and PATH additions
|
||||
|
||||
## File Generation
|
||||
|
||||
When asked to initialize projects or generate common files, follow the patterns in:
|
||||
- `initProjectScript` for project structure
|
||||
- `.gitignore` template for what to exclude
|
||||
- `README.md` template for documentation structure
|
||||
205
.github/workflows/check.yml
vendored
205
.github/workflows/check.yml
vendored
|
|
@ -4,6 +4,17 @@ on:
|
|||
push:
|
||||
paths:
|
||||
- 'templates/rde/flake.lock'
|
||||
- 'templates/rde/**/*.nix'
|
||||
- 'templates/rde/**/*.sh'
|
||||
- 'templates/rde/**/*.lua'
|
||||
- '.github/workflows/check.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'templates/rde/flake.lock'
|
||||
- 'templates/rde/**/*.nix'
|
||||
- 'templates/rde/**/*.sh'
|
||||
- 'templates/rde/**/*.lua'
|
||||
- '.github/workflows/check.yml'
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
|
@ -14,13 +25,199 @@ jobs:
|
|||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: wimpysworld/nothing-but-nix@main
|
||||
with:
|
||||
hatchet-protocol: 'carve'
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- run: nix build ./templates/rde
|
||||
- run: nix flake check ./templates/rde
|
||||
- uses: cachix/cachix-action@v16
|
||||
with:
|
||||
name: rde
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
extraPullNames: rstats-on-nix, nix-community
|
||||
# - uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
|
||||
# Build and basic checks
|
||||
- name: Build template
|
||||
run: nix build ./templates/rde
|
||||
- name: Run flake check
|
||||
run: nix flake check ./templates/rde
|
||||
|
||||
# Test development shell functionality
|
||||
- name: Test dev shell enters successfully
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "echo 'Dev shell works'"
|
||||
|
||||
# Test R functionality (default enabled)
|
||||
- name: Test R command is available
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "which p-r"
|
||||
|
||||
- name: Test R launches and runs basic command
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "p-r --version"
|
||||
|
||||
- name: Test R can execute simple code
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "p-r -e 'print(1+1)'"
|
||||
|
||||
- name: Test Quarto is available in R environment
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "quarto --version"
|
||||
|
||||
# Test Neovim functionality
|
||||
- name: Test Neovim command is available
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "which p"
|
||||
|
||||
- name: Test Neovim launches in headless mode
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "p --headless --version"
|
||||
|
||||
# Test utility commands
|
||||
- name: Test p-initProject command is available
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "which p-initProject"
|
||||
|
||||
- name: Test p-initProject creates project structure
|
||||
run: |
|
||||
TEST_DIR=$(mktemp -d)
|
||||
cd "$TEST_DIR"
|
||||
nix develop $GITHUB_WORKSPACE/templates/rde --command bash -c "p-initProject"
|
||||
# Verify directories were created
|
||||
test -d data/raw || exit 1
|
||||
test -d data/processed || exit 1
|
||||
test -d src || exit 1
|
||||
test -f README.md || exit 1
|
||||
test -f .gitignore || exit 1
|
||||
echo "Project structure created successfully"
|
||||
# Cleanup
|
||||
rm -rf "$TEST_DIR"
|
||||
|
||||
- name: Test p-updateDeps command is available
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix develop --command bash -c "which p-updateDeps"
|
||||
|
||||
# Test that package is built correctly
|
||||
- name: Test default package can be run
|
||||
run: |
|
||||
cd templates/rde
|
||||
nix run . -- --headless --version
|
||||
|
||||
test-with-python:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: wimpysworld/nothing-but-nix@main
|
||||
with:
|
||||
hatchet-protocol: 'carve'
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: cachix/cachix-action@v16
|
||||
with:
|
||||
name: rde
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
extraPullNames: rstats-on-nix, nix-community
|
||||
|
||||
# Create a temporary directory with Python enabled
|
||||
- name: Setup test directory with Python enabled
|
||||
run: |
|
||||
TEST_DIR=$(mktemp -d)
|
||||
cp -r templates/rde/. "$TEST_DIR/"
|
||||
cd "$TEST_DIR"
|
||||
# Enable Python in the config (handle variations in whitespace)
|
||||
sed -i 's/python[[:space:]]*=[[:space:]]*false;/python = true;/' flake.nix
|
||||
# Verify the change was successful
|
||||
grep -q "python[[:space:]]*=[[:space:]]*true;" flake.nix || {
|
||||
echo "Error: Failed to enable Python in flake.nix"
|
||||
exit 1
|
||||
}
|
||||
echo "TEST_PYTHON_DIR=$TEST_DIR" >> $GITHUB_ENV
|
||||
|
||||
- name: Build with Python enabled
|
||||
run: |
|
||||
cd "$TEST_PYTHON_DIR"
|
||||
nix build
|
||||
|
||||
- name: Test Python commands are available
|
||||
run: |
|
||||
cd "$TEST_PYTHON_DIR"
|
||||
nix develop --command bash -c "which p-py && which p-ipy && which p-initPython"
|
||||
|
||||
- name: Test Python launches
|
||||
run: |
|
||||
cd "$TEST_PYTHON_DIR"
|
||||
nix develop --command bash -c "p-py --version"
|
||||
|
||||
- name: Test Python can execute code
|
||||
run: |
|
||||
cd "$TEST_PYTHON_DIR"
|
||||
nix develop --command bash -c "p-py -c 'print(1+1)'"
|
||||
|
||||
- name: Test UV package manager is available
|
||||
run: |
|
||||
cd "$TEST_PYTHON_DIR"
|
||||
nix develop --command bash -c "uv --version"
|
||||
|
||||
test-with-julia:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: wimpysworld/nothing-but-nix@main
|
||||
with:
|
||||
hatchet-protocol: 'carve'
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: cachix/cachix-action@v16
|
||||
with:
|
||||
name: rde
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
extraPullNames: rstats-on-nix, nix-community
|
||||
|
||||
# Create a temporary directory with Julia enabled
|
||||
- name: Setup test directory with Julia enabled
|
||||
run: |
|
||||
TEST_DIR=$(mktemp -d)
|
||||
cp -r templates/rde/. "$TEST_DIR/"
|
||||
cd "$TEST_DIR"
|
||||
# Enable Julia in the config (handle variations in whitespace)
|
||||
sed -i 's/julia[[:space:]]*=[[:space:]]*false;/julia = true;/' flake.nix
|
||||
# Verify the change was successful
|
||||
grep -q "julia[[:space:]]*=[[:space:]]*true;" flake.nix || {
|
||||
echo "Error: Failed to enable Julia in flake.nix"
|
||||
exit 1
|
||||
}
|
||||
echo "TEST_JULIA_DIR=$TEST_DIR" >> $GITHUB_ENV
|
||||
|
||||
- name: Build with Julia enabled
|
||||
run: |
|
||||
cd "$TEST_JULIA_DIR"
|
||||
nix build
|
||||
|
||||
- name: Test Julia commands are available
|
||||
run: |
|
||||
cd "$TEST_JULIA_DIR"
|
||||
nix develop --command bash -c "which p-jl && which p-initJl"
|
||||
|
||||
- name: Test Julia launches
|
||||
run: |
|
||||
cd "$TEST_JULIA_DIR"
|
||||
nix develop --command bash -c "p-jl --version"
|
||||
|
||||
- name: Test Julia can execute code
|
||||
run: |
|
||||
cd "$TEST_JULIA_DIR"
|
||||
nix develop --command bash -c "p-jl -e 'println(1+1)'"
|
||||
|
|
|
|||
9
.github/workflows/check_macos.yml
vendored
9
.github/workflows/check_macos.yml
vendored
|
|
@ -14,9 +14,14 @@ jobs:
|
|||
matrix:
|
||||
os: [macos-latest]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- uses: cachix/cachix-action@v16
|
||||
with:
|
||||
name: rde
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
extraPullNames: rstats-on-nix, nix-community
|
||||
- run: nix build ./templates/rde
|
||||
- run: nix build ./templates/ed
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ jobs:
|
|||
id-token: "write"
|
||||
contents: "read"
|
||||
steps:
|
||||
- uses: "actions/checkout@v5"
|
||||
- uses: "actions/checkout@v6"
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: "DeterminateSystems/determinate-nix-action@v3"
|
||||
|
|
|
|||
24
.github/workflows/update.yml
vendored
24
.github/workflows/update.yml
vendored
|
|
@ -3,23 +3,33 @@ name: update-flake-lock
|
|||
on:
|
||||
workflow_dispatch: # allows manual triggering
|
||||
schedule:
|
||||
- cron: '0 3 * * *'
|
||||
- cron: '0 6 * * *'
|
||||
|
||||
jobs:
|
||||
lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v5
|
||||
- name: Install Determinate Nix
|
||||
uses: DeterminateSystems/determinate-nix-action@v3
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
uses: actions/checkout@v6
|
||||
- uses: wimpysworld/nothing-but-nix@main
|
||||
with:
|
||||
hatchet-protocol: 'carve'
|
||||
- uses: cachix/install-nix-action@v31
|
||||
with:
|
||||
github_access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- uses: cachix/cachix-action@v16
|
||||
with:
|
||||
name: rde
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
extraPullNames: rstats-on-nix, nix-community
|
||||
- run: cd templates/rde/ && nix develop -c p-updateDeps
|
||||
- run: cd templates/ed/ && nix develop -c updateR
|
||||
- name: Update n flake.lock
|
||||
uses: DeterminateSystems/update-flake-lock@v27
|
||||
uses: DeterminateSystems/update-flake-lock@v28
|
||||
with:
|
||||
token: ${{ secrets.GH_TOKEN_FOR_UPDATES }}
|
||||
branch: update_rde
|
||||
path-to-flake-dir: "templates/rde"
|
||||
path-to-flake-dir: "templates/ed"
|
||||
pr-title: "Update RDE flake.lock" # Title of PR to be created
|
||||
pr-labels: | # Labels to be set on the PR
|
||||
dependencies
|
||||
|
|
|
|||
70
README.md
Normal file
70
README.md
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
# Nix Project Templates (np)
|
||||
|
||||
A collection of Nix flake templates for reproducible development environments.
|
||||
|
||||
## Templates
|
||||
|
||||
### RDE (Research Development Environment)
|
||||
|
||||
The default template for data science and research projects with support for R, Python, and Julia.
|
||||
|
||||
**Quick start:**
|
||||
```bash
|
||||
nix flake init -t github:dwinkler1/np#rde
|
||||
nix develop
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- 🔬 Multi-language support (R, Python, Julia)
|
||||
- 📦 Reproducible with Nix
|
||||
- 🎨 Neovim-based IDE with LSP support
|
||||
- 📊 Research-focused workflows
|
||||
- 🔧 Modular and customizable
|
||||
|
||||
See [templates/rde/README.md](templates/rde/README.md) for full documentation.
|
||||
|
||||
## CI/CD
|
||||
|
||||
All templates are automatically tested to ensure functionality:
|
||||
|
||||
- **Build Tests**: Templates build successfully on Linux and macOS
|
||||
- **Functionality Tests**: All commands and language support are verified
|
||||
- **Configuration Tests**: Multiple configurations (R, Python, Julia) are tested
|
||||
- **Automated Updates**: Dependencies are updated daily via automated PRs
|
||||
|
||||
### CI Workflows
|
||||
|
||||
- `.github/workflows/check.yml` - Comprehensive functionality tests (Ubuntu)
|
||||
- `.github/workflows/check_macos.yml` - macOS compatibility tests
|
||||
- `.github/workflows/update.yml` - Automated dependency updates
|
||||
|
||||
## Usage
|
||||
|
||||
1. **Initialize a new project:**
|
||||
```bash
|
||||
nix flake init -t github:dwinkler1/np#rde
|
||||
```
|
||||
|
||||
2. **Enter development environment:**
|
||||
```bash
|
||||
nix develop
|
||||
# or with direnv
|
||||
echo "use flake" > .envrc && direnv allow
|
||||
```
|
||||
|
||||
3. **Start working:**
|
||||
```bash
|
||||
p-initProject # Create project structure
|
||||
p # Launch Neovim
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please ensure:
|
||||
- All templates pass CI tests
|
||||
- Documentation is updated for new features
|
||||
- Code follows existing patterns
|
||||
|
||||
## License
|
||||
|
||||
See [LICENSE](LICENSE) file for details.
|
||||
|
|
@ -6,7 +6,11 @@
|
|||
path = ./templates/rde;
|
||||
description = "Research Development Environment";
|
||||
};
|
||||
ed = {
|
||||
path = ./templates/ed;
|
||||
description = "Simple nvim Environment";
|
||||
};
|
||||
defaultTemplate = self.templates.rde;
|
||||
};
|
||||
defaultTemplate = self.templates.ed;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
1
templates/ed/.envrc
Normal file
1
templates/ed/.envrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
use flake
|
||||
1
templates/ed/.gitignore
vendored
Normal file
1
templates/ed/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
.nvimcom
|
||||
148
templates/ed/flake.lock
generated
Normal file
148
templates/ed/flake.lock
generated
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
{
|
||||
"nodes": {
|
||||
"fran": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"rixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771133455,
|
||||
"narHash": "sha256-DvHfkW3DctWV+YnigY4+5Stn9NgI38JqR2IScXDX8z8=",
|
||||
"owner": "dwinkler1",
|
||||
"repo": "fran",
|
||||
"rev": "68b189ab981adae06590ee1929a70c8b86afd2b8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "dwinkler1",
|
||||
"repo": "fran",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1771043024,
|
||||
"narHash": "sha256-O1XDr7EWbRp+kHrNNgLWgIrB0/US5wvw9K6RERWAj6I=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3aadb7ca9eac2891d52a9dec199d9580a6e2bf44",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nvimConfig": {
|
||||
"inputs": {
|
||||
"fran": [
|
||||
"fran"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references",
|
||||
"plugins-r": "plugins-r",
|
||||
"rixpkgs": [
|
||||
"rixpkgs"
|
||||
],
|
||||
"wrappers": "wrappers"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1770172480,
|
||||
"narHash": "sha256-gem34C89cocBGuWLj7cdrAS5WkrOBp6V+ycQM/RhcCw=",
|
||||
"owner": "dwinkler1",
|
||||
"repo": "nvimConfig",
|
||||
"rev": "8f5c05252e914cb3738039a7ec13eb7d5955227a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "dwinkler1",
|
||||
"repo": "nvimConfig",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plugins-cmp-pandoc-references": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1743491695,
|
||||
"narHash": "sha256-XsdneGNJzmRBggk8lz9JNDQYk7wbYfUAF2oZLXzFb9c=",
|
||||
"owner": "jmbuhr",
|
||||
"repo": "cmp-pandoc-references",
|
||||
"rev": "130eae4f75029d6495808e0ea4b769fa1ce4c9ac",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "jmbuhr",
|
||||
"repo": "cmp-pandoc-references",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plugins-r": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1769736135,
|
||||
"narHash": "sha256-T4QgcBL+LCXvrEiRE2JW4jtUKl8DKzFHk8czGUO1jgY=",
|
||||
"owner": "R-nvim",
|
||||
"repo": "R.nvim",
|
||||
"rev": "2701ec64f5485e17c0e057081a9ae2058d776464",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "R-nvim",
|
||||
"repo": "R.nvim",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1770035835,
|
||||
"narHash": "sha256-Pi8f3LPTFmG7SZeAJEAamOWly1SZhEofT92uBqS4atY=",
|
||||
"owner": "rstats-on-nix",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0d3fe7afce51d2126fdccf0b717d8048b90e4781",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "rstats-on-nix",
|
||||
"ref": "2026-02-02",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"fran": "fran",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nvimConfig": "nvimConfig",
|
||||
"rixpkgs": "rixpkgs"
|
||||
}
|
||||
},
|
||||
"wrappers": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nvimConfig",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1769745458,
|
||||
"narHash": "sha256-Fq6THKEiAKx+wWQ4wTg9HvOAyD6i8JkWfHVQDZH7Byo=",
|
||||
"owner": "BirdeeHub",
|
||||
"repo": "nix-wrapper-modules",
|
||||
"rev": "cc5e052dd1e93ae75dc06e3fabf46f0820c272f2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "BirdeeHub",
|
||||
"repo": "nix-wrapper-modules",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
134
templates/ed/flake.nix
Normal file
134
templates/ed/flake.nix
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
{
|
||||
description = "Project Editor";
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
nvimConfig,
|
||||
...
|
||||
} @ inputs: let
|
||||
projectSettings = {pkgs}: {
|
||||
cats = {
|
||||
clickhouse = false;
|
||||
gitPlugins = false;
|
||||
julia = false;
|
||||
lua = false;
|
||||
markdown = false;
|
||||
nix = true;
|
||||
optional = false;
|
||||
python = false;
|
||||
r = false;
|
||||
};
|
||||
|
||||
settings = let
|
||||
# With `replace` packages are replaced otherwise they are merged with base packages
|
||||
replace = pkgs.lib.mkForce;
|
||||
in {
|
||||
lang_packages = {
|
||||
python = replace (
|
||||
(with pkgs.python3Packages; [
|
||||
duckdb
|
||||
polars
|
||||
])
|
||||
++ (
|
||||
if builtins.pathExists ./python-packages.nix
|
||||
# p: with p; [ ... ]
|
||||
then import ./python-packages.nix pkgs.python3Packages
|
||||
else []
|
||||
)
|
||||
);
|
||||
|
||||
r = replace (
|
||||
(with pkgs.rpkgs.rPackages; [
|
||||
fixest
|
||||
# pkgs.extraRPackages.musicMetadata
|
||||
])
|
||||
++ (
|
||||
if builtins.pathExists ./r-packages.nix
|
||||
# p: with p.rPackages; [ ... ]
|
||||
then import ./r-packages.nix pkgs.rpkgs
|
||||
else []
|
||||
)
|
||||
);
|
||||
|
||||
julia = replace ([
|
||||
"StatsBase"
|
||||
]
|
||||
++ (
|
||||
if builtins.pathExists ./julia-packages.nix
|
||||
# [ ... ]
|
||||
then import ./julia-packages.nix
|
||||
else []
|
||||
));
|
||||
};
|
||||
colorscheme = "kanagawa";
|
||||
background = "dark";
|
||||
wrapRc = true;
|
||||
};
|
||||
binName = "vv";
|
||||
|
||||
env = {
|
||||
IS_PROJECT_EDITOR = "1";
|
||||
R_LIBS_USER = "./.nvimcom";
|
||||
};
|
||||
|
||||
extraPackages = with pkgs; [
|
||||
cowsay
|
||||
];
|
||||
|
||||
specs.extraLua = let
|
||||
name = builtins.baseNameOf (builtins.toString ./.);
|
||||
in {
|
||||
data = pkgs.vimPlugins.mini-notify;
|
||||
before = ["INIT_MAIN"];
|
||||
config = ''
|
||||
require("mini.notify").setup()
|
||||
vim.notify = MiniNotify.make_notify()
|
||||
vim.notify("Welcome to ${name}!")
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
systems = nixpkgs.lib.systems.flakeExposed;
|
||||
forAllSystems = nixpkgs.lib.genAttrs systems;
|
||||
overlays = [inputs.nvimConfig.overlays.dependencies];
|
||||
in {
|
||||
packages = forAllSystems (system: let
|
||||
pkgs = import nixpkgs {inherit system overlays;};
|
||||
baseNvim = nvimConfig.packages.${system}.default;
|
||||
|
||||
nvim = (baseNvim.eval (projectSettings {inherit pkgs;})).config.wrapper;
|
||||
default = nvim;
|
||||
in {
|
||||
default = nvim;
|
||||
});
|
||||
|
||||
devShells = forAllSystems (system: let
|
||||
pkgs = import nixpkgs {inherit system overlays;};
|
||||
nv = self.packages.${system}.default;
|
||||
in {
|
||||
default = pkgs.mkShell {
|
||||
packages = [nv pkgs.updateR];
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
|
||||
rixpkgs.url = "github:dwinkler1/rixpkgs/nixpkgs";
|
||||
fran = {
|
||||
url = "github:dwinkler1/fran";
|
||||
inputs = {
|
||||
nixpkgs.follows = "rixpkgs";
|
||||
};
|
||||
};
|
||||
nvimConfig = {
|
||||
url = "github:dwinkler1/nvimConfig";
|
||||
inputs = {
|
||||
rixpkgs.follows = "rixpkgs";
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
fran.follows = "fran";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1 +1,3 @@
|
|||
export DIRENV_WARN_TIMEOUT=20s
|
||||
|
||||
use flake
|
||||
|
|
|
|||
378
templates/rde/README.md
Normal file
378
templates/rde/README.md
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
# Research Development Environment (RDE) Template
|
||||
|
||||
A modular Nix flake template for reproducible research environments with support for R, Python, and Julia. Designed for data science, statistical analysis, and computational research.
|
||||
|
||||
## Features
|
||||
|
||||
- 🔬 **Multi-language support**: R, Python, Julia with integrated tooling
|
||||
- 📦 **Reproducible**: Nix ensures consistent environments across machines
|
||||
- 🎨 **Neovim-based**: Powerful editor with LSP, completion, and more
|
||||
- 📊 **Research-focused**: Pre-configured for data analysis workflows
|
||||
- 🔧 **Modular**: Enable only the languages you need
|
||||
- 📝 **Documented**: Comprehensive inline documentation
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Initialize a new project with this template
|
||||
nix flake init -t github:dwinkler1/np#rde
|
||||
|
||||
# Enter the development environment
|
||||
nix develop
|
||||
|
||||
# Or use direnv for automatic activation
|
||||
echo "use flake" > .envrc
|
||||
direnv allow
|
||||
```
|
||||
|
||||
### First Steps
|
||||
|
||||
```bash
|
||||
# Initialize project structure (creates directories, git repo)
|
||||
p-initProject
|
||||
|
||||
# Enable Python (if needed)
|
||||
# Edit flake.nix: set enabledLanguages.python = true
|
||||
|
||||
# Initialize Python project
|
||||
p-initPython
|
||||
|
||||
# Update all dependencies
|
||||
p-updateDeps
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
The template is organized into several directories for better maintainability:
|
||||
|
||||
```
|
||||
templates/rde/
|
||||
├── flake.nix # Main flake configuration (261 lines)
|
||||
├── README.md # This file
|
||||
├── overlays/ # Nix overlays for packages
|
||||
│ ├── r.nix # R packages configuration
|
||||
│ ├── python.nix # Python packages configuration
|
||||
│ ├── rix.nix # rstats-on-nix integration
|
||||
│ ├── theme.nix # Neovim theme configuration
|
||||
│ └── project-scripts.nix # Project initialization scripts
|
||||
├── hosts/ # Host/command configurations
|
||||
│ ├── default.nix # Merges all host configs
|
||||
│ ├── python.nix # Python commands (marimo, ipy, etc.)
|
||||
│ ├── julia.nix # Julia commands (jl, pluto, etc.)
|
||||
│ ├── r.nix # R commands
|
||||
│ └── utils.nix # Utility commands (initProject, etc.)
|
||||
├── lib/ # Helper functions
|
||||
│ ├── shell-hook.nix # Dev shell welcome message
|
||||
│ └── mini-notify-config.lua # Neovim notification filtering
|
||||
└── scripts/ # Shell scripts
|
||||
├── initPython.sh # Initialize Python project
|
||||
├── initProject.sh # Initialize project structure
|
||||
├── updateDeps.sh # Update all dependencies
|
||||
└── activateDevenv.sh # Activate devenv shell
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Edit the `config` section in `flake.nix` to customize your environment:
|
||||
|
||||
### Basic Settings
|
||||
|
||||
```nix
|
||||
config = rec {
|
||||
# Name for your project commands (e.g., myproject-r, myproject-py)
|
||||
defaultPackageName = "p";
|
||||
|
||||
# Enable/disable language support
|
||||
enabledLanguages = {
|
||||
julia = false; # Julia with Pluto notebooks
|
||||
python = false; # Python with uv package manager
|
||||
r = true; # R with tidyverse and friends
|
||||
};
|
||||
|
||||
# Additional features
|
||||
enabledPackages = {
|
||||
gitPlugins = enabledLanguages.r; # R.nvim plugin
|
||||
devenv = false; # Additional dev environment
|
||||
};
|
||||
|
||||
# Neovim color scheme
|
||||
theme = rec {
|
||||
colorscheme = "kanagawa"; # cyberdream, onedark, tokyonight, kanagawa
|
||||
background = "dark"; # dark or light
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### Language-Specific Configuration
|
||||
|
||||
#### R Configuration
|
||||
|
||||
Edit `overlays/r.nix` to add/remove R packages:
|
||||
|
||||
```nix
|
||||
reqPkgs = with final.rpkgs.rPackages; [
|
||||
tidyverse # Add your packages here
|
||||
data_table
|
||||
# ... more packages
|
||||
];
|
||||
```
|
||||
|
||||
Or create `r-packages.nix` in your project:
|
||||
|
||||
```nix
|
||||
rpkgs: with rpkgs.rPackages; [
|
||||
ggplot2
|
||||
dplyr
|
||||
]
|
||||
```
|
||||
|
||||
#### Python Configuration
|
||||
|
||||
Python packages are managed via `uv`:
|
||||
|
||||
```bash
|
||||
# Add packages to your project
|
||||
uv add numpy pandas matplotlib
|
||||
|
||||
# Or edit pyproject.toml directly
|
||||
```
|
||||
|
||||
#### Julia Configuration
|
||||
|
||||
Julia packages use the built-in package manager:
|
||||
|
||||
```bash
|
||||
# In Julia REPL (p-jl)
|
||||
using Pkg
|
||||
Pkg.add("DataFrames")
|
||||
```
|
||||
|
||||
## Available Commands
|
||||
|
||||
Commands are prefixed with your `defaultPackageName` (default: `p`).
|
||||
|
||||
### Editor
|
||||
|
||||
- `p` or `p-pvim`: Launch Neovim
|
||||
- `p-g`: Launch Neovide (GUI)
|
||||
|
||||
### R (when enabled)
|
||||
|
||||
- `p-r`: R console with pre-loaded packages
|
||||
- Includes: tidyverse, data.table, languageserver, quarto
|
||||
|
||||
### Python (when enabled)
|
||||
|
||||
- `p-py`: Python interpreter
|
||||
- `p-ipy`: IPython REPL (enhanced interactive shell)
|
||||
- `p-marimo`: Marimo notebooks (reactive notebooks)
|
||||
- `p-initPython`: Initialize Python project with uv
|
||||
|
||||
### Julia (when enabled)
|
||||
|
||||
- `p-jl`: Julia REPL with project environment
|
||||
- `p-pluto`: Pluto.jl notebooks (reactive notebooks)
|
||||
- `p-initJl`: Initialize Julia project
|
||||
|
||||
### Utilities
|
||||
|
||||
- `p-initProject`: Create project directory structure
|
||||
- `p-updateDeps`: Update all dependencies (R, Python, Julia, flake)
|
||||
|
||||
## Project Workflow
|
||||
|
||||
### 1. Initialize Project
|
||||
|
||||
```bash
|
||||
# Create standardized directory structure
|
||||
p-initProject
|
||||
|
||||
# Creates:
|
||||
# - data/{raw,processed,interim}/
|
||||
# - docs/
|
||||
# - figures/
|
||||
# - tables/
|
||||
# - src/{analysis,data_prep,explore,utils}/
|
||||
# - .gitignore
|
||||
# - README.md
|
||||
```
|
||||
|
||||
### 2. Set Up Language Environment
|
||||
|
||||
**For R:**
|
||||
```bash
|
||||
# R is enabled by default
|
||||
# Just start using it
|
||||
p-r
|
||||
```
|
||||
|
||||
**For Python:**
|
||||
```bash
|
||||
# 1. Enable in flake.nix
|
||||
# 2. Initialize project
|
||||
p-initPython
|
||||
# 3. Add packages
|
||||
uv add numpy pandas scikit-learn
|
||||
```
|
||||
|
||||
**For Julia:**
|
||||
```bash
|
||||
# 1. Enable in flake.nix
|
||||
# 2. Initialize project
|
||||
p-initJl
|
||||
# 3. Packages are managed in Julia REPL
|
||||
```
|
||||
|
||||
### 3. Development
|
||||
|
||||
```bash
|
||||
# Start Neovim
|
||||
p
|
||||
|
||||
# Or use notebooks
|
||||
p-marimo # Python notebooks
|
||||
p-pluto # Julia notebooks
|
||||
|
||||
# R scripts work with p (Neovim has R support)
|
||||
```
|
||||
|
||||
### 4. Keep Dependencies Updated
|
||||
|
||||
```bash
|
||||
# Update everything at once
|
||||
p-updateDeps
|
||||
|
||||
# This updates:
|
||||
# - R packages (rixpkgs snapshot)
|
||||
# - Python packages (via uv)
|
||||
# - Julia packages (via Pkg)
|
||||
# - Flake inputs
|
||||
```
|
||||
|
||||
## Benefits of This Structure
|
||||
|
||||
1. **Modularity**: Each component is in its own file, making it easier to understand and modify
|
||||
2. **Maintainability**: Changes to one language or feature don't affect others
|
||||
3. **Readability**: Main flake.nix is ~261 lines instead of 688 (62% reduction)
|
||||
4. **Reusability**: Individual modules can be easily reused or replaced
|
||||
5. **Testability**: Smaller files are easier to test and debug
|
||||
6. **Documentation**: Comprehensive inline comments explain how everything works
|
||||
|
||||
## Extending the Template
|
||||
|
||||
### Add New R Packages
|
||||
|
||||
**System-wide** (edit `overlays/r.nix`):
|
||||
```nix
|
||||
reqPkgs = with final.rpkgs.rPackages; [
|
||||
tidyverse
|
||||
yourNewPackage # Add here
|
||||
];
|
||||
```
|
||||
|
||||
**Project-specific** (create `r-packages.nix`):
|
||||
```nix
|
||||
rpkgs: with rpkgs.rPackages; [
|
||||
projectSpecificPackage
|
||||
]
|
||||
```
|
||||
|
||||
### Add New Python Packages
|
||||
|
||||
```bash
|
||||
uv add package-name
|
||||
```
|
||||
|
||||
### Add New Commands
|
||||
|
||||
Edit the appropriate file in `hosts/`:
|
||||
- `hosts/python.nix` - Python commands
|
||||
- `hosts/julia.nix` - Julia commands
|
||||
- `hosts/r.nix` - R commands
|
||||
- `hosts/utils.nix` - General utilities
|
||||
|
||||
### Add New Scripts
|
||||
|
||||
1. Create script in `scripts/`
|
||||
2. Add to `overlays/project-scripts.nix`
|
||||
3. Add to appropriate host file
|
||||
|
||||
### Customize Neovim
|
||||
|
||||
The template uses a pre-configured Neovim (nixCats). To customize:
|
||||
- Edit theme in `config.theme` section
|
||||
- Add plugins in `flake.nix` categoryDefinitions
|
||||
- Modify LSP settings in `categoryDefinitions.lspsAndRuntimeDeps`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Nix Build Fails
|
||||
|
||||
```bash
|
||||
# Update flake inputs
|
||||
nix flake update
|
||||
|
||||
# Clear cache
|
||||
nix-collect-garbage
|
||||
```
|
||||
|
||||
### Python Packages Not Found
|
||||
|
||||
```bash
|
||||
# Sync environment
|
||||
uv sync
|
||||
|
||||
# Or re-initialize
|
||||
p-initPython
|
||||
```
|
||||
|
||||
### R Packages Not Available
|
||||
|
||||
```bash
|
||||
# Update R snapshot
|
||||
p-updateDeps
|
||||
|
||||
# Or check overlays/r.nix for package name
|
||||
```
|
||||
|
||||
## CI and Testing
|
||||
|
||||
This template is automatically tested on every change to ensure all functionality works correctly. The CI workflow (`.github/workflows/check.yml`) runs comprehensive tests including:
|
||||
|
||||
### Default Configuration Tests (R enabled)
|
||||
- ✅ Template builds successfully
|
||||
- ✅ Flake check passes
|
||||
- ✅ Development shell enters without errors
|
||||
- ✅ Neovim launches in headless mode
|
||||
- ✅ R console is available and runs code
|
||||
- ✅ Utility commands (initProject, updateDeps) are available
|
||||
- ✅ Project structure creation works correctly
|
||||
|
||||
### Python Configuration Tests
|
||||
- ✅ Template builds with Python enabled
|
||||
- ✅ Python commands (p-py, p-ipy, p-initPython) are available
|
||||
- ✅ Python interpreter launches and executes code
|
||||
|
||||
### Julia Configuration Tests
|
||||
- ✅ Template builds with Julia enabled
|
||||
- ✅ Julia commands (p-jl, p-initJl) are available
|
||||
- ✅ Julia REPL launches and executes code
|
||||
|
||||
The CI runs on:
|
||||
- Every push to template files (`.nix`, `.sh`, `.lua`, `flake.lock`)
|
||||
- Every pull request affecting the template
|
||||
- Manual dispatch for testing
|
||||
|
||||
This ensures that users can confidently use the template knowing that all advertised functionality has been verified.
|
||||
|
||||
## Usage
|
||||
|
||||
Use this template with:
|
||||
|
||||
```bash
|
||||
nix flake init -t github:dwinkler1/np#rde
|
||||
```
|
||||
|
||||
Then run `direnv allow` or enter the dev shell with `nix develop`.
|
||||
139
templates/rde/flake.lock
generated
139
templates/rde/flake.lock
generated
|
|
@ -1,24 +1,53 @@
|
|||
{
|
||||
"nodes": {
|
||||
"fran": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"rixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1771133455,
|
||||
"narHash": "sha256-DvHfkW3DctWV+YnigY4+5Stn9NgI38JqR2IScXDX8z8=",
|
||||
"owner": "dwinkler1",
|
||||
"repo": "fran",
|
||||
"rev": "68b189ab981adae06590ee1929a70c8b86afd2b8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "dwinkler1",
|
||||
"repo": "fran",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixCats": {
|
||||
"inputs": {
|
||||
"fran": [
|
||||
"fran"
|
||||
],
|
||||
"nixCats": "nixCats_2",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references",
|
||||
"plugins-cmp-r": "plugins-cmp-r",
|
||||
"plugins-r": "plugins-r",
|
||||
"plugins-cmp-pandoc-references": [
|
||||
"plugins-cmp-pandoc-references"
|
||||
],
|
||||
"plugins-cmp-r": [
|
||||
"plugins-cmp-r"
|
||||
],
|
||||
"plugins-r": [
|
||||
"plugins-r"
|
||||
],
|
||||
"rixpkgs": [
|
||||
"rixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1756388494,
|
||||
"narHash": "sha256-Y06QA/XZ8+4nmjwZfFUWMf80slfIxOnylLn8GCmXjew=",
|
||||
"lastModified": 1770172580,
|
||||
"narHash": "sha256-l/fKPLdKxq7PLRbExDxsS4Esel4yos/NFJOFcDpsm2E=",
|
||||
"owner": "dwinkler1",
|
||||
"repo": "nixCatsConfig",
|
||||
"rev": "c1aa16d681ac53298477e78097fefabdaacc16a7",
|
||||
"rev": "98079a0844e53afd0c593c8f4d1ee5381baf36f0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -29,11 +58,11 @@
|
|||
},
|
||||
"nixCats_2": {
|
||||
"locked": {
|
||||
"lastModified": 1756094250,
|
||||
"narHash": "sha256-Bkghd2NdQqQfKwSftABMDjnfRMFTJXA/XvvfKVonV/Q=",
|
||||
"lastModified": 1769085828,
|
||||
"narHash": "sha256-TjhFIAtS628+/r3IuYWPcNa++mUMMDDG8PbSfFHXBiA=",
|
||||
"owner": "BirdeeHub",
|
||||
"repo": "nixCats-nvim",
|
||||
"rev": "7496b06144a15e44301aacea31c3e1ccdb81546e",
|
||||
"rev": "43fbf4d12b0a613f1a792503da4bb2bf270173c7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -44,16 +73,16 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1756288264,
|
||||
"narHash": "sha256-Om8adB1lfkU7D33VpR+/haZ2gI5r3Q+ZbIPzE5sYnwE=",
|
||||
"lastModified": 1771043024,
|
||||
"narHash": "sha256-O1XDr7EWbRp+kHrNNgLWgIrB0/US5wvw9K6RERWAj6I=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ddd1826f294a0ee5fdc198ab72c8306a0ea73aa9",
|
||||
"rev": "3aadb7ca9eac2891d52a9dec199d9580a6e2bf44",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"ref": "nixos-25.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
|
@ -74,46 +103,14 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plugins-cmp-pandoc-references_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1743491695,
|
||||
"narHash": "sha256-XsdneGNJzmRBggk8lz9JNDQYk7wbYfUAF2oZLXzFb9c=",
|
||||
"owner": "jmbuhr",
|
||||
"repo": "cmp-pandoc-references",
|
||||
"rev": "130eae4f75029d6495808e0ea4b769fa1ce4c9ac",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "jmbuhr",
|
||||
"repo": "cmp-pandoc-references",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plugins-cmp-r": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1746709841,
|
||||
"narHash": "sha256-TwmLSILu1H3RyRivCQlbsgUN4dsEqO1E8Hx71N/lFws=",
|
||||
"lastModified": 1764700377,
|
||||
"narHash": "sha256-xb7VFWM/BKAkN7fg62y8n618t2qkQjdYbPwhBhLJwtk=",
|
||||
"owner": "R-nvim",
|
||||
"repo": "cmp-r",
|
||||
"rev": "602f399c4efde01147cadfebcc884b7aa154f8b7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "R-nvim",
|
||||
"repo": "cmp-r",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plugins-cmp-r_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1746709841,
|
||||
"narHash": "sha256-TwmLSILu1H3RyRivCQlbsgUN4dsEqO1E8Hx71N/lFws=",
|
||||
"owner": "R-nvim",
|
||||
"repo": "cmp-r",
|
||||
"rev": "602f399c4efde01147cadfebcc884b7aa154f8b7",
|
||||
"rev": "70bfe8f4c062acc10266e24825439c009a0b1b89",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -125,54 +122,44 @@
|
|||
"plugins-r": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1755532199,
|
||||
"narHash": "sha256-mb8HCaMasPUP9JZUkH1sPrtdbhM2HMUkJEKDsRt6wTs=",
|
||||
"lastModified": 1763419698,
|
||||
"narHash": "sha256-GUnRsFF6MlUcFfEsNmm0zXauG3+Pf22OOJNXszOvs+M=",
|
||||
"owner": "R-nvim",
|
||||
"repo": "R.nvim",
|
||||
"rev": "fd992e1c13ad3df794a30af2e937b994bf7bf4db",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "R-nvim",
|
||||
"repo": "R.nvim",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"plugins-r_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1755532199,
|
||||
"narHash": "sha256-mb8HCaMasPUP9JZUkH1sPrtdbhM2HMUkJEKDsRt6wTs=",
|
||||
"owner": "R-nvim",
|
||||
"repo": "R.nvim",
|
||||
"rev": "fd992e1c13ad3df794a30af2e937b994bf7bf4db",
|
||||
"rev": "b40fca202f26be4c83875dae489c655f2b834df6",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "R-nvim",
|
||||
"ref": "v0.99.1",
|
||||
"repo": "R.nvim",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1754915244,
|
||||
"narHash": "sha256-WtdFq/HbvAgq03AMhSAJW35go6R5bqhGNf2KBzXqH2U=",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/rstats-on-nix/nixpkgs/archive/2025-08-11.tar.gz"
|
||||
"lastModified": 1770035835,
|
||||
"narHash": "sha256-Pi8f3LPTFmG7SZeAJEAamOWly1SZhEofT92uBqS4atY=",
|
||||
"owner": "rstats-on-nix",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0d3fe7afce51d2126fdccf0b717d8048b90e4781",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/rstats-on-nix/nixpkgs/archive/2025-08-11.tar.gz"
|
||||
"owner": "rstats-on-nix",
|
||||
"ref": "2026-02-02",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"fran": "fran",
|
||||
"nixCats": "nixCats",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references_2",
|
||||
"plugins-cmp-r": "plugins-cmp-r_2",
|
||||
"plugins-r": "plugins-r_2",
|
||||
"plugins-cmp-pandoc-references": "plugins-cmp-pandoc-references",
|
||||
"plugins-cmp-r": "plugins-cmp-r",
|
||||
"plugins-r": "plugins-r",
|
||||
"rixpkgs": "rixpkgs"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,6 @@
|
|||
{
|
||||
description = "New Project";
|
||||
inputs = {
|
||||
rixpkgs.url = "https://github.com/rstats-on-nix/nixpkgs/archive/2025-08-11.tar.gz";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
nixCats = {
|
||||
url = "github:dwinkler1/nixCatsConfig";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.rixpkgs.follows = "rixpkgs";
|
||||
};
|
||||
## Git Plugins
|
||||
"plugins-r" = {
|
||||
url = "github:R-nvim/R.nvim";
|
||||
flake = false;
|
||||
};
|
||||
"plugins-cmp-r" = {
|
||||
url = "github:R-nvim/cmp-r";
|
||||
flake = false;
|
||||
};
|
||||
"plugins-cmp-pandoc-references" = {
|
||||
url = "github:jmbuhr/cmp-pandoc-references";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
|
||||
outputs = {
|
||||
self,
|
||||
nixpkgs,
|
||||
|
|
@ -39,7 +18,7 @@
|
|||
enabledLanguages = {
|
||||
julia = false;
|
||||
python = false;
|
||||
r = false;
|
||||
r = true;
|
||||
};
|
||||
## Enable packages
|
||||
enabledPackages = {
|
||||
|
|
@ -47,199 +26,52 @@
|
|||
### Always enable when R is enabled
|
||||
### You can use your own R installation and just enable the plugin
|
||||
gitPlugins = enabledLanguages.r;
|
||||
## Create additional dev shells in the project
|
||||
devenv = false;
|
||||
};
|
||||
};
|
||||
# R packages
|
||||
rixOverlay = final: prev: {rpkgs = inputs.rixpkgs.legacyPackages.${prev.system};};
|
||||
rOverlay = final: prev: let
|
||||
reqPkgs = with final.rpkgs.rPackages; [
|
||||
broom
|
||||
data_table
|
||||
janitor
|
||||
languageserver
|
||||
reprex
|
||||
styler
|
||||
tidyverse
|
||||
(buildRPackage {
|
||||
name = "nvimcom";
|
||||
src = inputs.plugins-r;
|
||||
sourceRoot = "source/nvimcom";
|
||||
buildInputs = with prev.rpkgs; [
|
||||
R
|
||||
stdenv.cc.cc
|
||||
gnumake
|
||||
];
|
||||
propagatedBuildInputs = [];
|
||||
theme = rec {
|
||||
## set colortheme and background here
|
||||
### "cyberdream", "onedark", and "tokyonight" are pre-installed
|
||||
colorscheme = "kanagawa";
|
||||
background = "dark";
|
||||
## Add other colortheme packages and config here
|
||||
## The default is a best guess
|
||||
extraColorschemePackage = rec {
|
||||
name = colorscheme;
|
||||
extraLua = ''
|
||||
vim.notify("Loading ${colorscheme} with extra config...")
|
||||
require('${name}').setup({
|
||||
commentStyle = {italic = false},
|
||||
keywordStyle = {italic = false},
|
||||
theme = 'dragon'
|
||||
})
|
||||
];
|
||||
in {
|
||||
quarto = final.rpkgs.quarto.override {extraRPackages = reqPkgs;};
|
||||
rWrapper = final.rpkgs.rWrapper.override {packages = reqPkgs;};
|
||||
'';
|
||||
plugin = name + "-nvim";
|
||||
};
|
||||
};
|
||||
|
||||
# Python packages
|
||||
pythonOverlay = final: prev: {
|
||||
python = prev.python3.withPackages (pyPackages:
|
||||
with pyPackages; [
|
||||
requests
|
||||
]);
|
||||
};
|
||||
|
||||
###################################
|
||||
## ⬆️ BASIC CONFIG ABOVE HERE ⬆️ ##
|
||||
###################################
|
||||
|
||||
projectScriptsOverlay = final: prev: let
|
||||
initPython = ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ ! -f "pyproject.toml" ]]; then
|
||||
echo "🐍 Initializing UV project..."
|
||||
uv init
|
||||
echo "📦 Adding IPython and Marimo..."
|
||||
uv add ipython
|
||||
uv add marimo
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "✅ Python project initialized!"
|
||||
echo "run 'uv add PACKAGE' to add more python packages."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
else
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "🔄 Existing Python project detected."
|
||||
echo "📦 Ensuring IPython and Marimo are installed..."
|
||||
uv add ipython
|
||||
uv add marimo
|
||||
echo "Run '${config.defaultPackageName}-updateDeps' to update dependencies."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
fi
|
||||
'';
|
||||
# Import overlays from separate files
|
||||
# Each overlay adds specific packages or configurations
|
||||
rOverlay = import ./overlays/r.nix;
|
||||
pythonOverlay = import ./overlays/python.nix;
|
||||
rixOverlay = import ./overlays/rix.nix inputs;
|
||||
extraPkgOverlay = import ./overlays/theme.nix config;
|
||||
projectScriptsOverlay = import ./overlays/project-scripts.nix config;
|
||||
|
||||
initProjectScript = ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
supportedSystems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
"aarch64-darwin"
|
||||
];
|
||||
forSystems = nixpkgs.lib.genAttrs supportedSystems;
|
||||
|
||||
PROJECT_NAME="''${1:-${config.defaultPackageName}}"
|
||||
|
||||
echo "🚀 Setting up project: $PROJECT_NAME"
|
||||
|
||||
# Create directory structure
|
||||
directories=(
|
||||
"data/raw"
|
||||
"data/processed"
|
||||
"data/interim"
|
||||
"docs"
|
||||
"figures"
|
||||
"tables"
|
||||
"src/analysis"
|
||||
"src/data_prep"
|
||||
"src/explore"
|
||||
"src/utils"
|
||||
)
|
||||
|
||||
for dir in "''${directories[@]}"; do
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
mkdir -p "$dir"
|
||||
echo "✓ Created $dir/"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create essential files
|
||||
if [[ ! -f "README.md" ]]; then
|
||||
cat > README.md << 'EOF'
|
||||
# RDE
|
||||
|
||||
## Project Structure
|
||||
- `data/`: Data files (gitignored)
|
||||
- `docs/`: Documentation
|
||||
- `figures/`: Output figures
|
||||
- `tables/`: Output tables
|
||||
- `src/`: Source code
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Initialize git
|
||||
if [[ ! -d ".git" ]]; then
|
||||
git init
|
||||
echo "✓ Initialized Git repository and added: flake.nix, flake.lock"
|
||||
fi
|
||||
# Check if files are already staged/tracked before adding
|
||||
if ! git diff --cached --name-only | grep -q "flake.nix\|flake.lock" &&
|
||||
! git ls-files --error-unmatch flake.nix flake.lock >/dev/null 2>&1; then
|
||||
echo "✓ Adding flake.nix, flake.lock to Git repository"
|
||||
git add flake.nix flake.lock
|
||||
else
|
||||
echo "✓ flake.nix, flake.lock already tracked/staged in Git"
|
||||
fi
|
||||
# Create .gitignore
|
||||
if [[ ! -f ".gitignore" ]]; then
|
||||
cat > .gitignore << 'EOF'
|
||||
# Data files
|
||||
data/
|
||||
*.csv
|
||||
*.docx
|
||||
*.xlsx
|
||||
*.parquet
|
||||
|
||||
# R specific
|
||||
.Rproj.user/
|
||||
.Rhistory
|
||||
.RData
|
||||
.Ruserdata
|
||||
*.Rproj
|
||||
.Rlibs/
|
||||
|
||||
# Python specific
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.pytest_cache/
|
||||
.venv/
|
||||
|
||||
# Jupyter
|
||||
.ipynb_checkpoints/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "✅ Project setup completed successfully!"
|
||||
'';
|
||||
|
||||
updateDepsScript = ''
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🔄 Updating project dependencies..."
|
||||
|
||||
if [[ -f "flake.lock" ]]; then
|
||||
nix flake update
|
||||
echo "✅ Flake inputs updated"
|
||||
fi
|
||||
|
||||
if [[ -f "pyproject.toml" ]]; then
|
||||
uv sync --upgrade
|
||||
echo "✅ Python dependencies updated"
|
||||
fi
|
||||
|
||||
if [[ -f "Project.toml" ]]; then
|
||||
${config.defaultPackageName}-jl -e "using Pkg; Pkg.update()"
|
||||
echo "✅ Julia dependencies updated"
|
||||
fi
|
||||
|
||||
echo "🎉 All dependencies updated!"
|
||||
'';
|
||||
in {
|
||||
initPython = prev.writeShellScriptBin "initPython" initPython;
|
||||
initProject = prev.writeShellScriptBin "initProject" initProjectScript;
|
||||
updateDeps = prev.writeShellScriptBin "updateDeps" updateDepsScript;
|
||||
};
|
||||
forSystems = nixpkgs.lib.genAttrs nixpkgs.lib.platforms.all;
|
||||
# Main package configuration
|
||||
# This configures the Neovim environment with language support
|
||||
projectConfig = forSystems (
|
||||
system: let
|
||||
inherit (nixCats) utils;
|
||||
|
|
@ -251,11 +83,14 @@
|
|||
prev.dependencyOverlays
|
||||
++ [
|
||||
(utils.standardPluginOverlay inputs)
|
||||
extraPkgOverlay
|
||||
rixOverlay
|
||||
inputs.fran.overlays.default
|
||||
rOverlay
|
||||
pythonOverlay
|
||||
projectScriptsOverlay
|
||||
];
|
||||
|
||||
categoryDefinitions = utils.mergeCatDefs prev.categoryDefinitions (
|
||||
{
|
||||
pkgs,
|
||||
|
|
@ -266,28 +101,17 @@
|
|||
mkPlugin,
|
||||
...
|
||||
} @ packageDef: {
|
||||
# Language servers and runtime dependencies
|
||||
lspsAndRuntimeDeps = {
|
||||
project = with pkgs; [
|
||||
];
|
||||
julia = with pkgs; [
|
||||
julia-bin
|
||||
];
|
||||
python = with pkgs; [
|
||||
python
|
||||
nodejs
|
||||
pyright
|
||||
uv
|
||||
];
|
||||
r = with pkgs; [
|
||||
rWrapper
|
||||
quarto
|
||||
air-formatter
|
||||
];
|
||||
project = with pkgs; [];
|
||||
julia = with pkgs; [julia-bin];
|
||||
python = with pkgs; [python nodejs basedpyright uv];
|
||||
r = with pkgs; [rWrapper quarto air-formatter];
|
||||
};
|
||||
|
||||
# Plugins that load automatically
|
||||
startupPlugins = {
|
||||
project = with pkgs.vimPlugins; [
|
||||
];
|
||||
project = with pkgs.vimPlugins; [pkgs.extraTheme];
|
||||
gitPlugins = with pkgs.neovimPlugins; [
|
||||
{
|
||||
plugin = r;
|
||||
|
|
@ -296,63 +120,44 @@
|
|||
];
|
||||
};
|
||||
|
||||
# Plugins that load on-demand
|
||||
optionalPlugins = {
|
||||
project = with pkgs.vimPlugins; [
|
||||
];
|
||||
project = with pkgs.vimPlugins; [];
|
||||
gitPlugins = with pkgs.neovimPlugins; [
|
||||
cmp-r
|
||||
cmp-pandoc-references
|
||||
];
|
||||
};
|
||||
|
||||
# Lua code to run before main config
|
||||
optionalLuaPreInit = {
|
||||
project = [
|
||||
''
|
||||
local predicate = function(notif)
|
||||
if not (notif.data.source == "lsp_progress" and notif.data.client_name == "lua_ls") then
|
||||
return true
|
||||
end
|
||||
-- Filter out some LSP progress notifications from 'lua_ls'
|
||||
return notif.msg:find("Diagnosing") == nil and notif.msg:find("semantic tokens") == nil
|
||||
end
|
||||
local custom_sort = function(notif_arr)
|
||||
return MiniNotify.default_sort(vim.tbl_filter(predicate, notif_arr))
|
||||
end
|
||||
require("mini.notify").setup({ content = { sort = custom_sort } })
|
||||
vim.notify = MiniNotify.make_notify()
|
||||
''
|
||||
(builtins.readFile ./lib/mini-notify-config.lua)
|
||||
];
|
||||
};
|
||||
optionalLuaAdditions = {
|
||||
project = [
|
||||
"vim.notify('Project loaded: ${name}')"
|
||||
];
|
||||
};
|
||||
sharedLibraries = {
|
||||
project = {
|
||||
};
|
||||
};
|
||||
|
||||
# Lua code to run after main config
|
||||
optionalLuaAdditions = {
|
||||
project = ["vim.notify('Project loaded: ${name}')"];
|
||||
};
|
||||
|
||||
sharedLibraries = {
|
||||
project = {};
|
||||
};
|
||||
|
||||
# Environment variables for each language
|
||||
environmentVariables = {
|
||||
project = {
|
||||
};
|
||||
julia = {
|
||||
JULIA_NUM_THREADS = "auto";
|
||||
};
|
||||
project = {};
|
||||
julia = {JULIA_NUM_THREADS = "auto";};
|
||||
python = {
|
||||
# Prevent uv from managing Python downloads
|
||||
UV_PYTHON_DOWNLOADS = "never";
|
||||
# Force uv to use nixpkgs Python interpreter
|
||||
UV_PYTHON = pkgs.python.interpreter;
|
||||
};
|
||||
r = {
|
||||
R_LIBS_USER = "./.Rlibs";
|
||||
};
|
||||
r = {R_LIBS_USER = "./.Rlibs";};
|
||||
};
|
||||
|
||||
extraWrapperArgs = {
|
||||
python = [
|
||||
"--unset PYTHONPATH"
|
||||
];
|
||||
python = ["--unset PYTHONPATH"];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
@ -360,6 +165,8 @@
|
|||
packageDefinitions =
|
||||
prev.packageDefinitions
|
||||
// {
|
||||
# Main package definition
|
||||
# This creates the command with configured languages and tools
|
||||
"${config.defaultPackageName}" = utils.mergeCatDefs prev.packageDefinitions.n (
|
||||
{
|
||||
pkgs,
|
||||
|
|
@ -369,133 +176,19 @@
|
|||
settings = {
|
||||
suffix-path = false;
|
||||
suffix-LD = false;
|
||||
# your alias may not conflict with your other packages.
|
||||
aliases = ["pvim"];
|
||||
hosts = {
|
||||
g = {
|
||||
enable = true;
|
||||
path = {
|
||||
value = "${pkgs.neovide}/bin/neovide";
|
||||
args = [
|
||||
"--add-flags"
|
||||
"--neovim-bin ${name}"
|
||||
];
|
||||
};
|
||||
};
|
||||
m = let
|
||||
marimoInit = ''
|
||||
set -euo pipefail
|
||||
if [[ ! -f "pyproject.toml" ]]; then
|
||||
echo "🐍 Initializing UV project..."
|
||||
uv init
|
||||
echo "📦 Adding Marimo..."
|
||||
uv add marimo
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "✅ Python project initialized!"
|
||||
echo "run 'uv add PACKAGE' to add more python packages."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
else
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "🔄 Syncing existing project..."
|
||||
uv sync
|
||||
echo "🐍 Launching Marimo..."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
enable = config.enabledLanguages.python;
|
||||
path = {
|
||||
value = "${pkgs.uv}/bin/uv";
|
||||
args = [
|
||||
"--run"
|
||||
"${marimoInit}"
|
||||
"--add-flags"
|
||||
"run marimo edit \"$@\""
|
||||
];
|
||||
};
|
||||
};
|
||||
py = let
|
||||
ipythonInit = ''
|
||||
set -euo pipefail
|
||||
if [[ ! -f "pyproject.toml" ]]; then
|
||||
echo "🐍 Initializing UV project..."
|
||||
uv init
|
||||
echo "📦 Adding IPython..."
|
||||
uv add ipython
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "✅ Python project initialized!"
|
||||
echo "run 'uv add PACKAGE' to add more python packages."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
else
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "🔄 Syncing existing project..."
|
||||
echo "📦 Ensuring IPython is installed..."
|
||||
uv add ipython
|
||||
uv sync
|
||||
echo "🐍 Launching IPython..."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
enable = config.enabledLanguages.python;
|
||||
path = {
|
||||
value = "${pkgs.uv}/bin/uv";
|
||||
args = [
|
||||
"--run"
|
||||
"${ipythonInit}"
|
||||
"--add-flags"
|
||||
"run ipython \"$@\""
|
||||
];
|
||||
};
|
||||
};
|
||||
jl = {
|
||||
enable = config.enabledLanguages.julia;
|
||||
path = {
|
||||
value = "${pkgs.julia-bin}/bin/julia";
|
||||
args = ["--add-flags" "--project=."];
|
||||
};
|
||||
};
|
||||
initJl = {
|
||||
enable = config.enabledLanguages.julia;
|
||||
path = {
|
||||
value = "${pkgs.julia-bin}/bin/julia";
|
||||
args = ["--add-flags" "--project=. -e 'using Pkg; Pkg.instantiate()'"];
|
||||
};
|
||||
};
|
||||
r = {
|
||||
enable = config.enabledLanguages.r;
|
||||
path = {
|
||||
value = "${pkgs.rWrapper}/bin/R";
|
||||
args = ["--add-flags" "--no-save --no-restore"];
|
||||
};
|
||||
};
|
||||
initPython = {
|
||||
enable = config.enabledLanguages.python;
|
||||
path.value = "${pkgs.initPython}/bin/initPython";
|
||||
};
|
||||
initProject = {
|
||||
enable = true;
|
||||
path = {
|
||||
value = "${pkgs.initProject}/bin/initProject";
|
||||
};
|
||||
};
|
||||
updateDeps = {
|
||||
enable = true;
|
||||
path = {
|
||||
value = "${pkgs.updateDeps}/bin/updateDeps";
|
||||
};
|
||||
};
|
||||
node.enable = true;
|
||||
perl.enable = true;
|
||||
ruby.enable = true;
|
||||
};
|
||||
# Import all host commands from hosts/ directory
|
||||
hosts = import ./hosts config pkgs;
|
||||
};
|
||||
# Enable/disable features based on config
|
||||
categories = {
|
||||
julia = config.enabledLanguages.julia;
|
||||
python = config.enabledLanguages.python;
|
||||
r = config.enabledLanguages.r;
|
||||
project = true;
|
||||
gitPlugins = config.enabledPackages.gitPlugins;
|
||||
background = config.theme.background;
|
||||
colorscheme = config.theme.colorscheme;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
|
@ -506,41 +199,68 @@
|
|||
);
|
||||
in {
|
||||
packages = projectConfig;
|
||||
# Development shell configuration
|
||||
devShells = forSystems (system: let
|
||||
pkgs = import nixpkgs {inherit system;};
|
||||
# Language-specific packages that should be available in shell
|
||||
languagePackages = with pkgs;
|
||||
[]
|
||||
++ (if config.enabledLanguages.r then [quarto] else [])
|
||||
++ (if config.enabledLanguages.python then [uv] else [])
|
||||
++ (if config.enabledLanguages.julia then [] else []);
|
||||
in {
|
||||
default = let
|
||||
shellCmds = pkgs.lib.concatLines (pkgs.lib.filter (cmd: cmd != "") [
|
||||
(pkgs.lib.optionalString config.enabledLanguages.r " - ${config.defaultPackageName}-r: Launch R console")
|
||||
(pkgs.lib.optionalString config.enabledLanguages.julia " - ${config.defaultPackageName}-jl: Launch Julia REPL")
|
||||
(pkgs.lib.optionalString config.enabledLanguages.julia " - ${config.defaultPackageName}-initJl: Init existing Julia project")
|
||||
(pkgs.lib.optionalString config.enabledLanguages.python " - ${config.defaultPackageName}-m: Launch Marimo notebook")
|
||||
(pkgs.lib.optionalString config.enabledLanguages.python " - ${config.defaultPackageName}-py: Launch IPython REPL")
|
||||
(pkgs.lib.optionalString config.enabledLanguages.python " - ${config.defaultPackageName}-initPython: Init python project")
|
||||
" "
|
||||
"To adjust options run: ${config.defaultPackageName} flake.nix"
|
||||
]);
|
||||
in
|
||||
pkgs.mkShell {
|
||||
default = pkgs.mkShell {
|
||||
name = config.defaultPackageName;
|
||||
packages = [projectConfig.${system}.default];
|
||||
packages = [projectConfig.${system}.default] ++ languagePackages;
|
||||
inputsFrom = [];
|
||||
shellHook = ''
|
||||
echo ""
|
||||
echo "=========================================================================="
|
||||
echo "🎯 ${config.defaultPackageName} Development Environment"
|
||||
echo "---"
|
||||
echo "📝 Run '${config.defaultPackageName}-initProject' to set up project structure"
|
||||
echo "🔄 Run '${config.defaultPackageName}-updateDeps' to update all dependencies"
|
||||
echo "---"
|
||||
echo "🚀 Available commands:"
|
||||
echo " - ${config.defaultPackageName}: Launch Neovim"
|
||||
echo " - ${config.defaultPackageName}-g: Launch Neovide"
|
||||
echo "${shellCmds}"
|
||||
echo "=========================================================================="
|
||||
echo ""
|
||||
'';
|
||||
# Welcome message when entering the shell
|
||||
shellHook = import ./lib/shell-hook.nix config pkgs;
|
||||
};
|
||||
});
|
||||
};
|
||||
inputs = {
|
||||
rixpkgs.url = "github:rstats-on-nix/nixpkgs/2026-02-02";
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
|
||||
nixCats = {
|
||||
url = "github:dwinkler1/nixCatsConfig";
|
||||
inputs = {
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
rixpkgs.follows = "rixpkgs";
|
||||
fran.follows = "fran";
|
||||
plugins-cmp-pandoc-references.follows = "plugins-cmp-pandoc-references";
|
||||
plugins-cmp-r.follows = "plugins-cmp-r";
|
||||
plugins-r.follows = "plugins-r";
|
||||
};
|
||||
};
|
||||
## Extra R packages
|
||||
fran = {
|
||||
url = "github:dwinkler1/fran";
|
||||
inputs = {
|
||||
nixpkgs.follows = "rixpkgs";
|
||||
};
|
||||
};
|
||||
## Git Plugins
|
||||
"plugins-r" = {
|
||||
url = "github:R-nvim/R.nvim/v0.99.1";
|
||||
flake = false;
|
||||
};
|
||||
"plugins-cmp-r" = {
|
||||
url = "github:R-nvim/cmp-r";
|
||||
flake = false;
|
||||
};
|
||||
"plugins-cmp-pandoc-references" = {
|
||||
url = "github:jmbuhr/cmp-pandoc-references";
|
||||
flake = false;
|
||||
};
|
||||
};
|
||||
nixConfig = {
|
||||
extra-substituters = [
|
||||
"https://rstats-on-nix.cachix.org"
|
||||
"https://rde.cachix.org"
|
||||
];
|
||||
extra-trusted-public-keys = [
|
||||
"rstats-on-nix.cachix.org-1:vdiiVgocg6WeJrODIqdprZRUrhi1JzhBnXv7aWI6+F0="
|
||||
"rde.cachix.org-1:yRxQYM+69N/dVER6HNWRjsjytZnJVXLS/+t/LI9d1D4="
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
27
templates/rde/hosts/default.nix
Normal file
27
templates/rde/hosts/default.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Merges all host configurations from separate modules
|
||||
#
|
||||
# This file combines host definitions from language-specific modules.
|
||||
# It serves as the single entry point for all command definitions.
|
||||
#
|
||||
# Structure:
|
||||
# - python.nix: Python commands (marimo, ipy, py, initPython)
|
||||
# - julia.nix: Julia commands (jl, pluto, initJl)
|
||||
# - r.nix: R commands (r console)
|
||||
# - utils.nix: Utility commands (initProject, updateDeps, etc.)
|
||||
#
|
||||
# Usage:
|
||||
# This file is imported in flake.nix:
|
||||
# hosts = import ./hosts config pkgs;
|
||||
#
|
||||
# The merged result provides all commands in a single attribute set.
|
||||
# Commands are enabled/disabled based on config.enabledLanguages settings.
|
||||
config: pkgs: let
|
||||
# Import individual host modules
|
||||
pythonHosts = import ./python.nix config pkgs;
|
||||
juliaHosts = import ./julia.nix config pkgs;
|
||||
rHosts = import ./r.nix config pkgs;
|
||||
utilsHosts = import ./utils.nix config pkgs;
|
||||
in
|
||||
# Merge all hosts into single attribute set
|
||||
# Later definitions override earlier ones in case of conflicts
|
||||
pythonHosts // juliaHosts // rHosts // utilsHosts
|
||||
66
templates/rde/hosts/julia.nix
Normal file
66
templates/rde/hosts/julia.nix
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Julia-related host configurations
|
||||
#
|
||||
# This module defines all Julia-related commands available in the dev shell.
|
||||
# Julia is configured with project-local package management.
|
||||
#
|
||||
# Available commands (when Julia is enabled):
|
||||
# - <name>-jl: Launch Julia REPL with project environment
|
||||
# - <name>-pluto: Launch Pluto.jl notebook server
|
||||
# - <name>-initJl: Initialize Julia project and install Pluto
|
||||
#
|
||||
# How it works:
|
||||
# - All commands use --project=. to activate local Project.toml
|
||||
# - JULIA_NUM_THREADS=auto enables multi-threading
|
||||
# - Packages are managed via Julia's built-in Pkg manager
|
||||
#
|
||||
# Project setup:
|
||||
# 1. Run <name>-initJl to create Project.toml
|
||||
# 2. Add packages: julia --project=. -e 'using Pkg; Pkg.add("PackageName")'
|
||||
# 3. Packages are stored in Project.toml and Manifest.toml
|
||||
#
|
||||
# Dependencies: julia-bin (configured in flake.nix)
|
||||
config: pkgs: {
|
||||
# jl: Julia REPL with project environment
|
||||
# Activates local Project.toml for package management
|
||||
# Use Pkg.add("PackageName") to install packages
|
||||
jl = {
|
||||
enable = config.enabledLanguages.julia;
|
||||
path = {
|
||||
value = "${pkgs.julia-bin}/bin/julia";
|
||||
args = ["--add-flags" "--project=."];
|
||||
};
|
||||
};
|
||||
|
||||
# initJl: Initialize Julia project
|
||||
# Creates Project.toml and installs Pluto.jl notebook
|
||||
# Run this once to set up Julia package management
|
||||
initJl = {
|
||||
enable = config.enabledLanguages.julia;
|
||||
path = {
|
||||
value = "${pkgs.julia-bin}/bin/julia";
|
||||
args = ["--add-flags" "--project=. -e 'using Pkg; Pkg.instantiate(); Pkg.add(\"Pluto\")'"];
|
||||
};
|
||||
};
|
||||
|
||||
# pluto: Launch Pluto.jl interactive notebook
|
||||
# Auto-installs Pluto if not present in Project.toml
|
||||
# Opens browser with notebook interface
|
||||
# Notebooks are reactive - cells update automatically
|
||||
pluto = let
|
||||
runPluto = ''
|
||||
import Pkg; import TOML; Pkg.instantiate();
|
||||
proj = isfile("Project.toml") ? TOML.parsefile(Base.active_project()) : Dict();
|
||||
deps = get(proj, "deps", Dict());
|
||||
if !haskey(deps, "Pluto")
|
||||
Pkg.add("Pluto");
|
||||
end
|
||||
import Pluto; Pluto.run();
|
||||
'';
|
||||
in {
|
||||
enable = config.enabledLanguages.julia;
|
||||
path = {
|
||||
value = "${pkgs.julia-bin}/bin/julia";
|
||||
args = ["--add-flags" "--project=. -e '${runPluto}'"];
|
||||
};
|
||||
};
|
||||
}
|
||||
96
templates/rde/hosts/python.nix
Normal file
96
templates/rde/hosts/python.nix
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Python-related host configurations
|
||||
#
|
||||
# This module defines all Python-related commands available in the dev shell.
|
||||
# Each command is configured with enable conditions and execution paths.
|
||||
#
|
||||
# Available commands (when Python is enabled):
|
||||
# - <name>-marimo: Launch Marimo notebook (interactive Python notebooks)
|
||||
# - <name>-py: Run Python interpreter
|
||||
# - <name>-ipy: Launch IPython REPL (enhanced interactive shell)
|
||||
# - <name>-initPython: Initialize Python project with uv
|
||||
#
|
||||
# How it works:
|
||||
# - Commands are enabled based on config.enabledLanguages.python
|
||||
# - UV (Python package manager) handles project dependencies
|
||||
# - Each command auto-initializes project if pyproject.toml doesn't exist
|
||||
#
|
||||
# Dependencies: uv, python, nodejs, basedpyright (configured in flake.nix)
|
||||
config: pkgs: {
|
||||
# Marimo: Interactive notebook environment for Python
|
||||
# Auto-initializes UV project and installs marimo on first run
|
||||
marimo = let
|
||||
marimoInit = ''
|
||||
set -euo pipefail
|
||||
if [[ ! -f "pyproject.toml" ]]; then
|
||||
echo "🐍 Initializing UV project..."
|
||||
uv init
|
||||
echo "📦 Adding Marimo..."
|
||||
uv add marimo
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "✅ Python project initialized!"
|
||||
echo "run 'uv add PACKAGE' to add more python packages."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
else
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "🔄 Syncing existing project..."
|
||||
uv sync
|
||||
echo "🐍 Launching Marimo..."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
fi
|
||||
uv run marimo edit "$@"
|
||||
'';
|
||||
in {
|
||||
enable = config.enabledLanguages.python;
|
||||
path = {
|
||||
value = "${pkgs.writeShellScriptBin "marimo-wrapper" marimoInit}/bin/marimo-wrapper";
|
||||
};
|
||||
};
|
||||
|
||||
# py: Standard Python interpreter
|
||||
# Direct access to Python REPL for quick experiments
|
||||
py = {
|
||||
enable = config.enabledLanguages.python;
|
||||
path = {
|
||||
value = "${pkgs.python.interpreter}";
|
||||
};
|
||||
};
|
||||
|
||||
# ipy: IPython - Enhanced interactive Python shell
|
||||
# Features: syntax highlighting, tab completion, magic commands
|
||||
# Auto-initializes UV project and installs IPython on first run
|
||||
ipy = let
|
||||
ipythonInit = ''
|
||||
set -euo pipefail
|
||||
if [[ ! -f "pyproject.toml" ]]; then
|
||||
echo "🐍 Initializing UV project..."
|
||||
uv init
|
||||
echo "📦 Adding IPython..."
|
||||
uv add ipython
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "✅ Python project initialized!"
|
||||
echo "run 'uv add PACKAGE' to add more python packages."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
else
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "🔄 Syncing existing project..."
|
||||
uv sync
|
||||
echo "🐍 Launching IPython..."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
fi
|
||||
uv run ipython "$@"
|
||||
'';
|
||||
in {
|
||||
enable = config.enabledLanguages.python;
|
||||
path = {
|
||||
value = "${pkgs.writeShellScriptBin "ipy-wrapper" ipythonInit}/bin/ipy-wrapper";
|
||||
};
|
||||
};
|
||||
|
||||
# initPython: Initialize Python project
|
||||
# Creates pyproject.toml and adds IPython and Marimo
|
||||
# Use this to set up Python tooling in an existing project
|
||||
initPython = {
|
||||
enable = config.enabledLanguages.python;
|
||||
path.value = "${pkgs.initPython}/bin/initPython";
|
||||
};
|
||||
}
|
||||
31
templates/rde/hosts/r.nix
Normal file
31
templates/rde/hosts/r.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# R-related host configurations
|
||||
#
|
||||
# This module defines R-related commands available in the dev shell.
|
||||
# R is configured with project-local package library and Quarto support.
|
||||
#
|
||||
# Available commands (when R is enabled):
|
||||
# - <name>-r: Launch R console with packages
|
||||
#
|
||||
# How it works:
|
||||
# - Uses rWrapper which includes all packages from overlays/r.nix
|
||||
# - R_LIBS_USER=./.Rlibs enables project-local package installation
|
||||
# - --no-save --no-restore ensures clean session startup
|
||||
#
|
||||
# Package management:
|
||||
# - System packages: Edit overlays/r.nix
|
||||
# - Project packages: Install with install.packages() in R
|
||||
# - Custom packages: Create r-packages.nix in project root
|
||||
#
|
||||
# Dependencies: rWrapper, quarto, air-formatter (configured in flake.nix)
|
||||
config: pkgs: {
|
||||
# r: R console with pre-configured packages
|
||||
# Includes tidyverse, data.table, and other common packages
|
||||
# Session starts without saving/restoring workspace
|
||||
r = {
|
||||
enable = config.enabledLanguages.r;
|
||||
path = {
|
||||
value = "${pkgs.rWrapper}/bin/R";
|
||||
args = ["--add-flags" "--no-save --no-restore"];
|
||||
};
|
||||
};
|
||||
}
|
||||
90
templates/rde/hosts/utils.nix
Normal file
90
templates/rde/hosts/utils.nix
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# Utility and common host configurations
|
||||
#
|
||||
# This module defines general-purpose commands and utilities.
|
||||
# These commands are available regardless of enabled languages.
|
||||
#
|
||||
# Available commands:
|
||||
# - <name>: Launch Neovim editor (default command)
|
||||
# - <name>-g: Launch Neovide (GUI for Neovim)
|
||||
# - <name>-initProject: Initialize project directory structure
|
||||
# - <name>-updateDeps: Update all dependencies (R, Python, Julia, flake)
|
||||
# - <name>-initDevenv: Initialize devenv project (if enabled)
|
||||
# - <name>-devenv: Run devenv commands (if enabled)
|
||||
# - <name>-activateDevenv: Activate devenv shell (if enabled)
|
||||
#
|
||||
# Note: node, perl, ruby are also available but have minimal configuration
|
||||
#
|
||||
# Dependencies: neovide, devenv (if enabled), project scripts
|
||||
config: pkgs: {
|
||||
# g: Neovide - GUI frontend for Neovim
|
||||
# Provides smooth scrolling, animations, and GUI features
|
||||
# Automatically connects to the configured Neovim instance
|
||||
g = {
|
||||
enable = true;
|
||||
path = {
|
||||
value = "${pkgs.neovide}/bin/neovide";
|
||||
args = [
|
||||
"--add-flags"
|
||||
"--neovim-bin ${config.defaultPackageName}"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# initProject: Initialize research project structure
|
||||
# Creates standardized directory layout for data analysis
|
||||
# Sets up: data/, docs/, figures/, tables/, src/
|
||||
# Also initializes git repository and .gitignore
|
||||
initProject = {
|
||||
enable = true;
|
||||
path = {
|
||||
value = "${pkgs.initProject}/bin/initProject";
|
||||
};
|
||||
};
|
||||
|
||||
# initDevenv: Initialize devenv project
|
||||
# Devenv provides additional development environment features
|
||||
# Only available if config.enabledPackages.devenv = true
|
||||
initDevenv = {
|
||||
enable = config.enabledPackages.devenv;
|
||||
path = {
|
||||
value = "${pkgs.devenv}/bin/devenv";
|
||||
args = ["--add-flags" "init"];
|
||||
};
|
||||
};
|
||||
|
||||
# activateDevenv: Activate devenv shell
|
||||
# Automatically runs when entering dev shell if devenv.nix exists
|
||||
# Only available if config.enabledPackages.devenv = true
|
||||
activateDevenv = {
|
||||
enable = config.enabledPackages.devenv;
|
||||
path = {
|
||||
value = "${pkgs.activateDevenv}/bin/activateDevenv";
|
||||
};
|
||||
};
|
||||
|
||||
# devenv: Run devenv commands
|
||||
# Access to full devenv CLI for managing development environments
|
||||
# Only available if config.enabledPackages.devenv = true
|
||||
devenv = {
|
||||
enable = config.enabledPackages.devenv;
|
||||
path = {
|
||||
value = "${pkgs.devenv}/bin/devenv";
|
||||
};
|
||||
};
|
||||
|
||||
# updateDeps: Update all project dependencies
|
||||
# Updates: R packages (rixpkgs), Python (uv), Julia (Pkg), flake inputs
|
||||
# Automatically detects which languages are in use
|
||||
updateDeps = {
|
||||
enable = true;
|
||||
path = {
|
||||
value = "${pkgs.updateDeps}/bin/updateDeps";
|
||||
};
|
||||
};
|
||||
|
||||
# Additional language runtimes with minimal configuration
|
||||
# These are available but not heavily used by this template
|
||||
node.enable = true; # Node.js runtime (used by some LSPs)
|
||||
perl.enable = true; # Perl runtime
|
||||
ruby.enable = true; # Ruby runtime
|
||||
}
|
||||
42
templates/rde/lib/mini-notify-config.lua
Normal file
42
templates/rde/lib/mini-notify-config.lua
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
-- Neovim notification configuration using mini.notify
|
||||
--
|
||||
-- This file configures the mini.notify plugin to filter out verbose LSP messages.
|
||||
-- It reduces noise from the Lua language server during development.
|
||||
--
|
||||
-- What it does:
|
||||
-- - Sets up mini.notify as the notification handler
|
||||
-- - Filters out "Diagnosing" and "semantic tokens" messages from lua_ls
|
||||
-- - Keeps all other notifications visible
|
||||
--
|
||||
-- Usage:
|
||||
-- Loaded automatically via flake.nix:
|
||||
-- optionalLuaPreInit.project = [(builtins.readFile ./lib/mini-notify-config.lua)]
|
||||
--
|
||||
-- Customization:
|
||||
-- - Add more patterns to filter in the predicate function
|
||||
-- - Filter notifications from other LSP servers by client_name
|
||||
-- - Adjust notification display settings in setup() call
|
||||
|
||||
-- Predicate function to filter notifications
|
||||
-- Returns true if notification should be shown, false to hide it
|
||||
local predicate = function(notif)
|
||||
-- Keep all non-LSP notifications
|
||||
if not (notif.data.source == "lsp_progress" and notif.data.client_name == "lua_ls") then
|
||||
return true
|
||||
end
|
||||
-- Filter out specific verbose LSP progress notifications from lua_ls
|
||||
-- These messages are too frequent and not useful during development
|
||||
return notif.msg:find("Diagnosing") == nil and notif.msg:find("semantic tokens") == nil
|
||||
end
|
||||
|
||||
-- Custom sort function that applies filtering
|
||||
-- Filters notification array before sorting
|
||||
local custom_sort = function(notif_arr)
|
||||
return MiniNotify.default_sort(vim.tbl_filter(predicate, notif_arr))
|
||||
end
|
||||
|
||||
-- Initialize mini.notify with custom configuration
|
||||
require("mini.notify").setup({ content = { sort = custom_sort } })
|
||||
|
||||
-- Set mini.notify as the default notification handler
|
||||
vim.notify = MiniNotify.make_notify()
|
||||
56
templates/rde/lib/shell-hook.nix
Normal file
56
templates/rde/lib/shell-hook.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Shell hook configuration
|
||||
#
|
||||
# This module generates the welcome message displayed when entering the dev shell.
|
||||
# It provides information about available commands and how to get started.
|
||||
#
|
||||
# The message includes:
|
||||
# - Project name and welcome banner
|
||||
# - Quick start instructions (initProject, updateDeps)
|
||||
# - List of all available commands based on enabled languages
|
||||
# - Instructions for editing configuration
|
||||
#
|
||||
# Commands are conditionally shown based on config.enabledLanguages settings.
|
||||
# This ensures users only see commands relevant to their configuration.
|
||||
#
|
||||
# Usage:
|
||||
# Imported in flake.nix as:
|
||||
# shellHook = import ./lib/shell-hook.nix config pkgs;
|
||||
#
|
||||
# Generates the help message displayed when entering the dev shell
|
||||
config: pkgs: let
|
||||
inherit (config) defaultPackageName enabledLanguages enabledPackages;
|
||||
|
||||
# Build dynamic list of available commands based on enabled languages
|
||||
# Filters out empty strings for disabled languages
|
||||
shellCmds = pkgs.lib.concatLines (pkgs.lib.filter (cmd: cmd != "") [
|
||||
(pkgs.lib.optionalString enabledLanguages.r " - ${defaultPackageName}-r: Launch R console")
|
||||
(pkgs.lib.optionalString enabledLanguages.julia " - ${defaultPackageName}-jl: Launch Julia REPL")
|
||||
(pkgs.lib.optionalString enabledLanguages.julia " - ${defaultPackageName}-pluto: Launch Pluto.jl notebook")
|
||||
(pkgs.lib.optionalString enabledLanguages.julia " - ${defaultPackageName}-initJl: Init existing Julia project")
|
||||
(pkgs.lib.optionalString enabledLanguages.python " - ${defaultPackageName}-marimo: Launch Marimo notebook")
|
||||
(pkgs.lib.optionalString enabledLanguages.python " - ${defaultPackageName}-py: Run python")
|
||||
(pkgs.lib.optionalString enabledLanguages.python " - ${defaultPackageName}-ipy: Launch IPython REPL")
|
||||
(pkgs.lib.optionalString enabledLanguages.python " - ${defaultPackageName}-initPython: Init python project")
|
||||
(pkgs.lib.optionalString enabledPackages.devenv " - ${defaultPackageName}-initDevenv: Init devenv project")
|
||||
(pkgs.lib.optionalString enabledPackages.devenv " - ${defaultPackageName}-devenv: Run devenv")
|
||||
" "
|
||||
"To adjust options run: ${defaultPackageName} flake.nix"
|
||||
]);
|
||||
in ''
|
||||
echo ""
|
||||
echo "=========================================================================="
|
||||
echo "🎯 ${defaultPackageName} Development Environment"
|
||||
echo "---"
|
||||
echo "📝 Run '${defaultPackageName}-initProject' to set up project structure"
|
||||
echo "🔄 Run '${defaultPackageName}-updateDeps' to update all dependencies"
|
||||
echo "---"
|
||||
echo "🚀 Available commands:"
|
||||
echo " - ${defaultPackageName}: Launch Neovim"
|
||||
echo " - ${defaultPackageName}-g: Launch Neovide"
|
||||
echo "${shellCmds}"
|
||||
echo "=========================================================================="
|
||||
echo ""
|
||||
# Auto-activate devenv shell if devenv.nix exists (can be disabled in config)
|
||||
${pkgs.lib.optionalString enabledPackages.devenv "${defaultPackageName}-activateDevenv"}
|
||||
echo ""
|
||||
''
|
||||
39
templates/rde/overlays/project-scripts.nix
Normal file
39
templates/rde/overlays/project-scripts.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Project scripts overlay
|
||||
#
|
||||
# This overlay wraps shell scripts from the scripts/ directory as Nix packages.
|
||||
# Scripts are made available as executable commands with the project name prefix.
|
||||
#
|
||||
# How it works:
|
||||
# 1. Reads shell scripts from scripts/ directory
|
||||
# 2. Substitutes @defaultPackageName@ with actual package name
|
||||
# 3. Creates executable packages via writeShellScriptBin
|
||||
# 4. Scripts become available as: <packageName>-<scriptName>
|
||||
#
|
||||
# Available scripts:
|
||||
# - initPython: Initialize Python project with uv
|
||||
# - initProject: Set up project directory structure
|
||||
# - updateDeps: Update all dependencies (R, Python, Julia, flake)
|
||||
# - activateDevenv: Activate devenv shell if available
|
||||
#
|
||||
# Usage: Scripts are automatically available in the dev shell
|
||||
config: final: prev: let
|
||||
# Helper function to substitute config placeholders in scripts
|
||||
# Replaces @defaultPackageName@ with the actual package name from config
|
||||
substituteScript = scriptPath:
|
||||
prev.lib.replaceStrings
|
||||
["@defaultPackageName@"]
|
||||
[config.defaultPackageName]
|
||||
(builtins.readFile scriptPath);
|
||||
in {
|
||||
# Python project initialization (creates pyproject.toml, adds packages)
|
||||
initPython = prev.writeShellScriptBin "initPython" (substituteScript ../scripts/initPython.sh);
|
||||
|
||||
# Project structure setup (creates directories, git repo, .gitignore)
|
||||
initProject = prev.writeShellScriptBin "initProject" (substituteScript ../scripts/initProject.sh);
|
||||
|
||||
# Update all dependencies (R packages, Python packages, flake inputs)
|
||||
updateDeps = prev.writeShellScriptBin "updateDeps" (substituteScript ../scripts/updateDeps.sh);
|
||||
|
||||
# Activate devenv environment if devenv.nix exists
|
||||
activateDevenv = prev.writeShellScriptBin "activateDevenv" (substituteScript ../scripts/activateDevenv.sh);
|
||||
}
|
||||
22
templates/rde/overlays/python.nix
Normal file
22
templates/rde/overlays/python.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Python packages overlay
|
||||
#
|
||||
# This overlay configures the Python environment with essential packages.
|
||||
# Note: Most Python packages should be managed via uv (pyproject.toml)
|
||||
# This overlay is for packages needed at the system level.
|
||||
#
|
||||
# Usage:
|
||||
# - Add system-level Python packages to the list below
|
||||
# - For project-specific packages, use uv (e.g., 'uv add package-name')
|
||||
# - The Python interpreter is available via pkgs.python
|
||||
#
|
||||
# Example additions:
|
||||
# - numpy, pandas, scipy for scientific computing
|
||||
# - pytest, black, mypy for development tools
|
||||
final: prev: {
|
||||
# Python 3 with system-level packages
|
||||
python = prev.python3.withPackages (pyPackages:
|
||||
with pyPackages; [
|
||||
requests # HTTP library for making API calls
|
||||
# Add more system-level packages here
|
||||
]);
|
||||
}
|
||||
39
templates/rde/overlays/r.nix
Normal file
39
templates/rde/overlays/r.nix
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# R packages overlay
|
||||
#
|
||||
# This overlay configures the R environment with essential packages for data analysis.
|
||||
# It combines packages from rstats-on-nix (rpkgs) with custom packages.
|
||||
#
|
||||
# Usage:
|
||||
# - Edit the package list below to add/remove R packages
|
||||
# - Create r-packages.nix in your project root to add custom packages
|
||||
# - Custom file format: rpkgs: with rpkgs.rPackages; [ package1 package2 ]
|
||||
#
|
||||
# The overlay exports:
|
||||
# - quarto: Quarto with R packages
|
||||
# - rWrapper: R executable with all packages available
|
||||
final: prev: let
|
||||
# Core R packages for data analysis and development
|
||||
reqPkgs = with final.rpkgs.rPackages;
|
||||
[
|
||||
broom # Tidy model outputs
|
||||
data_table # Fast data manipulation
|
||||
janitor # Data cleaning helpers
|
||||
languageserver # LSP for IDE support
|
||||
reprex # Reproducible examples
|
||||
styler # Code formatting
|
||||
tidyverse # Data science ecosystem
|
||||
]
|
||||
# Additional packages from fran overlay
|
||||
++ (with final.extraRPackages; [
|
||||
httpgd # HTTP graphics device for interactive plots
|
||||
])
|
||||
# Import custom R packages from project root if file exists
|
||||
# Users can create r-packages.nix in their project to add more packages
|
||||
# Example r-packages.nix: rpkgs: with rpkgs.rPackages; [ ggplot2 dplyr ]
|
||||
++ (prev.lib.optional (builtins.pathExists ./r-packages.nix) (import ./r-packages.nix final.rpkgs));
|
||||
in {
|
||||
# Quarto with R support and all required packages
|
||||
quarto = final.rpkgs.quarto.override {extraRPackages = reqPkgs;};
|
||||
# R wrapper with all packages pre-loaded
|
||||
rWrapper = final.rpkgs.rWrapper.override {packages = reqPkgs;};
|
||||
}
|
||||
21
templates/rde/overlays/rix.nix
Normal file
21
templates/rde/overlays/rix.nix
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Rix overlay for R packages from rstats-on-nix
|
||||
#
|
||||
# This overlay provides access to R packages from the rstats-on-nix project.
|
||||
# rstats-on-nix maintains snapshots of CRAN packages built with Nix.
|
||||
#
|
||||
# Purpose:
|
||||
# - Provides reproducible R package versions
|
||||
# - Ensures binary cache availability for faster builds
|
||||
# - Maintained by the rstats-on-nix community
|
||||
#
|
||||
# The rpkgs attribute gives access to:
|
||||
# - rpkgs.rPackages: All CRAN packages
|
||||
# - rpkgs.quarto: Quarto publishing system
|
||||
# - rpkgs.rWrapper: R with package management
|
||||
#
|
||||
# Update the R snapshot date in flake.nix inputs section:
|
||||
# rixpkgs.url = "github:rstats-on-nix/nixpkgs/YYYY-MM-DD"
|
||||
inputs: final: prev: {
|
||||
# R packages from rstats-on-nix for the current system
|
||||
rpkgs = inputs.rixpkgs.legacyPackages.${prev.stdenv.hostPlatform.system};
|
||||
}
|
||||
30
templates/rde/overlays/theme.nix
Normal file
30
templates/rde/overlays/theme.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# Extra theme packages overlay
|
||||
#
|
||||
# This overlay configures the Neovim color scheme based on user configuration.
|
||||
# It transforms the theme config from flake.nix into a Neovim plugin structure.
|
||||
#
|
||||
# Usage:
|
||||
# - Configure theme in flake.nix config.theme section
|
||||
# - Specify colorscheme name, background (dark/light)
|
||||
# - Add custom Lua configuration in extraColorschemePackage
|
||||
#
|
||||
# The overlay exports:
|
||||
# - extraTheme: Plugin structure with theme configuration
|
||||
#
|
||||
# Built-in themes: cyberdream, onedark, tokyonight, kanagawa
|
||||
config: final: prev: let
|
||||
# Transform user theme config into Neovim plugin format
|
||||
extraTheme = {
|
||||
# Get the plugin package from nixpkgs
|
||||
plugin = prev.vimPlugins."${config.theme.extraColorschemePackage.plugin}";
|
||||
# Theme name for identification
|
||||
name = config.theme.extraColorschemePackage.name;
|
||||
# Lua configuration to run when theme loads
|
||||
config = {
|
||||
lua = config.theme.extraColorschemePackage.extraLua;
|
||||
};
|
||||
};
|
||||
in {
|
||||
# Export theme for use in Neovim configuration
|
||||
inherit extraTheme;
|
||||
}
|
||||
15
templates/rde/scripts/activateDevenv.sh
Normal file
15
templates/rde/scripts/activateDevenv.sh
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ -f "devenv.nix" ]]; then
|
||||
echo "🚀 Activating devenv environment..."
|
||||
if ! command -v @defaultPackageName@-devenv &> /dev/null; then
|
||||
echo "❌ Command '@defaultPackageName@-devenv' not found."
|
||||
echo "Ensure devenv is properly configured in your environment."
|
||||
exit 1
|
||||
fi
|
||||
exec @defaultPackageName@-devenv shell
|
||||
else
|
||||
echo "❌ No devenv.nix file found in the current directory."
|
||||
echo "To create one, run '@defaultPackageName@-initDevenv'"
|
||||
exit 1
|
||||
fi
|
||||
120
templates/rde/scripts/initProject.sh
Normal file
120
templates/rde/scripts/initProject.sh
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_NAME="${1:-@defaultPackageName@}"
|
||||
|
||||
echo "🚀 Setting up project: $PROJECT_NAME"
|
||||
|
||||
# Create directory structure
|
||||
directories=(
|
||||
"data/raw"
|
||||
"data/processed"
|
||||
"data/interim"
|
||||
"docs"
|
||||
"figures"
|
||||
"tables"
|
||||
"src/analysis"
|
||||
"src/data_prep"
|
||||
"src/explore"
|
||||
"src/utils"
|
||||
)
|
||||
|
||||
for dir in "${directories[@]}"; do
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
mkdir -p "$dir"
|
||||
echo "✓ Created $dir/"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create essential files
|
||||
if [[ ! -f "README.md" ]]; then
|
||||
cat > README.md << 'EOF'
|
||||
# RDE
|
||||
|
||||
## Project Structure
|
||||
- `data/`: Data files (gitignored)
|
||||
- `docs/`: Documentation
|
||||
- `figures/`: Output figures
|
||||
- `tables/`: Output tables
|
||||
- `src/`: Source code
|
||||
|
||||
EOF
|
||||
fi
|
||||
|
||||
# Initialize git
|
||||
if [[ ! -d ".git" ]]; then
|
||||
if ! command -v git &> /dev/null; then
|
||||
echo "⚠️ Warning: 'git' command not found. Skipping git initialization."
|
||||
echo "Install git to enable version control."
|
||||
else
|
||||
git init
|
||||
echo "✓ Initialized Git repository"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if files exist and are not already staged/tracked before adding
|
||||
if command -v git &> /dev/null && [[ -d ".git" ]]; then
|
||||
if [[ -f "flake.nix" ]] && ! git diff --cached --name-only 2>/dev/null | grep -q "flake.nix" &&
|
||||
! git ls-files --error-unmatch flake.nix >/dev/null 2>&1; then
|
||||
echo "✓ Adding flake.nix to Git repository"
|
||||
git add flake.nix
|
||||
elif [[ -f "flake.nix" ]]; then
|
||||
echo "✓ flake.nix already tracked/staged in Git"
|
||||
fi
|
||||
|
||||
if [[ -f "flake.lock" ]] && ! git diff --cached --name-only 2>/dev/null | grep -q "flake.lock" &&
|
||||
! git ls-files --error-unmatch flake.lock >/dev/null 2>&1; then
|
||||
echo "✓ Adding flake.lock to Git repository"
|
||||
git add flake.lock
|
||||
elif [[ -f "flake.lock" ]]; then
|
||||
echo "✓ flake.lock already tracked/staged in Git"
|
||||
fi
|
||||
fi
|
||||
# Create .gitignore
|
||||
if [[ ! -f ".gitignore" ]]; then
|
||||
cat > .gitignore << 'EOF'
|
||||
# Data files
|
||||
data/
|
||||
*.csv
|
||||
*.docx
|
||||
*.xlsx
|
||||
*.parquet
|
||||
|
||||
# R specific
|
||||
.Rproj.user/
|
||||
.Rhistory
|
||||
.RData
|
||||
.Ruserdata
|
||||
*.Rproj
|
||||
.Rlibs/
|
||||
|
||||
# Python specific
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.pytest_cache/
|
||||
.venv/
|
||||
|
||||
# Jupyter
|
||||
.ipynb_checkpoints/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Devenv
|
||||
.devenv*
|
||||
devenv.local.nix
|
||||
|
||||
# direnv
|
||||
.direnv
|
||||
|
||||
# pre-commit
|
||||
.pre-commit-config.yaml
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "✅ Project setup completed successfully!"
|
||||
30
templates/rde/scripts/initPython.sh
Normal file
30
templates/rde/scripts/initPython.sh
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Check if uv command is available
|
||||
if ! command -v uv &> /dev/null; then
|
||||
echo "❌ Command 'uv' not found."
|
||||
echo "UV is required for Python project management."
|
||||
echo "Ensure UV is properly installed in your environment."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "pyproject.toml" ]]; then
|
||||
echo "🐍 Initializing UV project..."
|
||||
uv init
|
||||
echo "📦 Adding IPython and Marimo..."
|
||||
uv add ipython
|
||||
uv add marimo
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "✅ Python project initialized!"
|
||||
echo "run 'uv add PACKAGE' to add more python packages."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
else
|
||||
echo "--------------------------------------------------------------------------"
|
||||
echo "🔄 Existing Python project detected."
|
||||
echo "📦 Ensuring IPython and Marimo are installed..."
|
||||
uv add ipython
|
||||
uv add marimo
|
||||
echo "Run '@defaultPackageName@-updateDeps' to update dependencies."
|
||||
echo "--------------------------------------------------------------------------"
|
||||
fi
|
||||
98
templates/rde/scripts/updateDeps.sh
Normal file
98
templates/rde/scripts/updateDeps.sh
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
echo "🔄 Updating project dependencies..."
|
||||
|
||||
# Check for required commands
|
||||
if ! command -v wget &> /dev/null; then
|
||||
echo "❌ Error: 'wget' command not found."
|
||||
echo "Please install wget to fetch R version information."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v sed &> /dev/null; then
|
||||
echo "❌ Error: 'sed' command not found."
|
||||
echo "Please install sed to update flake.nix."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v nix &> /dev/null; then
|
||||
echo "❌ Error: 'nix' command not found."
|
||||
echo "Please install Nix to update flake inputs."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure we're in the repository root
|
||||
if [[ ! -f "flake.nix" ]]; then
|
||||
# Try to find git root
|
||||
if command -v git &> /dev/null && git rev-parse --show-toplevel >/dev/null 2>&1; then
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
if [[ ! -f "flake.nix" ]]; then
|
||||
echo "❌ Error: flake.nix not found in repository root"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "❌ Error: Not in a git repository and flake.nix not found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Fetch latest R version from rstats-on-nix
|
||||
# This command chain: downloads CSV, extracts last line, gets 4th field (date), removes quotes
|
||||
echo "📡 Fetching latest R version from rstats-on-nix..."
|
||||
RVER=$( wget -qO- 'https://raw.githubusercontent.com/ropensci/rix/refs/heads/main/inst/extdata/available_df.csv' | tail -n 1 | head -n 1 | cut -d',' -f4 | tr -d '"' )
|
||||
|
||||
# Validate RVER matches YYYY-MM-DD format
|
||||
if [[ ! "$RVER" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
|
||||
echo "❌ Error: Failed to fetch valid R version date. Got: '$RVER'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ R date is $RVER"
|
||||
|
||||
# Create backup of flake.nix before modifying
|
||||
cp flake.nix flake.nix.backup
|
||||
|
||||
# Update rixpkgs date in flake.nix
|
||||
if sed -i "s|rixpkgs.url = \"github:rstats-on-nix/nixpkgs/[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}\";|rixpkgs.url = \"github:rstats-on-nix/nixpkgs/$RVER\";|" flake.nix; then
|
||||
echo "✅ Updated rixpkgs date in flake.nix"
|
||||
rm flake.nix.backup
|
||||
else
|
||||
echo "⚠️ Warning: Failed to update flake.nix, restoring backup"
|
||||
mv flake.nix.backup flake.nix
|
||||
fi
|
||||
|
||||
nix flake update
|
||||
echo "✅ Flake inputs updated"
|
||||
|
||||
# Update Python dependencies if pyproject.toml exists and uv is available
|
||||
if [[ -f "pyproject.toml" ]]; then
|
||||
if command -v uv >/dev/null 2>&1; then
|
||||
uv sync --upgrade
|
||||
echo "✅ Python dependencies updated"
|
||||
else
|
||||
echo "ℹ️ pyproject.toml found but uv command not available, skipping Python update"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update Julia dependencies if Project.toml exists and julia is available
|
||||
if [[ -f "Project.toml" ]]; then
|
||||
if command -v @defaultPackageName@-jl >/dev/null 2>&1; then
|
||||
@defaultPackageName@-jl -e "using Pkg; Pkg.update()"
|
||||
echo "✅ Julia dependencies updated"
|
||||
else
|
||||
echo "ℹ️ Project.toml found but @defaultPackageName@-jl command not available, skipping Julia update"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Update devenv dependencies if devenv.nix exists and devenv is available
|
||||
if [[ -f "devenv.nix" ]]; then
|
||||
if command -v devenv >/dev/null 2>&1; then
|
||||
devenv update
|
||||
echo "✅ Devenv dependencies updated"
|
||||
else
|
||||
echo "ℹ️ devenv.nix found but devenv command not available, skipping devenv update"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "🎉 All dependencies updated!"
|
||||
Loading…
Add table
Add a link
Reference in a new issue