Skip to content

Develop#6

Merged
walmir-silva merged 14 commits into
mainfrom
develop
Mar 2, 2026
Merged

Develop#6
walmir-silva merged 14 commits into
mainfrom
develop

Conversation

@walmir-silva
Copy link
Copy Markdown
Contributor

No description provided.

BREAKING CHANGE: complete API rewrite, drops kariricode/data-structure

- Zero external dependencies, PHP 8.4+ required
- AES-256-GCM transparent encryption (encrypted: prefix)
- OPcache-friendly cache (dumpCache / loadFromCache)
- Fluent validation DSL: validate()->required()->isInteger()->between()->assert()
- Schema-based validation (.env.schema declarative format)
- Environment cascade loading (bootEnv)
- Variable processors: CsvToArrayProcessor, UrlNormalizerProcessor, TrimProcessor, Base64Decode
- Glob pattern filtering via allowList / denyList
- Source tracking and debug() introspection
- CLI tooling: bin/kariricode-dotenv
- 8 ADRs and 7 SPECs in docs/
- 161 tests, 275 assertions, zero warnings
…ar devkit)

- Remove .docker/ folder (Dockerfile + kariricode-php.ini)
- Remove require-dev (phpunit, phpstan, php-cs-fixer) from composer.json
- Tools provided by global kariricode-devkit kcode.phar
- composer.lock updated (53 packages removed)
…Makefile

- Remove .php-cs-fixer.php (tool managed by global kcode.phar)
- Remove .vscode/settings.json (referenced removed vendor tools)
- Rewrite Makefile: replace 175-line docker-centric Makefile with
  clean devkit-aware version using global phpunit/phpstan/php-cs-fixer
- Remove src/Console/ (empty directory, not in v4.x scope)
- Remove src/{...} and tests/{...} stale brace-expansion artifact dirs
- Remove Makefile (kcode.phar handles all dev commands)
- Remove phpunit.xml (kcode.phar provides phpunit config)
- Remove README.pt-br.md (legacy PT-BR duplicate)
- Full feature coverage: type casting, interpolation, load modes, bootEnv
- Fluent validation DSL with all rules documented
- AES-256-GCM encryption usage walkthrough
- OPcache caching section
- Variable processors with glob pattern matching
- Debug and introspection API
- Architecture table with ADR/SPEC links
- Project stats table
- Contributing section using kcode global
- Centered badges + footer in devkit style
…ration

Two missing immutable mutation methods declared in docblocks and tested
but never implemented. Both follow the existing with*() pattern defined
in ARFA 1.3 P1 (every transformation produces a new state instance).

Used in DotenvConfiguration chaining:
  $config->withAllowList(['DB_*'])->withDenyList(['SECRET*'])

@SInCE 4.0.0
…nd fix return types

Psalm 6.x enforces #[Override] on all methods that implement an interface
or override a parent. 45 issues auto-fixed by:
  psalm --config=.kcode/psalm.xml --alter --issues=MissingOverrideAttribute,InvalidReturnType

Files touched:
  - src/Core/DotenvParser.php
  - src/Dotenv.php
  - src/Processor/* (4 processors)
  - src/Type/Caster/* (6 casters)
  - src/Type/Detector/* (6 detectors)
  - src/Validation/Rule/* (10 rule classes)

No logic changes — annotation-only.
1. DotenvConfigurationTest::testDefaultValues — asserted $config->putenv
   (non-existent property) instead of $config->usePutenv; also corrected
   expected value: usePutenv defaults to false (thread-safety default).

2. DotenvIntegrationTest x5 — ImmutableException thrown before the test
   assertion's expected exception because APP_ENV persisted from a prior test.
   Fixed by using LoadMode::Overwrite in the four affected test cases:
     - testValidationDslPasses
     - testValidationDslCollectsAllErrors
     - testSchemaValidationPasses
     - testSchemaValidationFails

Result: 205 tests · 396 assertions · 0 failures · 0 errors (PHPUnit 12.5)
- Badge: 161 passing → 205 passing
- Test suite: 161 tests/275 assertions → 205 tests/396 assertions
- PHP source files: 36 → 38 (DotenvConfiguration + DotenvParser growth)
…afe resolveRawValue

DotenvParser.php:
- Closed over $_ENV/$_SERVER with is_string() guards to avoid returning
  non-empty-list<string> (which fails the callable(array<>):string contract).
- Both closures now explicitly declare : string return type.
- Removed incorrect @psalm-return scalar|string[] annotations.

Dotenv.php:
- resolveRawValue(): declared proper ?string return type, replaced raw
  $_ENV/$_SERVER access with is_string() guards (Psalm PossiblyInvalidCast).
- bootEnv(): wrapped envName in (string) cast (Psalm PossiblyInvalidCast
  in string interpolation "{}.$envName").
- validate(): replaced fn()=>resolveRawValue() short-closure with explicit
  body calling (string) cast to satisfy ?string declared return.
…d errors

EnvironmentValidator.php:
- All variadic $names spreads wrapped with array_values() to produce
  list<string> instead of array<array-key,string> (Psalm PropertyTypeCoercion).
- AllowedValuesRule constructor now receives array_values($allowed)
  to produce list<string> (ArgumentTypeCoercion).

BetweenRule.php:
- Replaced $value + 0 with (float) $value — Psalm strict mode rejects
  mixed numeric arithmetic (InvalidOperand). Semantics are identical.

MatchesRegexRule.php:
- Added @psalm-suppress ArgumentTypeCoercion for preg_match($this->pattern)
  — the pattern is always a non-empty-string (guaranteed by constructor);
  Psalm can't infer this without a runtime assertion.
Encryptor.php:
- (string) hex2bin() — hex2bin returns false|string; ctype_xdigit check
  in the ternary makes the false branch unreachable, (string) cast satisfies Psalm.
- (string) openssl_error_string() — returns false on no error; (string) cast
  converts false to empty string safely.

KeyPair.php:
- (string) hex2bin($privateKey) — same pattern; validated by ctype_xdigit guard.

SchemaParser.php:
- Added explicit $eqPos === false guard after strpos() call inside
  str_contains() block. str_contains() guarantees presence but Psalm cannot
  infer that strpos() is therefore non-false without the explicit check.

CsvToArrayProcessor.php:
- Added $separator = ... !== '' ? ... : ',' guard before explode() to
  satisfy Psalm's non-empty-string requirement for the separator argument.
  Fallback to ',' is safe and semantically correct.
PHPStan fixes:
- Cache/PhpFileCache.php: (int) getmypid(), $data['__metadata'] array access
  guarded via is_array(), return type assertion via @var annotation.
- Core/DotenvParser.php: added @param list<string> $lines and
  @param array<string,string> $resolvedVariables to all private methods;
  @var int<0,max> assertions on array offsets $lineNumber and $nextLineIndex.
- Dotenv.php: DOTENV_PRIVATE_KEY from $_SERVER/$_ENV guarded with is_string()
  to fix 'mixed given to Encryptor constructor'.
- Processor/CsvToArrayProcessor.php: @return list<string> annotation.
- Schema/SchemaParser.php: @param array<string,string> for boolDirective.
- Type/Caster/ArrayCaster.php: json_decode → array_values() for list<mixed>.
- Type/Caster/JsonCaster.php: json_decode → @var array<string,mixed> assertion.
- Validation/EnvironmentValidator.php: @param list<string> $allowed on
  allowedValues(); removed redundant array_values() (RedundantFunctionCall).

Psalm fixes:
- Cache/PhpFileCache.php: PossiblyFalseOperand on getmypid() → (int) cast.
- Core/DotenvParser.php: InvalidArrayOffset → @var int<0,max> assertions.
- Dotenv.php: removed (string) redundant casts (resolveRawValue returns ?string).

Result:
  ✓ cs-fixer   passed
  ✓ phpstan    passed (Level 9, 0 errors)
  ✓ psalm      passed (0 errors)
  ✓ phpunit    passed (205 tests · 396 assertions · 0 failures)
  ✓ All 4 tool(s) passed
@walmir-silva walmir-silva merged commit 159454d into main Mar 2, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant