Oidis Builder Overview
Oidis Builder (io-oidis-builder) is the build automation tool for the entire Oidis Framework. It provides
a unified CLI and task system for compiling, testing, packaging, and deploying Oidis projects — across
multiple languages and platforms — from a single entry point.
oidis install # prepare dependencies
oidis build prod # compile and package for production
oidis test lint # run all linters
oidis deploy:dev # deploy to dev server
oidis CLIThe oidis command is globally available (oidis.cmd on Windows, oidis.sh on Linux/macOS) and is the only supported interface for building, testing, installing dependencies, and running Oidis projects.
Never use npm run, npm test, npm install, npm start, or npx directly in an Oidis project — these bypass the builder's task chain, module hooks, and configuration resolution. If you need npm passthrough (e.g., npm audit), use oidis -- npm audit.
Non-Oidis projects (wiki/Docusaurus, E2E runner, standalone tools) that are not managed by Oidis Builder use npm normally.
Supported Languages & Platforms
| Language / Technology | What the builder does |
|---|---|
| TypeScript | Compile, lint (ESLint), unit test, coverage, minify |
| SASS / SCSS | Compile to CSS, lint (Stylelint), minify |
| C++ / XCpp | Cross-compile (GCC, Clang, MSVC, ARM), unit test, lint (CppCheck) |
| Java | Maven build, lint (Checkstyle), package JAR |
| Python | Compile (bytecode), lint (Pylint), unit test, package (wheel) |
| JavaScript | Minify (UglifyJS), lint (ESLint), native modules (node-gyp) |
Target platforms: Windows (x32, x64), Linux (x64, ARM 32/64), macOS
Architecture
Oidis Builder is built on top of io-oidis-localhost — the Oidis server runtime framework. The core
components are:
CLI input (oidis <command>)
│
▼
ProgramArgs ← Parses CLI arguments, maps them to task names and options
│
▼
Loader ← Application entry point; bootstraps all subsystems
│
├── EnvironmentArgs ← Loads project config (package.conf.jsonp → imports → solution → private.conf)
├── FileSystemHandler ← File I/O abstraction
├── Terminal ← Shell command execution
├── HttpServer ← Built-in dev server
└── TasksResolver ← Discovers and executes tasks
│
├── Task classes (auto-discovered via Reflection)
└── ModulesResolver ← External script hooks (before/after events)
Loader
Loader is the application singleton — every component accesses shared state through it:
Loader.getInstance().getProjectConfig() // IProject — target project config
Loader.getInstance().getAppConfiguration() // IAppConfiguration — builder global config
Loader.getInstance().getAppProperties() // IProperties — computed build paths & capabilities
Loader.getInstance().getProgramArgs() // ProgramArgs — parsed CLI arguments
Loader.getInstance().getFileSystemHandler() // FileSystemHandler — file I/O
Loader.getInstance().getTerminal() // Terminal — shell execution
Startup Sequence
- Bootstrap — Loader initializes subsystems (LogProcessor, FileSystem, Terminal, HttpServer)
- Parse args —
ProgramArgsmaps CLI arguments to task names - Load project env —
EnvironmentArgs.LoadProjectEnvironment()loads builder's own config - Load task modules — all compiled
.jstask files are imported dynamically - Refresh Reflection —
Reflection.Refresh()discovers allIBaseTaskimplementors - Create TasksResolver — discovers and registers all task instances
- Run
solution-loader— loads the target project'spackage.conf.jsonpand resolves solution - Execute requested tasks —
TasksResolver.Resolve(tasks)runs the task chain
Task System
All builder functionality is implemented as tasks — TypeScript classes extending BaseTask and
implementing the IBaseTask interface. There are 120+ built-in tasks.
Task Discovery
Tasks are discovered automatically at startup via Reflection. Any class that:
- Implements
IBaseTask - Is loaded into memory
is registered automatically. No manual registration needed.
Task Names
A task's name is derived from its class name, lowercased, with the namespace removed:
| Class name | Task name |
|---|---|
TypeScriptCompile | typescript |
ProjectCleanup | project-cleanup |
RunUnitTest | run-unit-test |
SassCompress | sass-compress |
Task:Option Syntax
Many tasks accept a subtype via a colon separator: task:option. The part before : is the task
name; the part after is passed to Process($option):
oidis build:prod # task=build, option=prod
oidis test:lint # task=test, option=lint
oidis project-cleanup:all # task=project-cleanup, option=all
This works both on the CLI and inside modules.register.json hook definitions.
Task Execution Flow
For each task in the resolved chain:
1. ModulesResolver.getTaskEvents(taskName)
→ returns { before: [...], after: [...] }
2. Build execution set: [...before-hooks, task, ...after-hooks]
3. For each entry in the set:
a. Log: "Running <task> task"
b. Call task.Process($option)
c. Await completion
d. Handle errors
Chaining Tasks
Tasks can trigger other tasks internally using runTaskAsync():
// Inside a task's processAsync():
await this.runTaskAsync("typescript");
await this.runTaskAsync(["sass-compress", "jslint"]);
This re-enters TasksResolver.Resolve(), including all before/after hooks of the chained tasks.
BaseTask API
All tasks extend BaseTask. The key protected members available to every task:
| Property | Type | Description |
|---|---|---|
this.project | IProject | Target project configuration from package.conf.jsonp |
this.properties | IProperties | Computed build paths and project capabilities |
this.programArgs | ProgramArgs | Parsed CLI arguments |
this.build | IBuildArgs | Build metadata (type, time, platform, release name) |
this.builderConfig | IAppConfiguration | Builder's own global configuration |
this.fileSystem | FileSystemHandler | File I/O operations |
this.terminal | Terminal | Shell command execution |
this.externalModules | string | Path to <appdata>/external_modules |
this.wuiModules | string | Path to <appdata>/wui_modules/<type> |
Key methods:
| Method | Description |
|---|---|
processAsync($option?) | Override this — task implementation |
runTaskAsync($tasks) | Run other tasks by name (with hooks) |
resolveExternConfig($name) | Load a tool config from resource/configs/ |
getDependenciesTree($option?) | Declare task dependencies (override to specify) |
Implementing a task:
export class MyTask extends BaseTask {
protected async processAsync($option? : string) : Promise<void> {
// Access project config, build paths, run shell commands:
const version : string = this.project.version;
const src : string = this.properties.sources;
await this.terminal.SpawnAsync("my-tool", ["--input", src, "--option", $option]);
// Chain other tasks:
await this.runTaskAsync("typescript");
}
}
Module System
Modules are external scripts (Node.js or other interpreters) that hook into the task lifecycle via
before/after events. They are configured in package.conf.jsonp under modules, or in
resource/configs/modules.register.json.
"modules": {
"my-hook": {
"script": "resource/scripts/my-hook.js",
"events": {
"before": "compile",
"after": ["typescript", "sass-compress"]
}
}
}
A module can also replace a built-in task by setting overrideTask: true:
"modules": {
"typescript": {
"script": "resource/scripts/custom-ts.js",
"overrideTask": true
}
}
See Module System for full details.
Configuration System
The builder uses layered JSONP configuration files. Every project has:
| File | Committed | Description |
|---|---|---|
package.conf.jsonp | Yes | Project identity, dependencies, build targets, deploy servers |
private.conf.jsonp | No | Machine-specific overrides: local paths, credentials |
Configuration is loaded in layers (later layers override earlier):
- Builder global config (builder's own
commons.jsonp, fromimports) package.conf.jsonp- Imported configs (via
importsfield) - Active solution config (selected by
--solutionflag) private.conf.jsonp
See Configuration Reference for the full schema.
IProperties — Computed Build State
After loading the project config, the builder computes IProperties — a set of resolved paths and
capability flags used by all tasks:
| Property | Description |
|---|---|
properties.projectBase | Absolute path to the target project root |
properties.binBase | Absolute path to the builder installation |
properties.sources | Path to source/typescript/ |
properties.resources | Path to resource/ |
properties.dependencies | Path to dependencies/ |
properties.dest | Path to build/target/ |
properties.compiled | Path to build/compiled/ |
properties.tmp | Path to build/cache/ |
properties.packageName | Project name from config |
properties.packageVersion | Project version from config |
properties.projectHas | Capability flags (see below) |
properties.projectHas capability flags:
this.properties.projectHas.TypeScript.Source() // has TypeScript source code
this.properties.projectHas.TypeScript.Tests() // has TypeScript unit tests
this.properties.projectHas.Java.Source() // has Java source code
this.properties.projectHas.Cpp.Source() // has C++ source code
this.properties.projectHas.Python.Source() // has Python source code
this.properties.projectHas.SASS() // has SASS/SCSS files
this.properties.projectHas.Resources() // has resource files
this.properties.projectHas.SeleniumTests() // has Selenium integration tests
this.properties.projectHas.ESModules() // uses ES module format
Tasks use these flags to skip irrelevant compilation steps automatically.
IBuildArgs — Build Context
Available as this.build inside every task:
| Field | Type | Description |
|---|---|---|
type | CliTaskType | Build type: dev, eap, prod |
isRebuild | boolean | True if triggered by rebuild-* command |
isTest | boolean | True if --with-test was passed |
platform | string | Target platform identifier |
releaseName | string | Name of the active release |
time | Date | Build start time |
timestamp | number | Build timestamp in milliseconds |
year | number | Current year (used in copyright strings) |
Environment Path Management
Oidis Builder manages the PATH environment variable to expose toolchains from external_modules/.
This means tools like java, python, cmake, gcc, doxygen are accessible without system-wide
installation if they are present in external_modules/:
| Toolchain | Directory |
|---|---|
| JDK / Maven | external_modules/jdk, external_modules/maven |
| GCC | external_modules/gcc |
| ARM GCC | external_modules/aarch32, external_modules/aarch64 |
| CMake | external_modules/cmake |
| Python | external_modules/python, external_modules/python3 |
| Doxygen | external_modules/doxygen |
| Git | external_modules/git |
| UPX | external_modules/upx |
| MSYS2 (Windows) | external_modules/msys2 |
Run oidis install to download and install these toolchains automatically.
Remote Execution & Builder Forwarding
The builder supports transparent remote task execution. A project can declare a preferred builder
location in package.conf.jsonp:
"builder": {
"location": "service", // forward to local Builder service
"location": "agent", // forward to Oidis Hub agent
"location": "/path/to/builder", // forward to specific builder binary
"port": 3666 // service port (implies "service" location)
}
When a remote builder is configured, tasks are forwarded transparently:
--service→ forward to running Builder service on same machine--hub→ forward to Oidis Hub agent--agent/oidis agent→ connect this builder to Oidis Hub as an agent
See CLI Reference for command details.
ForceCompile
ForceCompile.ts is the manifest that imports classes resolved only at runtime by namespace. Every build that
compiles TypeScript (oidis build dev, prod, eap) runs typescript-reference:source, which adds each project
source file containing @Extern(, @Resolver( or @Route( to the generated block of ForceCompile.ts.
oidis install does not update it. Interface registrations (typescript-interfaces) and namespace mappings
(typescript-mappings) are separate tasks of the same build step.
See ForceCompile for details.
Pages in This Section
| Page | Purpose |
|---|---|
| CLI Reference | All CLI commands, flags, and usage examples |
| Configuration | package.conf.jsonp schema, layered config, and private.conf.jsonp |
| Tasks Reference | Catalog of all 120+ built-in tasks with descriptions |
| Build Process | Step-by-step breakdown of oidis build — from install to package |
| Module System | External script hooks — before/after events, task overrides |
| Deploy | Deployment pipeline — dev, staging, and production targets |
| Extending | Writing custom tasks and integrating third-party tools |
| Troubleshooting | Common build errors, diagnostics, and solutions |
See also: CLI Reference | Configuration | Architecture Overview