Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
* @washingtonpost/news-engineering
* @washingtonpost/news-engineering @WashPost/data-reporting

# Order is important; the last matching pattern takes the most
# precedence. When someone opens a pull request that only
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/_python-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
python-version: "3.11"

- name: Install Zig
run: python -m pip install ziglang==0.11.0 wheel
run: python -m pip install ziglang==0.14.0 wheel

- name: Build wheels
run: python python/make_wheels.py ${{ matrix.architecture }}-${{ matrix.os }}
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.11.0
version: 0.14.0
- name: Get output paths
uses: kanga333/variable-mapper@master
id: map
Expand Down Expand Up @@ -64,8 +64,11 @@ jobs:
- name: Zip output executable
if: matrix.os != 'wasm'
run: zip -j fastfec-${{ matrix.os }}-${{ matrix.architecture }}-${{ inputs.version }}.zip zig-out/bin/fastfec${{ steps.map.outputs.exeExt }}
- name: Move output library
if: matrix.os != 'wasm'
- name: Move output library (windows)
if: matrix.os == 'windows'
run: mv zig-out/bin/${{ steps.map.outputs.libName }}.${{ steps.map.outputs.libExt }} libfastfec-${{ matrix.os }}-${{ matrix.architecture }}-${{ inputs.version }}.${{ steps.map.outputs.libExt }}
- name: Move output library (non-windows)
if: matrix.os != 'windows' && matrix.os != 'wasm'
run: mv zig-out/lib/${{ steps.map.outputs.libName }}.${{ steps.map.outputs.libExt }} libfastfec-${{ matrix.os }}-${{ matrix.architecture }}-${{ inputs.version }}.${{ steps.map.outputs.libExt }}
- name: Move output library (wasm)
if: matrix.os == 'wasm'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
- uses: actions/checkout@v4
- uses: goto-bus-stop/setup-zig@v1
with:
version: 0.11.0
version: 0.14.0
- name: Run zig test
run: zig build test

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
!.gitignore
!.github
!.pre-commit-config.yaml
!.git-blame-ignore-revs
bin
*.test
*.fec
Expand Down Expand Up @@ -40,4 +41,4 @@ share/python-wheels/
.installed.cfg
*.egg
*.whl
MANIFEST
MANIFEST
15 changes: 7 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
files: \.py$
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v5.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/pycqa/isort
rev: 5.10.1
rev: 5.13.2
hooks:
- id: isort
name: isort (python)
args: ["--profile", "black", --line-length=120]
args: ["--profile", "black", "--line-length=120"]

# black
- repo: https://github.com/ambv/black
rev: 21.9b0
- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
args: # arguments to configure black
- --line-length=120
language_version: python3.9

# flake8
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
- repo: https://github.com/PyCQA/flake8
rev: 7.1.1
hooks:
- id: flake8
args: # arguments to configure flake8
Expand Down
111 changes: 111 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# AGENTS.md

## What this repo is

FastFEC is a C parser for raw `.fec` filings. It has:

- a CLI binary (`fastfec`) that writes parsed CSV files
- a shared C library (`libfastfec`)
- a Python wrapper package in `python/` that loads the shared library

## Repo structure

- `src/`: C source code for parser, CLI, writer, and bundled PCRE
- `build.zig`: Zig build script for CLI, shared lib, and C tests
- `scripts/`: mapping generation scripts (`generate_mappings.py`)
- `python/src/fastfec/`: Python wrapper (`ctypes` client + utils)
- `python/tests/`: Python tests + fixture `.fec` files

## macOS setup

1. Install Zig (recommended on current macOS):

```sh
brew install zig@0.14
```

2. Use this Zig in shell for the session:

```sh
export PATH="/opt/homebrew/opt/zig@0.14/bin:$PATH"
```

3. Verify:

```sh
zig version
```

## Build (C CLI + shared lib)

From repo root:

```sh
zig build
```

Outputs:

- `zig-out/bin/fastfec`
- `zig-out/lib/libfastfec.dylib`

## Run CLI

Parse a local filing:

```sh
./zig-out/bin/fastfec -x -s python/tests/fixtures/13360.fec /private/tmp/fastfec_out 13360
```

Notes:

- `-x` disables stdin and forces file input mode
- output files are written under `{output_dir}/{filing_id}/`

## Run C tests

```sh
zig build test
```

## Makefile shortcuts

From repo root:

```sh
make help
```

Main targets:

- `make build`: build CLI + shared library
- `make c-test`: run C tests
- `make cli-smoke`: parse fixture filing and write CSV output to `/private/tmp/fastfec_make_smoke`
- `make py-setup`: create `python/.venv`
- `make py-install`: install Python dev dependencies
- `make py-test`: run Python tests (`tox -e py`)
- `make all`: run full verification (`build`, `c-test`, `cli-smoke`, `py-test`)

## Python interface setup

From repo root:

```sh
python3 -m venv python/.venv
source python/.venv/bin/activate
cd python
pip install -r requirements-dev.txt
```

## Run Python tests

```sh
source python/.venv/bin/activate
cd python
tox -e py
```

## Dependency notes

- The Python package depends on `ziglang==0.11.0` for wheel/build workflows.
- On newer macOS, using system `zig 0.11.0` directly may fail; building the repo with `zig@0.14` is the practical path.
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
SHELL := /bin/zsh

ifneq ("$(wildcard /opt/homebrew/opt/zig@0.14/bin/zig)","")
ZIG ?= /opt/homebrew/opt/zig@0.14/bin/zig
else
ZIG ?= zig
endif

VENV := python/.venv
FIXTURE := python/tests/fixtures/13360.fec
SMOKE_OUT := /private/tmp/fastfec_make_smoke

.PHONY: help all check-zig build c-test cli-smoke py-setup py-install py-test

help:
@echo "Targets:"
@echo " make build - Build CLI + shared lib"
@echo " make c-test - Run C tests"
@echo " make cli-smoke - Parse fixture with CLI"
@echo " make py-setup - Create python/.venv"
@echo " make py-install - Install python dev deps"
@echo " make py-test - Run Python tox tests"
@echo " make all - Run full verification"

check-zig:
@command -v $(ZIG) >/dev/null 2>&1 || (echo "Zig not found. Install with: brew install zig@0.14" && exit 1)
@$(ZIG) version

build: check-zig
$(ZIG) build

c-test: check-zig
$(ZIG) build test

cli-smoke: build
mkdir -p $(SMOKE_OUT)
./zig-out/bin/fastfec -x -s $(FIXTURE) $(SMOKE_OUT) 13360
@test -d $(SMOKE_OUT)/13360
@echo "Smoke output files:"
@find $(SMOKE_OUT)/13360 -maxdepth 1 -type f | head -n 10

py-setup:
@test -d $(VENV) || python3 -m venv $(VENV)

py-install: py-setup
source $(VENV)/bin/activate && cd python && pip install -r requirements-dev.txt

py-test: py-install
source $(VENV)/bin/activate && cd python && tox -e py

all: build c-test cli-smoke py-test
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,16 @@ The following was performed on an M1 Macbook Air:

### Build system

[Zig](https://ziglang.org/) is used to build and compile the project. Download and install the latest version of Zig (>=0.11.0) by following the instructions on the website (you can verify it's working by typing `zig` in the terminal and seeing help commands).
[Zig](https://ziglang.org/) is used to build and compile the project. Download and install Zig 0.14.0 or later by following the instructions on the website (you can verify it's working by typing `zig` in the terminal and seeing help commands).

### Dependencies

FastFEC has no external C dependencies. [PCRE](./src/pcre/README) is bundled with the library to ensure compatibility with Zig's build system and cross-platform compilation.
FastFEC vendors PCRE2 (`pcre2-8`) by default in `src/pcre2`, ensuring consistent builds across platforms (including wasm). Packagers may switch to system PCRE2 if desired, but no system dependency is required for normal builds.

### Requirements

- Zig >= 0.14.0 (tested on 0.14.0 and 0.15.1)
- No external C dependencies required (PCRE2 is vendored)

### Building

Expand Down
Loading