Thank you for contributing to the Icod command-suite ports. The repository contains managed implementations of GNU Coreutils, Fileutils, Textutils, Diffutils, Patch, and related command families. Changes should preserve command compatibility, cross-platform behavior, and the repository's shared architectural boundaries.
- Target framework:
net10.0. Other frameworks can be included, but we must support at leastnet10.0. - Language version: C# 13, declared as
<LangVersion>13.0</LangVersion>in every project. - Nullable reference types and implicit global usings remain enabled where the existing project enables them.
- Supported CI runners are
windows-latest,ubuntu-latest, andmacos-latest; best-effort BSD portability is also a project goal. - Repository text files use UTF-8 with LF line endings. Configure editors and Git to preserve LF; do not commit CRLF-only churn.
- Runtime command output should use
Environment.NewLineunless the command contract requires a byte delimiter or preserves input record terminators. - Literal newline escapes such as
\nand\r\nare permitted only when they are part of the utility’s data semantics, escape grammar, or documented byte transformation. They are never used as the host platform’s generated line separator. - Generated line endings use
WriteLine,WriteLineAsync, orEnvironment.NewLine. Line-oriented input usesReadLine,ReadLineAsync, andEnvironment.NewLineas appropriate. Code must not hard-code\nor\r\nfor host line-reading or line-writing semantics. - When multiple strings are sent to
WriteAsync,WriteLineAsync, or related output methods, combine them withSystem.String.Concatrather than the+operator. - Do your utmost to properly document every public, protected, and internal type and member. Use
<inheritdoc/>where appropriate to avoid duplicating documentation.
Do not change the target framework, language version, configuration policy, signing policy, or repository line-ending convention in an unrelated contribution.
All project-related code files should go in the src directory. Tests should go in the tests directory.
- Keep every test project in the top-level
testssolution folder, not under an individual command's solution folder. - Preserve the established Debug, Staging, and Release property groups in every
.csproj. - Release builds treat warnings as errors except
CS1591under the current repository policy. - Add substantive XML documentation to every public, protected, and internal type and member.
- Add or update a directory
README.mdwhen a source directory contains more than one implementation file. - Do not introduce a
Directory.Build.propspolicy migration as part of an unrelated command change.
Follow the repository .editorconfig and the style already used in the surrounding project. In particular:
- use tabs for indentation where the existing files do;
- use PascalCase for types and members and camelCase for locals and parameters;
- use
varwhen the assigned type is clear; - keep nullable flow explicit rather than suppressing warnings casually;
- prefer checked arithmetic and explicit resource limits for untrusted input;
- propagate
CancellationTokenthrough asynchronous work; - use TAP-based asynchronous orchestration and retain the established synchronous compatibility wrapper when the command family exposes one;
- use the shared declarative option parser and shared diagnostic conventions;
Unsupported platform behavior must produce a controlled diagnostic and nonzero status. It must not silently report success or fabricate Unix capabilities.
Tests should include the relevant combinations of:
- ordinary success and GNU-compatible status classes;
- invalid options, malformed input, and controlled operational failures;
- cancellation and deterministic cleanup;
- LF, CRLF, CR, NUL-delimited, binary, and incomplete-final-record cases where applicable;
- Windows and POSIX pathname grammar through synthetic providers;
- real host links or special files only when capability checks can skip unsupported cases deterministically;
- resource limits and adversarial inputs;
- multiple operands or files and continuation after per-item failure;
- executable/process-host behavior in addition to direct command calls where the public CLI contract is affected.
Keep test workspaces uniquely named and delete only resources owned by that test. Avoid assertions over a global temporary-file namespace that another test assembly may use concurrently.
Fixtures must record provenance. Keep GNU-generated, Icod-generated, independent, malformed, binary, and security fixtures separated where those distinctions matter. Do not generate an expected result with the same implementation being tested. Native-tool differential tests must be opt-in and must not be required for the normal test suite.
Follow the installed xUnit analyzer guidance. Prefer dedicated assertions such as Assert.Contains, Assert.DoesNotContain, Assert.Single, and Assert.ThrowsAsync over wrapping the same condition in Assert.True.
From the repository root, restore, build, and test the solution:
dotnet clean Icod.Path.sln -c Debug
dotnet restore Icod.Path.sln
dotnet build Icod.Path.sln -c Debug --no-restore
dotnet test Icod.Path.sln -c Debug --no-build
Also validate Release when the change is intended for completion or merge:
dotnet clean Icod.Path.sln -c Release
dotnet build Icod.Path.sln -c Release
dotnet test Icod.Path.sln -c Release --no-build
Repository build scripts may be used instead when they cover the same solution-wide steps. Run the focused test project while developing, but do not substitute that for the full solution test run before submitting a pull request.
The repository roadmap governs suite ordering, completion gates, and shared infrastructure. Suite-specific roadmaps govern detailed command behavior. Update the applicable roadmap when completing a scheduled phase, but distinguish clearly among:
- implemented behavior;
- locally validated behavior;
- three-runner CI validation;
- deliberately deferred behavior;
- platform-limited behavior.
Do not mark a gate or phase complete by weakening its tests or by claiming validation that was not run.
Use a focused branch and keep unrelated formatting or project-policy churn out of the change. A pull request should:
- explain the GNU or suite behavior being implemented;
- identify important compatibility decisions and intentional divergences;
- list added or changed tests;
- report the exact build and test commands run and the platforms used;
- update relevant documentation and roadmap status;
- call out any remaining unsupported or deferred cases.
Use an imperative, present-tense commit subject such as Implement patch filename selection. Keep the subject concise and add a body when the compatibility or safety reasoning is not obvious.
For questions or design changes that affect more than one command family, open an issue or discuss the contract before creating another shared abstraction.