Files
nixpkgs/CONTRIBUTING.md
m3tam3re 1ce83403bc first
2025-10-04 15:53:48 +02:00

7.9 KiB

Contributing to m3ta-nixpkgs

Thank you for your interest in contributing to m3ta-nixpkgs! This guide will help you get started with adding packages, modules, and improvements to this repository.

Table of Contents

Getting Started

Prerequisites

  • Nix with flakes enabled
  • Git
  • Basic understanding of Nix expressions

Enable Flakes

Add to ~/.config/nix/nix.conf or /etc/nix/nix.conf:

experimental-features = nix-command flakes

Clone and Setup

git clone https://code.m3ta.dev/m3tam3re/nixpkgs
cd m3ta-nixpkgs
nix develop  # Enter development environment

Adding a New Package

Step 1: Create Package Directory

mkdir pkgs/my-package

Step 2: Write the Package Expression

Create pkgs/my-package/default.nix using the template:

cp templates/package/default.nix pkgs/my-package/default.nix

Edit the file to match your package:

{
  lib,
  stdenv,
  fetchFromGitHub,
}:
stdenv.mkDerivation rec {
  pname = "my-package";
  version = "1.0.0";

  src = fetchFromGitHub {
    owner = "owner";
    repo = "repo";
    rev = "v${version}";
    hash = lib.fakeHash;  # Use this initially
  };

  meta = with lib; {
    description = "A short description";
    homepage = "https://github.com/owner/repo";
    license = licenses.mit;
    platforms = platforms.linux;
    mainProgram = "my-package";
  };
}

Step 3: Get the Correct Hash

nix build .#my-package
# The error message will show the correct hash
# Replace lib.fakeHash with the actual hash

Step 4: Register the Package

Add to pkgs/default.nix:

{pkgs, ...}: {
  # ... existing packages ...
  my-package = pkgs.callPackage ./my-package {};
}

Step 5: Test the Package

# Build the package
nix build .#my-package

# Run the package
nix run .#my-package

# Check if it works
./result/bin/my-package --version

Adding a NixOS Module

Step 1: Create Module File

cp templates/nixos-module/default.nix modules/nixos/my-module.nix

Step 2: Implement the Module

Edit modules/nixos/my-module.nix:

{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.m3ta.myModule;
in {
  options.m3ta.myModule = {
    enable = mkEnableOption "my custom module";
    # Add your options here
  };

  config = mkIf cfg.enable {
    # Add your configuration here
  };
}

Step 3: Register the Module

Add to modules/nixos/default.nix:

{
  config,
  lib,
  pkgs,
  ...
}: {
  imports = [
    ./my-module.nix  # Add this line
  ];
}

Step 4: Test the Module

Create a test configuration or add to your existing NixOS configuration:

{
  inputs.m3ta-nixpkgs.url = "path:/path/to/m3ta-nixpkgs";

  outputs = {nixpkgs, m3ta-nixpkgs, ...}: {
    nixosConfigurations.test = nixpkgs.lib.nixosSystem {
      modules = [
        m3ta-nixpkgs.nixosModules.default
        {
          m3ta.myModule.enable = true;
        }
      ];
    };
  };
}

Adding a Home Manager Module

Step 1: Create Module File

cp templates/home-manager-module/default.nix modules/home-manager/my-module.nix

Step 2: Implement the Module

Edit modules/home-manager/my-module.nix:

{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.programs.myProgram;
in {
  options.programs.myProgram = {
    enable = mkEnableOption "my program";
    # Add your options here
  };

  config = mkIf cfg.enable {
    # Add your configuration here
  };
}

Step 3: Register the Module

Add to modules/home-manager/default.nix:

{
  # ... existing modules ...
  myModule = import ./my-module.nix;
}

Step 4: Test the Module

Test with Home Manager:

{
  inputs.m3ta-nixpkgs.url = "path:/path/to/m3ta-nixpkgs";

  outputs = {home-manager, m3ta-nixpkgs, ...}: {
    homeConfigurations.test = home-manager.lib.homeManagerConfiguration {
      modules = [
        m3ta-nixpkgs.homeManagerModules.default
        {
          programs.myProgram.enable = true;
        }
      ];
    };
  };
}

Code Style Guidelines

Nix Code Style

  1. Formatting: Use nixpkgs-fmt for consistent formatting

    nix fmt
    
  2. Naming Conventions:

    • Package names: lowercase with hyphens (my-package)
    • Module options: camelCase (myModule)
    • Variables: camelCase (cfg, myVar)
  3. File Structure:

    • One package per directory
    • Use default.nix for the main expression
    • Keep related files together
  4. Comments:

    • Add comments for non-obvious code
    • Document complex expressions
    • Explain why, not what

Example Good Practice

{
  lib,
  stdenv,
  fetchFromGitHub,
  # Group related dependencies
  # Build tools
  cmake,
  pkg-config,
  # Libraries
  openssl,
  zlib,
}:
stdenv.mkDerivation rec {
  pname = "example";
  version = "1.0.0";

  src = fetchFromGitHub {
    owner = "example";
    repo = pname;
    rev = "v${version}";
    hash = "sha256-...";
  };

  nativeBuildInputs = [
    cmake
    pkg-config
  ];

  buildInputs = [
    openssl
    zlib
  ];

  # Explain non-obvious configuration
  cmakeFlags = [
    "-DENABLE_FEATURE=ON"  # Required for proper functionality
  ];

  meta = with lib; {
    description = "Clear, concise description";
    homepage = "https://example.com";
    license = licenses.mit;
    maintainers = with maintainers; [];
    platforms = platforms.linux;
    mainProgram = "example";
  };
}

Testing Your Changes

1. Check Flake Validity

nix flake check

2. Build All Packages

nix flake show  # See all outputs
nix build .#package-name

3. Test in a Clean Environment

# Build without any cached results
nix build .#package-name --rebuild

4. Test Module Integration

Test modules in a VM:

nixos-rebuild build-vm --flake .#test-config

5. Verify Metadata

Check that package metadata is complete:

nix eval .#packages.x86_64-linux.my-package.meta --json | jq

Submitting Changes

Before Submitting

  • Code follows style guidelines

  • Package builds successfully

  • Tests pass (if applicable)

  • Documentation is updated

  • Commit messages are clear and descriptive

  • CI workflows pass (check GitHub Actions)

Commit Message Format

type: brief description

Longer explanation if needed.

- Detail 1
- Detail 2

Types:

  • feat: New feature (package, module)
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes
  • refactor: Code refactoring
  • chore: Maintenance tasks

Examples

feat: add hyprpaper-random package

Add a random wallpaper selector for Hyprpaper.
Includes systemd timer integration.
fix: correct msty-studio dependencies

Add missing libGL dependency that caused runtime errors.
docs: update README with usage instructions

Add detailed instructions for using packages and modules.

Best Practices

Security

  • Never include API keys, passwords, or secrets
  • Use lib.fakeHash initially, then update with correct hash
  • Review dependencies for known vulnerabilities

Performance

  • Use callPackage for better caching
  • Avoid unnecessary import statements
  • Use overlays efficiently

Maintainability

  • Keep packages focused and simple
  • Document complex logic
  • Follow nixpkgs conventions
  • Update regularly

Getting Help

License

By contributing, you agree that your contributions will be licensed under the same license as the project.