Djazair Package Manager (DPM)
DPM is the official, self-hosted package manager and build orchestrator for the Djazair Programming Language. Written natively in Djazair, DPM provides project scaffolding, Semantic Versioning (SemVer) dependency resolution, multi-source downloading (GitHub monorepos, Git repositories, HTTP ZIPs, and local archives), isolated per-project dependency trees, global tool installations, and automated native compilation for hybrid C/C++ packages.
DPM is implemented as a core Djazair application (dpm/init.dz) and can be executed either directly via the standalone dpm wrapper script (dpm.bat on Windows, dpm on POSIX) or through the language driver: djazair dpm <command>.
Architecture & Core Concepts
DPM is architected around deterministic dependency management, clean isolation, and cross-platform portability. Understanding these foundations is essential for developing production-grade applications and reusable packages in Djazair.
Local Isolation vs Global Scope
DPM operates in two distinct execution modes:
- Local Project Scope (Default): Dependencies are installed strictly within the project directory inside the isolated
djazair_packages/folder. Modifications are recorded directly in the project's rootdpm.jsonmanifest. This ensures completely reproducible builds and guarantees that two projects on the same machine can safely depend on different versions of the same library without conflict. - Global System Scope (
-g,--global): Installs packages system-wide in the language runtime directory (or~/.djazair/packages). This mode is ideal for developer command-line tools, language extensions, and global utilities that need to be accessible from any working directory.
| Scope | Default Installation Directory | Manifest Impact | Primary Use Case |
|---|---|---|---|
| Local (Default) | <project_root>/djazair_packages/ |
Pinned to root dpm.json (require) |
Application libraries, database drivers, framework plugins |
Global (-g) |
<djazair_root>/packages/ or ~/.djazair/packages/ |
None (standalone installation) | CLI utilities, linters, system-wide code generators |
Package Classification: Pure vs Hybrid
DPM explicitly recognizes two primary categories of packages:
- Pure Packages (
"type": "pure"): Built entirely in Djazair source code (.dzfiles). They require no external compiler toolchain, install instantaneously across all operating systems (Windows, Linux, macOS), and have zero native binary dependencies. - Hybrid Packages (
"type": "hybrid"): Contain both Djazair wrapper code and low-level C or C++ extensions (e.g., SQLite, WebSockets, image processing). They declare platform-specific build scripts (build.baton Windows,build.shon POSIX) and link against the Djazair C runtime header files (djazair_api.h) and static library (libdjazair.a).
Runtime Module Resolution Hierarchy
When your Djazair script issues an import or use statement, the interpreter resolves packages in the following strictly defined order:
- Project-Local Directory Package:
<project_root>/djazair_packages/<name>/init.dz - Project-Local Single-File Package:
<project_root>/djazair_packages/<name>.dz - Global System Package:
<djazair_root>/packages/<name>/init.dz - Built-In Standard Library: Embedded C/Djazair standard modules (e.g.,
math,json,http,file).
Semantic Versioning (SemVer 2.0.0 Engine)
DPM embeds an internal, full-featured SemVer parsing and evaluation engine (dpm/core/semver.dz). When declaring dependencies or updating packages, DPM evaluates version constraints to ensure breaking changes are never introduced unintentionally.
| Constraint Pattern | Example | Matching Versions | Behavior & Rationale |
|---|---|---|---|
Caret (^) (Default) |
^1.2.0 |
1.2.0, 1.2.3, 1.9.9 (Rejects 2.0.0) |
Allows backwards-compatible minor and patch updates. For zero-major versions (^0.2.0), minor increments are treated as breaking (matches 0.2.x, rejects 0.3.0). |
Tilde (~) |
~1.2.0 |
1.2.0, 1.2.9 (Rejects 1.3.0) |
Restricts updates strictly to patch releases. Useful when minor versions might alter API behavior. |
| Exact | 1.2.3 |
Only 1.2.3 |
Locks dependency to an exact release. Essential for ultra-deterministic critical deployments. |
| Wildcard / Latest | * or latest |
Any version | Matches the absolute latest release found upstream. |
| Comparison Operators | >=1.0.0 <2.0.0 |
Any version in range | Supports standard relational bounds (>=, >, <=, <). |
| Pre-Release Identifiers | 1.0.0-rc.1 |
SemVer pre-release | Parsed cleanly via semver.parse(), allowing development candidate tracking. |
Complete CLI Reference & Workflows
DPM commands share a consistent interface, intuitive aliases, and standardized flag behavior:
dpm <command> [options] [arguments]
# or
djazair dpm <command> [options] [arguments]
Global Command-Line Flags
-g,--global: Target the global language packages directory instead of the project-local workspace.-q,--quiet: Run quietly, suppressing all non-error informational logs.--verbose: Enable verbose diagnostic traces, showing git command outputs and path resolution steps.-v,--version: Print DPM version, Djazair engine version, host OS platform, and author info.-h,--help: Display interactive help screen.
1. Project Scaffolding: dpm init
Initializes a new Djazair project or library package. It launches an interactive wizard that prompts for project metadata and automatically generates a standard dpm.json manifest, starter entrypoint, .gitignore, and README.md.
# Interactive scaffolding wizard
dpm init
# Non-interactive mode (accepts all sensible defaults immediately)
dpm init --yes
# or
dpm init -y
When run, dpm init scaffolds the following standard directory structure:
my_project/
├── dpm.json # Package manifest & dependency declarations
├── init.dz # Primary entrypoint with starter function
├── .gitignore # Pre-configured to ignore djazair_packages/ and build binaries
└── README.md # Formatted markdown documentation with install/usage examples
The generated .gitignore automatically excludes djazair_packages/, native build artifacts (*.dll, *.so, *.dylib, *.o, *.a), build flags (.built), and the DPM temporary cache (.dpm_cache/). This ensures you never accidentally commit downloaded dependencies or compiled binaries to source control.
2. Package Installation: dpm install
The install command (aliases: i, add) handles both batch dependency synchronization and single package retrieval.
Batch Manifest Installation
Running dpm install without arguments reads the local dpm.json, parses the require block, and recursively downloads, verifies, and installs every listed dependency:
dpm install
Supported Package Specifiers & Source Formats
DPM supports an exceptionally versatile range of source identifiers:
| Source Format | Syntax Example | Resolution Mechanism |
|---|---|---|
| Shorthand Name | dpm install sqlitedpm install qalam |
Checks local offline packages (<djazair_root>/packages/) first; if not found, fetches from the official extensions monorepo (github:djazair-language/djazair-extensions/<name>). |
| GitHub Monorepo Subdirectory | dpm install github:org/repo/subfolder |
Clones/caches the repository and extracts the specified subdirectory as a standalone package. |
| GitHub Repository Shorthand | dpm install github:user/repo |
Clones directly from https://github.com/user/repo.git. |
| Direct Git URL | dpm install https://github.com/team/auth.git |
Executes shallow clone (--depth 1), cleans up .git metadata, and places package in djazair_packages/auth. |
| Direct HTTP/HTTPS ZIP Archive | dpm install https://cdn.example.com/matrix.zip |
Downloads archive to DPM cache and extracts cleanly into project packages. |
| Local Directory or Archive | dpm install ./libs/my-custom-pkgdpm install ../archives/pkg.zip |
Copies local filesystem directory or extracts local archive directly into djazair_packages/. |
Installation Modifiers
# Install globally into language packages directory
dpm install -g qalam
# Install without updating the root dpm.json manifest
dpm install sqlite --no-save
# Force re-download and re-install even if package directory exists
dpm install sqlite --force
3. Package Upgrades: dpm update
The update command (alias: up) inspects installed packages against their remote origin. For Git-backed packages, DPM queries remote tags (git ls-remote --tags), compares available versions using its SemVer engine, and upgrades the package when a newer compatible version is detected.
# Update a specific package locally
dpm update sqlite
# Update all installed packages in the current project
dpm update *
# or
dpm update
# Update a globally installed package
dpm update -g qalam
# Force re-installation of the latest version
dpm update sqlite --force
4. Package Uninstallation: dpm remove
The remove command (aliases: rm, uninstall) safely deletes a package from djazair_packages/ and automatically removes its dependency constraint from dpm.json:
# Remove package locally and update dpm.json
dpm remove sqlite
# Remove a globally installed package
dpm remove -g qalam
5. Inventory Inspection: dpm list
The list command (alias: ls) scans the packages directory and outputs a cleanly formatted table of all installed packages, their detected versions, and package types:
# List project-local packages
dpm list
# List globally installed packages
dpm list -g
6. Deep Metadata Inspection: dpm info
The info command (alias: show) prints an exhaustive diagnostic report for any package, including its scope, installation location, entrypoint, author, dependency map, update availability, and file inventory:
dpm info sqlite
Package Information: sqlite
----------------------------------------------------
Name: sqlite
Scope: Local
Location: D:\Projects\app\djazair_packages\sqlite
Version: 1.0.0
Type: hybrid
Description: SQLite native embedded database engine for Djazair
Source: github:djazair-language/djazair-extensions/sqlite
Entrypoint: init.dz
Developer: Harizi Riyadh <hariziriyadh@gmail.com>
Dependencies: None
Files (6): dpm.json, init.dz, build.bat, build.sh, sqlite3.c, sqlite3.h
7. Distributable Bundling: dpm pack
Packages the current project or library into a clean, distributable ZIP archive named <name>-<version>.zip. It automatically excludes local dependencies (djazair_packages/), compiled binaries, and temporary files, producing a production-ready distribution artifact ready to be published or shared.
dpm pack
# Output: Package archive created: 'D:\Projects\my_lib\my_lib-1.0.0.zip'
Package Manifest (dpm.json) Specification
The dpm.json file is the single source of truth for any Djazair project or distributable library. Below is the complete annotated specification:
{
"name": "super_cache",
"version": "1.2.0",
"description": "High-performance LRU cache and memory storage for Djazair",
"type": "pure",
"entry": "init.dz",
"source": "github:developer/super_cache",
"developer": {
"name": "Harizi Riyadh",
"email": "hariziriyadh@gmail.com"
},
"require": {
"qalam": "^0.2.0",
"sqlite": "~1.0.0"
},
"build": {
"windows": "build.bat",
"linux": "./build.sh"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
name |
String | Yes | The unique identifier of the package. Must use lowercase alphanumeric characters, dashes, or underscores (e.g. "json_validator"). |
version |
String | Yes | Valid SemVer 2.0.0 string (MAJOR.MINOR.PATCH[-PRERELEASE]). |
description |
String | No | Concise overview of the package's purpose and functionality. |
type |
String | Yes | Either "pure" (Djazair code only) or "hybrid" (contains native C/C++ build steps). |
entry |
String | No | Main entrypoint file executed when the package is imported. Defaults to "init.dz". |
source |
String | No | Upstream repository specifier (e.g. "github:org/repo" or Git URL) used for automated updates. |
developer |
Object | No | Metadata map containing author "name" and "email". |
require |
Object | No | Dictionary of package dependencies mapped to SemVer constraints (e.g., {"qalam": "^0.2.0"}). |
build |
Object | No (Hybrid only) | Cross-platform build scripts for hybrid packages (e.g., "windows": "build.bat", "linux": "./build.sh"). |
Professional Tutorial: Creating & Publishing a Package
Follow this end-to-end walkthrough to create, structure, test, bundle, and distribute a professional Djazair package.
Step 1: Scaffolding the Package
Create a dedicated directory for your library and initialize it with DPM:
mkdir string_utils
cd string_utils
dpm init
Fill in the interactive prompts:
Package name (string_utils): string_utils
Version (0.1.0): 1.0.0
Description: Advanced string transformation algorithms for Djazair
Type (pure/hybrid) [pure]: pure
Author Name: Harizi Riyadh
Author Email: hariziriyadh@gmail.com
Step 2: Designing the Package Architecture
A professional package organizes its internal logic under a src/ directory and exports a clean public API through init.dz:
string_utils/
├── dpm.json
├── init.dz
├── src/
│ ├── case.dz
│ └── slugify.dz
├── tests/
│ └── test_string_utils.dz
└── README.md
Write your internal modules inside src/:
# src/slugify.dz
fn toSlug(text)
let clean = text.lower().strip()
let result = ""
for ch in clean
if (ch >= "a" and ch <= "z") or (ch >= "0" and ch <= "9")
result = result + ch
elif ch == " " or ch == "_" or ch == "-"
if !result.endsWith("-") and result.length() > 0
result = result + "-"
end
end
end
return result
end
Expose your public functions in the package entrypoint (init.dz):
# init.dz — Public API Gateway
import "src/slugify.dz" as slug
# Re-export clean functions
fn slugify(text)
return slug.toSlug(text)
end
fn version()
return "1.0.0"
end
Step 3: Managing Dependencies
If your package requires helper libraries (e.g. qalam for colored output or logging), install them directly:
dpm install qalam
DPM installs qalam into djazair_packages/qalam and automatically records "qalam": "^0.2.0" in your dpm.json.
Step 4: Writing Unit Tests
Create a test runner under tests/test_string_utils.dz utilizing the standard assert library:
# tests/test_string_utils.dz
use assert
import "../init.dz" as string_utils
print("==> Testing string_utils...")
assert.equal(string_utils.slugify("Hello World! 2026"), "hello-world-2026", "Slugification failed")
assert.equal(string_utils.slugify("Djazair Programming"), "djazair-programming", "Multiple spaces failed")
print("==> All tests passed successfully!")
Execute your tests:
djazair tests/test_string_utils.dz
Step 5: Packaging & Publishing
When ready for release, bundle your package using dpm pack:
dpm pack
# Produces: string_utils-1.0.0.zip
To publish via Git, push your code to GitHub with a SemVer release tag:
git init
git add .
git commit -m "Release v1.0.0"
git tag v1.0.0
git remote add origin https://github.com/myusername/string_utils.git
git push -u origin main --tags
Step 6: Consuming the Published Package
Other developers can now install and consume your package directly:
# Install via GitHub shorthand
dpm install github:myusername/string_utils
# Or install from direct ZIP release
dpm install https://github.com/myusername/string_utils/releases/download/v1.0.0/string_utils-1.0.0.zip
In consumer code:
use string_utils
let slug = string_utils.slugify("Building with Djazair and DPM")
print("Generated Slug: " + slug)
# Output: Generated Slug: building-with-djazair-and-dpm
Authoring Hybrid Packages (C/C++ Extensions)
Hybrid packages bridge high-performance C or C++ shared libraries into the Djazair runtime. DPM automates native builds by orchestrating cross-platform build scripts.
Hybrid Package Layout
fast_hash/
├── dpm.json # Declares "type": "hybrid" and "build" scripts
├── init.dz # Djazair bindings loading the native library
├── build.bat # Windows compilation script (MinGW / MSVC)
├── build.sh # Linux & macOS compilation script (GCC / Clang)
└── src/
├── native.c # C implementation using Djazair C API
└── native.h
Hybrid dpm.json
{
"name": "fast_hash",
"version": "1.0.0",
"description": "Native high-speed hashing module for Djazair",
"type": "hybrid",
"entry": "init.dz",
"build": {
"windows": "build.bat",
"linux": "./build.sh"
}
}
Standard Build Scripts
DPM sets the DJAZAIR_ROOT environment variable before executing your build scripts. Your scripts should reference the Djazair header files in $DJAZAIR_ROOT/src/include and link against libdjazair:
@echo off
setlocal
:: Set include and library directories
if "%DJAZAIR_ROOT%"=="" set DJAZAIR_ROOT=..\..
gcc -O3 -shared -fPIC ^
-I"%DJAZAIR_ROOT%\src\include" ^
-o fast_hash.dll ^
src\native.c ^
-L"%DJAZAIR_ROOT%\build\lib" -ldjazair
if %ERRORLEVEL% equ 0 (
echo [OK] fast_hash.dll compiled successfully.
exit /b 0
) else (
echo [ERROR] Compilation failed.
exit /b 1
)
#!/usr/bin/env bash
set -e
: "${DJAZAIR_ROOT:=../..}"
gcc -O3 -shared -fPIC \
-I"${DJAZAIR_ROOT}/src/include" \
-o fast_hash.so \
src/native.c \
-L"${DJAZAIR_ROOT}/build/lib" -ldjazair
echo "[OK] fast_hash.so compiled successfully."
Programmatic Package Inspection via lang
Djazair's standard library lang module provides native functions to inspect packages and query update states directly from your running scripts:
| Function | Return Type | Description |
|---|---|---|
lang.packagesDir() |
String |
Returns the absolute path to the active global packages directory. |
lang.packageExist(name, [isGlobal]) |
Boolean |
Checks if a package exists locally or globally. Alias: lang.packageExists(). |
lang.checkPackageUpdate(name, [isGlobal]) |
Map |
Returns a dictionary with isInstalled, hasUpdate, currentVersion, latestVersion, path, and scope. |
lang.hasUpdate(name, [isGlobal]) |
Boolean |
Convenience predicate checking if a newer version is available upstream. |
Real-World Dynamic Inspection Example
use lang
# Check if SQLite package is available
if lang.packageExist("sqlite")
let info = lang.checkPackageUpdate("sqlite")
print("SQLite Version: " + info["currentVersion"])
print("Installed Path: " + info["path"])
if info["hasUpdate"]
print("Notice: A newer SQLite release (v" + info["latestVersion"] + ") is available!")
print("Run 'dpm update sqlite' to upgrade.")
end
else
print("SQLite is not installed. Please run: dpm install sqlite")
end
Production & CI/CD Best Practices
1. Git Repository Hygiene
- Always commit
dpm.json: The manifest defines exact version bounds and is critical for team collaboration. - Never commit
djazair_packages/: Always ignore dependencies in.gitignore. Team members and CI servers will reconstitute them deterministically usingdpm install. - Never commit binary artifacts: Ensure
*.dll,*.so,*.dylib, and.dpm_cache/are gitignored.
2. Continuous Integration (CI/CD) Configuration
In automated GitHub Actions or GitLab CI environments, incorporate DPM dependency synchronization into your build matrix:
# .github/workflows/ci.yml
name: Test Suite
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout Source
uses: actions/checkout@v4
- name: Setup Djazair & DPM
run: |
sudo apt-get update && sudo apt-get install -y gcc make
# Build or install Djazair binaries
make install
- name: Install Project Dependencies
run: dpm install
- name: Run Test Suite
run: djazair tests/run_all.dz
3. Troubleshooting Common Issues
- Git is not recognized: DPM relies on the system
gitcommand to fetch repositories. Ensure Git is installed and added to your systemPATH. - Compiler toolchain missing for hybrid packages: On Windows, ensure MinGW GCC (e.g. MSYS2 or WinLibs) is in your
PATH. On Linux, installbuild-essential(GCC/Clang and Make). - Cleaning Cache: DPM caches monorepos and downloaded archives in your OS temporary directory under
dpm_cache/. To clear stale caches, delete the directory:bash# Windows PowerShell Remove-Item -Recurse -Force "$env:TEMP\dpm_cache" # Linux / macOS rm -rf /tmp/dpm_cache