# GitConverter.Lib `GitConverter.Lib` is the core library that implements GIS conversion logic, detection heuristics and supporting infrastructure used by the ConsoleApp and test projects. This README summarizes the library responsibilities, public surface, usage patterns, testing guidance, extension steps and operational notes for maintainers. > Targets: .NET Standard 2.1 (consumable by .NET 9 hosts) Contents - Overview - Responsibilities - Public surface & key types - Quickstart (host usage) - Logging and diagnostics - Licensing (Aspose.GIS) - Testing guidance - Extending the library (adding formats) - Packaging & compatibility - Troubleshooting - Contribution guidance - Maintainer checklist ## Overview The library provides a small, focused API to convert between GIS formats (CSV, Shapefile, GML, GeoJSON and others) while centralizing file-system safety, archive handling and detection logic. Converters implement `IConverter` and are resolved by the registry-style `ConverterFactory`. ## Responsibilities - Implement format-specific converters (Aspose.GIS-backed or lightweight implementations). - Provide utilities for: - Input validation and directory preparation (`ConverterUtils`). - Archive inspection and safe extraction (zip-slip protection). - JSON format detection heuristics (`JsonFormatDetector`) for GeoJSON, EsriJSON, TopoJSON and GeoJSON Sequence (NDJSON). - Mapping of canonical option strings to drivers and file extension helpers. - Expose a lightweight logging abstraction (`IAppLogger` / `Log`) so tests and hosts capture diagnostics. - Centralize license application (`AsposeLicenseManager`) so converters are license-aware without embedding licensing logic. ## Public surface & key types - `IConverter` — converter contract. Main method: - `ConversionResult Convert(string gisInputFilePath, string gisSourceFormatOption, string gisTargetFormatOption, string outputFolderPath, string tempFolderPath)` - `IConverterFactory` / `ConverterFactory` — resolve converters by friendly display keys. Use `TryCreate` for non-throwing flows and `Create` when you want an exception with suggestion on unknown keys. - `ConverterUtils` — path validation, archive listing, safe extraction, output path construction and temp cleanup helpers. - `JsonFormatDetector` — heuristics and bounded-header sniffers for JSON formats. - `ConversionResult` / `ConversionStatus` — uniform result carrier for converters. - `FileExtension` / `FileExtensionHelpers` — canonical extension mappings used to build output file names. - `AsposeLicenseManager` — centralized license application helper. ## Quickstart (host usage) Typical flow for a host (ConsoleApp or service): 1. Configure logging early (see `GitConverter.Lib.Logging.Log`). 2. Optionally apply Aspose license: `AsposeLicenseManager.ApplyLicense()` and fail gracefully if required. 3. Construct or obtain a `ConverterFactory` instance. 4. Validate inputs using `ConverterUtils.ValidateInputs` and prepare output/temp folders with `ConverterUtils.PreparePaths`. 5. Resolve a converter using `TryCreate(sourceOrTargetOption, out var converter)` and call `converter.Convert(...)`. 6. Inspect `ConversionResult` and map to exit codes or UI messages. ### Minimal host wiring (example) ```csharp // Configure logging (optional) Log.SetFile("logs/conversion.log", "Info"); Log.Enable(); // Apply Aspose license (optional for licensed converters) if (!AsposeLicenseManager.ApplyLicense()) { Console.Error.WriteLine("Aspose license not applied; licensed converters may fail."); } var factory = new ConverterFactory(); if (!factory.TryCreate("GeoJson", out var converter)) { Console.Error.WriteLine("Unknown target format"); return 1; } var validation = ConverterUtils.ValidateInputs(inputPath, outputFolder, tempFolder); if (validation != null) { Console.Error.WriteLine(validation.Message); return 1; } var prep = ConverterUtils.PreparePaths(outputFolder, tempFolder); if (prep != null) { Console.Error.WriteLine(prep.Message); return 1; } var result = converter.Convert(inputPath, sourceOption, targetOption, outputFolder, tempFolder); Console.WriteLine(result.Message); return result.Status == ConversionStatus.Success ? 0 : 1; ``` ## Logging and diagnostics - Use the `Log` façade (`Log.Debug`, `Log.Info`, `Log.Warn`, `Log.Error`) throughout the library. - In production configure file logging via `Log.SetFile(path, level)` and call `Log.Enable()`. - In unit tests replace `Log.Current` with a `TestLogger` to capture messages for assertions using `LogAssert`. Key tokens to search for when diagnosing failures: - `starting conversion (option='...')` - `Conversion succeeded:` / `Conversion failed:` - Archive extraction / zip-slip warnings - `lookup miss` and factory registration summaries ## Licensing (Aspose.GIS) - `AsposeLicenseManager.ApplyLicense()` attempts to apply an Aspose license (embedded resource first, optional file fallback) and returns `true` on success. - The method logs diagnostics and returns `false` on failure (it does not throw); callers should surface friendly messages to users. - Do not commit license files to source control. Provision via CI secrets or secure provisioning for licensed integration runs. ## Testing guidance - Unit tests - Inject a small `registrations` dictionary and a `TestLogger` into `ConverterFactory` to avoid creating heavy converters. - Test `ConverterUtils`, `FactoryHelpers` and `JsonFormatDetector` with small synthetic inputs. - Prefer `TryCreate` in tests unless verifying suggestion/exception behavior. - Integration tests - Place small samples under `TestsApp/TestData/` and mark with `PreserveNewest`. - Gate licensed or expensive integration tests using environment flags such as `GITCONVERTER_ENABLE_INTEGRATION=1` and check `AsposeLicenseManager.ApplyLicense()` before exercising licensed flows. - Assertions - Use `FileExtensionHelpers.ToDotExtension(...)` to derive expected file suffixes. - Prefer case-insensitive substring checks for messages and log tokens to reduce brittleness. ## Extending the library (adding formats) 1. Implement an `IConverter` (or reuse `UniversalGisConverter` for simple wrappers). 2. Add option key and registration in `ConverterFactory`. 3. Map driver and file extension in `ConverterUtils` and `FileExtensionHelpers`. 4. Add unit tests for detection and factory routing and a small integration sample/test if applicable. ## Packaging & compatibility - Targets `.NET Standard 2.1` so the library can be consumed by `.NET 9` hosts. - Keep public APIs platform-agnostic to preserve portability. ## Troubleshooting - Missing converter / lookup failures: verify `FactoryHelpers.NormalizeKey` and review factory startup logs for supported keys. - Archive extraction problems: inspect archive listing helpers and zip-slip warnings; ensure test zips include expected entry paths (see TestData README for zip tips). - License-related failures: confirm embedded resource name or configured path and file permissions. ## Contribution guidance - Open issues for bugs, missing formats or flaky tests. Provide failing test name, stack trace, logs and sample artifacts when possible. - When contributing converters include unit tests for edge cases (ambiguous JSON, KMZ detection, zipped FileGDB) and minimal integration samples. ## Maintainer checklist - When adding a format: - Add option keys and registrations in `ConverterFactory`. - Update `FileExtensionHelpers` and `ConverterUtils` mappings. - Add unit tests for detection and behavior. - Add integration sample under `TestsApp/TestData/` and a gated test if appropriate. ## API documentation Per-type XML remarks are available in source files and surface in IDE IntelliSense. Key types: - `GitConverter.Lib.Converters.IConverter` - `GitConverter.Lib.Factories.ConverterFactory` - `GitConverter.Lib.Utils.ConverterUtils` - `GitConverter.Lib.Logging.Log` --- If you want I can add a `Quickstart.md` file with runnable examples, or add a small `examples/` folder demonstrating common host wiring.