core

Foundation functions for project shell operations

The core module provides the essential machinery that all other pj components depend on: command execution, prerequisite checking, port management, and theme configuration. These primitives handle the mechanical work of running subprocesses, validating system state, and configuring the development environment.

Constants

A horizontal rule separator used throughout for visual sectioning in logs and output.

Software Version


source

get_pj_version

 get_pj_version ()

Get pj version from settings.ini

Process Management

Background processes—Jupyter servers, Quarto preview, nbdev watchers—accumulate during development. We need atomic cleanup to return to a known state.


source

kill_processes

 kill_processes (args)

Kill all running pj-related processes

The pkill -f pattern matching catches processes by command line, not just process name. This matters for Quarto, which spawns as a Deno subprocess—killing “quarto” misses the actual server; killing “quarto.js preview” hits it.

Port Allocation

Multiple Jupyter instances need distinct ports. Rather than hardcode or prompt, we scan upward from a sensible default until we find an available port.


source

find_free_port

 find_free_port (start=64000)

Find first available port starting from given port

Starting at 64000 avoids privileged ports (<1024) and common application ports (8000-9000). The 100-port window should never exhaust unless something is catastrophically wrong.

Theme Configuration

The default nbdev documentation is light-mode only. We inject a dark theme with toggle, custom syntax highlighting, and adjusted cell output styling.


source

setup_dark_theme

 setup_dark_theme (project_path, log_file=None, verbose=False)

Set up dark mode theme for nbdev docs

Quarto’s theming system expects a SCSS file for dark mode overrides. The key insight: cell outputs default to system colors, which are invisible on dark backgrounds. We force explicit colors for all output contexts.

Command Validation

Before running a complex workflow, verify that all required tools exist. Failing fast with installation hints beats cryptic subprocess errors halfway through.


source

check_cmd

 check_cmd (cmd, install_hint)

Check if a command exists in PATH

shutil.which() searches $PATH reliably across platforms. Returns the full path if found, None otherwise.

Command Execution

All subprocess calls funnel through run_cmd(), which provides consistent logging, error handling, and optional verbose output with formatted boundaries.


source

run_cmd

 run_cmd (cmd, cwd=None, check=True, capture_output=False, log_file=None,
          verbose=False)

Run a shell command with optional logging and pretty output

Three modes: capture (return stdout/stderr for parsing), verbose (stream with box borders), silent (log to file only). The verbose mode’s box drawing makes it clear where command output begins and ends—essential when debugging multi-step processes.

The mock Result class in verbose mode maintains API compatibility: callers always get an object with .returncode, .stdout, .stderr attributes.

Git Configuration

Extract user information from git config for populating project metadata without prompting.


source

get_git_config

 get_git_config (key)

Get git config value

Returns None on any failure—missing git, key not set, etc. Callers provide sensible defaults when None is returned.