Skip to content
Merged
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
6 changes: 3 additions & 3 deletions docs/src/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ It provides infrastructure shared by every package above it.

Three things to keep in mind:

1. **No top-level exports.** `using CTBase` loads the package but brings no symbols
- **No top-level exports.** `using CTBase` loads the package but brings no symbols
into scope. Every symbol is accessed via its qualified path:
```julia
CTBase.Descriptions.add # ✓ always works
CTBase.Exceptions.NotImplemented
```
2. **Submodule-first API.** The public API lives in named submodules
- **Submodule-first API.** The public API lives in named submodules
(`Core`, `Exceptions`, `Traits`, `Data`, `Descriptions`, `Options`, `Strategies`,
`Orchestration`, `Differentiation`, `Interpolation`, `DevTools`, `Unicode`, …).
Bring a submodule's name into scope and call its API qualified:
Expand All @@ -40,7 +40,7 @@ Three things to keep in mind:
Exceptions.IncorrectArgument(...)
Traits.is_autonomous(...)
```
3. **Extension-backed features.** `run_tests`, `postprocess_coverage`, and
- **Extension-backed features.** `run_tests`, `postprocess_coverage`, and
`automatic_reference_documentation` require loading the matching weak dependency
(`Test`, `Coverage`, `Documenter` respectively) before they become active.
Likewise, the differentiation primitives of `CTBase.Differentiation` become active
Expand Down
32 changes: 16 additions & 16 deletions docs/src/guide/api-documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ docs/

The documentation generation happens in two stages:

1. **`api_reference.jl`**: Defines `generate_api_reference()` which calls `CTBase.automatic_reference_documentation()` for each module.
2. **`make.jl`**: Calls `with_api_reference()` which executes the generation and passes the pages to `Documenter.makedocs()`.
- **`api_reference.jl`**: Defines `generate_api_reference()` which calls `CTBase.automatic_reference_documentation()` for each module.
- **`make.jl`**: Calls `with_api_reference()` which executes the generation and passes the pages to `Documenter.makedocs()`.

## Setting Up API Documentation

Expand Down Expand Up @@ -254,9 +254,9 @@ end

`with_api_reference()` is a project-level wrapper (not part of CTBase) that:

1. Calls `generate_api_reference()` to register configurations.
2. Passes the resulting pages to your `makedocs()` call.
3. Cleans up temporary generated files after the build.
- Calls `generate_api_reference()` to register configurations.
- Passes the resulting pages to your `makedocs()` call.
- Cleans up temporary generated files after the build.

## DocType System

Expand Down Expand Up @@ -373,9 +373,9 @@ const MyExt = Base.get_extension(MyPackage, :MyExt)

**Solution**: Check that:

1. Docstrings are properly formatted with `"""`
2. Source files are correctly specified in `primary_modules`
3. The module is properly loaded
- Docstrings are properly formatted with `"""`
- Source files are correctly specified in `primary_modules`
- The module is properly loaded

### Issue: Too many symbols documented

Expand Down Expand Up @@ -413,14 +413,14 @@ MarkdownAST = "..."

## Best Practices

1. **Exclude internal symbols**: Use the `exclude` parameter to hide implementation details or compiler-generated symbols
2. **Separate public and private**: Create separate pages for public and private APIs to keep the end-user documentation focused
3. **Document external modules**: Use `external_modules_to_document` to include methods from other packages that your package extends (e.g., `Base` or `Plots`)
4. **Check extensions before documenting**: Always use `Base.get_extension()` to safely check for optional dependencies before calling `automatic_reference_documentation` on them
5. **Use meaningful titles**: Choose clear, descriptive titles for each documentation page
6. **Organize by module**: Group related functionality together
7. **Keep it up-to-date**: Regenerate documentation with each release
8. **Test documentation builds**: Include documentation building in your CI pipeline
- **Exclude internal symbols**: Use the `exclude` parameter to hide implementation details or compiler-generated symbols
- **Separate public and private**: Create separate pages for public and private APIs to keep the end-user documentation focused
- **Document external modules**: Use `external_modules_to_document` to include methods from other packages that your package extends (e.g., `Base` or `Plots`)
- **Check extensions before documenting**: Always use `Base.get_extension()` to safely check for optional dependencies before calling `automatic_reference_documentation` on them
- **Use meaningful titles**: Choose clear, descriptive titles for each documentation page
- **Organize by module**: Group related functionality together
- **Keep it up-to-date**: Regenerate documentation with each release
- **Test documentation builds**: Include documentation building in your CI pipeline

## CI/CD Integration

Expand Down
20 changes: 10 additions & 10 deletions docs/src/guide/coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,19 @@ src/MyModule.jl:42
- **Low coverage (<70%)**: Needs more tests, many code paths untested

Focus on:
1. **Critical paths**: Ensure core functionality is well-tested
2. **Error handling**: Test exception paths
3. **Edge cases**: Test boundary conditions
- **Critical paths**: Ensure core functionality is well-tested
- **Error handling**: Test exception paths
- **Edge cases**: Test boundary conditions

## Best Practices

1. **Run coverage regularly**: Include in your development workflow
2. **Focus on quality, not just quantity**: 100% coverage doesn't mean bug-free code
3. **Test meaningful paths**: Cover important logic, not just trivial getters
4. **Use coverage to find gaps**: Identify untested code paths
5. **Integrate with CI**: Automate coverage reporting in your CI pipeline
6. **Set coverage thresholds**: Maintain or improve coverage over time
7. **Review uncovered lines**: Understand why code isn't covered
- **Run coverage regularly**: Include in your development workflow
- **Focus on quality, not just quantity**: 100% coverage doesn't mean bug-free code
- **Test meaningful paths**: Cover important logic, not just trivial getters
- **Use coverage to find gaps**: Identify untested code paths
- **Integrate with CI**: Automate coverage reporting in your CI pipeline
- **Set coverage thresholds**: Maintain or improve coverage over time
- **Review uncovered lines**: Understand why code isn't covered

## CI/CD Integration

Expand Down
12 changes: 6 additions & 6 deletions docs/src/guide/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,12 @@ This makes debugging faster by providing all the information needed to understan

## Best Practices

1. **Choose the right exception type**: Use the decision table above
2. **Provide context**: Always fill in optional fields when available
3. **Be specific**: Include actual values in error messages
4. **Suggest solutions**: Help users fix the problem
5. **Catch specifically**: Use `e isa SpecificException` rather than catching all exceptions
6. **Don't hide errors**: Only catch exceptions you can handle
- **Choose the right exception type**: Use the decision table above
- **Provide context**: Always fill in optional fields when available
- **Be specific**: Include actual values in error messages
- **Suggest solutions**: Help users fix the problem
- **Catch specifically**: Use `e isa SpecificException` rather than catching all exceptions
- **Don't hide errors**: Only catch exceptions you can handle

## See Also

Expand Down
16 changes: 8 additions & 8 deletions docs/src/guide/options-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ def = Options.OptionDefinition(

The constructor automatically:

1. Checks that `default` matches the declared `type`
2. Runs the `validator` on the `default` value (if both are provided)
3. Skips validation when `default` is `NotProvided`
- Checks that `default` matches the declared `type`
- Runs the `validator` on the `default` value (if both are provided)
- Skips validation when `default` is `NotProvided`

Type mismatch in the constructor:

Expand Down Expand Up @@ -379,11 +379,11 @@ println("Remaining: ", remaining)

The function:

1. Searches all names (primary + aliases)
2. Validates the type
3. Runs the validator
4. Returns `OptionValue` with `:user` source
5. Removes the matched key from remaining kwargs
- Searches all names (primary + aliases)
- Validates the type
- Runs the validator
- Returns `OptionValue` with `:user` source
- Removes the matched key from remaining kwargs

Type mismatch in extraction:

Expand Down
8 changes: 4 additions & 4 deletions docs/src/guide/orchestration-and-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ Build option ownership map

### How it works internally

1. **Extract action options** — options like `display` are matched against `action_defs` and removed from the pool
2. **Build strategy-to-family map** — maps each strategy ID to its family name (e.g., `:ipopt → :solver`)
3. **Build option ownership map** — scans all strategy metadata to determine which family defines each option name
4. **Route each remaining option** — auto-route if unambiguous, require disambiguation if ambiguous, error if unknown
- **Extract action options** — options like `display` are matched against `action_defs` and removed from the pool
- **Build strategy-to-family map** — maps each strategy ID to its family name (e.g., `:ipopt → :solver`)
- **Build option ownership map** — scans all strategy metadata to determine which family defines each option name
- **Route each remaining option** — auto-route if unambiguous, require disambiguation if ambiguous, error if unknown

## Disambiguation

Expand Down
8 changes: 4 additions & 4 deletions docs/src/guide/strategy-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ Strategies.describe(Strategies.CPU)

Every parameter type must:

1. **Subtype `AbstractStrategyParameter`**
2. **Be a singleton** (no fields)
3. **Implement `id(::Type{<:YourParameter})`** returning a `Symbol`
4. **Implement `description(::Type{<:YourParameter})`** returning a `String`
- **Subtype `AbstractStrategyParameter`**
- **Be a singleton** (no fields)
- **Implement `id(::Type{<:YourParameter})`** returning a `Symbol`
- **Implement `description(::Type{<:YourParameter})`** returning a `String`

```@example params
struct Distributed <: Strategies.AbstractStrategyParameter end
Expand Down
20 changes: 10 additions & 10 deletions docs/src/guide/test-runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ The entry point is [`CTBase.DevTools.run_tests`](@ref), activated by loading the

A robust testing architecture typically involves:

1. **Test Runner**: A `runtests.jl` file that allows running specific test groups via command-line arguments.
2. **Test Suite Structure**: Modular test files, each containing a main entry point function.
- **Test Runner**: A `runtests.jl` file that allows running specific test groups via command-line arguments.
- **Test Suite Structure**: Modular test files, each containing a main entry point function.

### Recommended Directory Structure

Expand Down Expand Up @@ -432,14 +432,14 @@ julia --project -e 'using Pkg; Pkg.test("MyPackage";

## Best Practices

1. **One test function per file**: Keep test files focused and easy to navigate
2. **Use descriptive names**: Name test files and functions clearly (e.g., `test_optimization.jl`, `test_optimization()`)
3. **Organize by feature**: Group related tests in subdirectories
4. **Fast tests first**: Place quick unit tests before slow integration tests
5. **Isolate test state**: Each test should be independent and not rely on execution order
6. **Use test fixtures**: Create helper functions for common test setup
7. **Document test requirements**: Note any special dependencies or setup needed
8. **No `test/` subdirectory in `test/`**: Avoid naming a subdirectory `test` inside your test directory
- **One test function per file**: Keep test files focused and easy to navigate
- **Use descriptive names**: Name test files and functions clearly (e.g., `test_optimization.jl`, `test_optimization()`)
- **Organize by feature**: Group related tests in subdirectories
- **Fast tests first**: Place quick unit tests before slow integration tests
- **Isolate test state**: Each test should be independent and not rely on execution order
- **Use test fixtures**: Create helper functions for common test setup
- **Document test requirements**: Note any special dependencies or setup needed
- **No `test/` subdirectory in `test/`**: Avoid naming a subdirectory `test` inside your test directory

## Integration with CI/CD

Expand Down
6 changes: 3 additions & 3 deletions src/Exceptions/Exceptions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ fields for better error reporting, suggestions, and context.

# Main Features

1. **Enriched Exceptions**: `IncorrectArgument`, `PreconditionError`, etc. with optional fields
2. **User-Friendly Display**: Clear, formatted error messages with emojis and sections
3. **Rich Context**: Detailed information for debugging and problem resolution
- **Enriched Exceptions**: `IncorrectArgument`, `PreconditionError`, etc. with optional fields
- **User-Friendly Display**: Clear, formatted error messages with emojis and sections
- **Rich Context**: Detailed information for debugging and problem resolution

# Usage

Expand Down
4 changes: 2 additions & 2 deletions src/Options/option_definition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ The validator should:
# Constructor Validation

The constructor performs the following validations:
1. Checks that `default` matches the specified `type` (unless `default` is `nothing` or `NotProvided`)
2. Runs the `validator` on the `default` value (if both are provided and `default` is not `NotProvided`)
- Checks that `default` matches the specified `type` (unless `default` is `nothing` or `NotProvided`)
- Runs the `validator` on the `default` value (if both are provided and `default` is not `NotProvided`)

# Example
```julia
Expand Down
8 changes: 4 additions & 4 deletions src/Strategies/api/builders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ $(TYPEDSIGNATURES)
Build a strategy instance from its ID and options.

This function creates a concrete strategy instance by:
1. Looking up the strategy type from its ID in the registry
2. Constructing the instance with the provided options
- Looking up the strategy type from its ID in the registry
- Constructing the instance with the provided options

# Arguments
- `id::Symbol`: Strategy identifier (e.g., `:adnlp`, `:ipopt`)
Expand Down Expand Up @@ -57,8 +57,8 @@ $(TYPEDSIGNATURES)
Build a parameterized strategy instance from ID, parameter, and options.

This function creates a concrete parameterized strategy instance by:
1. Looking up the parameterized strategy type from its ID and parameter
2. Constructing the instance with the provided options
- Looking up the parameterized strategy type from its ID and parameter
- Constructing the instance with the provided options

# Arguments
- `id::Symbol`: Strategy identifier (e.g., `:madnlp`)
Expand Down
14 changes: 7 additions & 7 deletions src/Strategies/api/configuration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ $(TYPEDSIGNATURES)
Build StrategyOptions from user kwargs and strategy metadata.

This function creates a StrategyOptions instance by:
1. Validating the mode parameter (`:strict` or `:permissive`)
2. Extracting known options from kwargs using the Options API
3. Handling unknown options based on the mode
4. Converting the extracted Dict to NamedTuple
5. Wrapping in StrategyOptions
- Validating the mode parameter (`:strict` or `:permissive`)
- Extracting known options from kwargs using the Options API
- Handling unknown options based on the mode
- Converting the extracted Dict to NamedTuple
- Wrapping in StrategyOptions

The Options.extract_options function handles:
- Alias resolution to primary names
Expand Down Expand Up @@ -145,8 +145,8 @@ $(TYPEDSIGNATURES)
Resolve an alias to its primary key name.

Searches through strategy metadata to find if a given key is either:
1. A primary option name
2. An alias for a primary option name
- A primary option name
- An alias for a primary option name

# Arguments
- `meta::StrategyMetadata`: Strategy metadata to search in
Expand Down
6 changes: 3 additions & 3 deletions src/Strategies/api/registry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ This function validates the registry structure and ensures:

# Validation Rules

1. **ID Uniqueness**: Within each family, all strategy `id()` values must be unique
2. **Type Hierarchy**: Each strategy must be a subtype of its family
3. **No Duplicates**: Each family can only appear once in the registry
- **ID Uniqueness**: Within each family, all strategy `id()` values must be unique
- **Type Hierarchy**: Each strategy must be a subtype of its family
- **No Duplicates**: Each family can only appear once in the registry

# Example
```julia-repl
Expand Down
4 changes: 2 additions & 2 deletions src/Strategies/api/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ $(TYPEDSIGNATURES)
Extract strategy options as a mutable Dict, ready for modification.

This is a convenience method that combines two steps into one:
1. Getting `StrategyOptions` from the strategy
2. Converting to `Dict` via `options_dict(StrategyOptions)`
- Getting `StrategyOptions` from the strategy
- Converting to `Dict` via `options_dict(StrategyOptions)`

# Arguments
- `strategy::AbstractStrategy`: Strategy instance (solver, modeler, etc.)
Expand Down
12 changes: 6 additions & 6 deletions src/Strategies/contract/abstract_strategy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ Methods defined on **instances** that provide the actual configuration:

Every concrete strategy must provide:

1. **Type definition** with an `options::StrategyOptions` field (recommended)
2. **Type-level methods** for `id` and `metadata`
3. **Constructor** accepting keyword arguments (uses `build_strategy_options`)
4. **Instance-level access** to configured options
- **Type definition** with an `options::StrategyOptions` field (recommended)
- **Type-level methods** for `id` and `metadata`
- **Constructor** accepting keyword arguments (uses `build_strategy_options`)
- **Instance-level access** to configured options

## Parameter Position Contract

Expand Down Expand Up @@ -350,8 +350,8 @@ Default implementation for `options(strategy::T)` with flexible field access.

This implementation supports two common patterns for strategy types:

1. **Field-based (recommended)**: Strategy has an `options::StrategyOptions` field
2. **Custom getter**: Strategy implements its own `options()` method
- **Field-based (recommended)**: Strategy has an `options::StrategyOptions` field
- **Custom getter**: Strategy implements its own `options()` method

If the strategy type has an `options` field, this implementation returns it.
Otherwise, it throws a `NotImplemented` error to indicate that the concrete
Expand Down
Loading