Skip to content
Open
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
27 changes: 27 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"version": 1,
"isRoot": true,
"tools": {
"mindee.cli": {
"version": "4.4.0",
"commands": [
"mindee"
],
"rollForward": false
},
"dotnet-delice": {
"version": "2.1.0",
"commands": [
"dotnet-delice"
],
"rollForward": false
},
"husky": {
"version": "0.9.1",
"commands": [
"husky"
],
"rollForward": false
}
}
}
6 changes: 6 additions & 0 deletions .github/workflows/_static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ jobs:

- name: Run dotnet format
run: dotnet format --verify-no-changes

- name: Restore local tools (dotnet-delice)
run: dotnet tool restore

- name: Check dependency licenses against whitelist
run: bash .husky/check-licenses.sh
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -371,5 +371,6 @@ _site
# StrongName files
*.snk
*.snk.b64
# Local CLI publish.
dotnet-tools.json

# dotnet-delice output
/licenses.json
76 changes: 76 additions & 0 deletions .husky/check-licenses.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env bash
#
# License whitelist check for NuGet dependencies.
#
# Runs `dotnet delice` and fails if any package uses a license expression that
# isn't listed in .husky/licenses.allowed, unless the package name appears in
# .husky/licenses.allowed-packages.
#
# Requires: dotnet, jq, bash. No Python.
#
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SLN="$SCRIPT_DIR/../Mindee.sln"
ALLOWED_FILE="$SCRIPT_DIR/licenses.allowed"
ALLOWED_PKGS_FILE="$SCRIPT_DIR/licenses.allowed-packages"

command -v jq >/dev/null 2>&1 || {
echo "[husky] jq is required for the license check but was not found in PATH." >&2
exit 2
}

TMP_JSON="$(mktemp -t delice-XXXXXX.json)"
trap 'rm -f "$TMP_JSON"' EXIT

echo "[husky] Running dotnet delice on ${SLN} ..."
dotnet delice "$SLN" -j --json-output "$TMP_JSON" >/dev/null

strip_comments() {
# Drop blank lines and '#' comments, trim trailing whitespace.
sed -e 's/[[:space:]]*$//' -e '/^[[:space:]]*#/d' -e '/^[[:space:]]*$/d' "$1"
}

ALLOWED_LICENSES="$(strip_comments "$ALLOWED_FILE" || true)"
ALLOWED_PACKAGES="$(strip_comments "$ALLOWED_PKGS_FILE" 2>/dev/null || true)"

# Emit one tab-separated record per package: project<TAB>name<TAB>version<TAB>expression
# We deliberately avoid jq's @tsv, which doubles backslashes (breaking matches
# against expressions like `licenses\LICENSE.txt`).
RECORDS="$(jq -r '
.projects[]
| .projectName as $p
| .licenses[]
| .expression as $e
| .packages[]
| [$p, .name, (.version // "?"), $e] | join("\t")
' "$TMP_JSON")"

violations=""
while IFS=$'\t' read -r project name version expression; do
[ -z "${name:-}" ] && continue
# Allowed license expression?
if printf '%s\n' "$ALLOWED_LICENSES" | grep -Fxq -- "$expression"; then
continue
fi
# Per-package exception?
if [ -n "$ALLOWED_PACKAGES" ] && printf '%s\n' "$ALLOWED_PACKAGES" | grep -Fxq -- "$name"; then
continue
fi
violations+=$'\n'" - ${name}@${version} (license: ${expression}) [project: ${project}]"
done <<< "$RECORDS"

if [ -n "$violations" ]; then
{
echo "Disallowed package licenses detected:"
# De-duplicate while preserving order.
printf '%s\n' "$violations" | awk 'NF && !seen[$0]++'
echo
echo "Either remove the offending dependency, add the license expression to"
echo ".husky/licenses.allowed, or add the package name to"
echo ".husky/licenses.allowed-packages after review."
} >&2
exit 1
fi

echo "License check passed: all packages use whitelisted licenses."
11 changes: 11 additions & 0 deletions .husky/licenses.allowed
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# One SPDX-style license expression per line. Blank lines and '#' comments allowed.
# Any package whose license expression is NOT in this list will fail the pre-push check,
# unless the package name appears in licenses.allowed-packages.
MIT
Apache-2.0
BSD-3-Clause
LGPL-3.0-or-later
Apache-2.0 AND MIT
Microsoft Software License
licenses\LICENSE.txt
Project References
6 changes: 6 additions & 0 deletions .husky/licenses.allowed-packages
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Per-package overrides for cases where delice cannot detect the SPDX license
# (legacy NuGet license structure). Verified manually to be acceptable.
# One "PackageName" per line (no version).
Microsoft.NETFramework.ReferenceAssemblies
Microsoft.NETFramework.ReferenceAssemblies.net472
Microsoft.NETFramework.ReferenceAssemblies.net48
22 changes: 22 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

## husky task runner examples -------------------
## Note : for local installation use 'dotnet' prefix. e.g. 'dotnet husky'

## run all tasks
#husky run

### run all tasks with group: 'group-name'
#husky run --group group-name

## run task with name: 'task-name'
#husky run --name task-name

## pass hook arguments to task
#husky run --args "$1" "$2"

## or put your custom commands -------------------
#echo 'Husky.Net is awesome!'

dotnet husky run --group pre-commit
4 changes: 4 additions & 0 deletions .husky/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

dotnet husky run --group pre-push
27 changes: 27 additions & 0 deletions .husky/run-unit-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash
#
# Run unit tests for the target frameworks that are actually supported on the
# current OS. .NET Framework targets (net472 / net48) require Windows because
# Docnet.Core's native PDF binaries don't load under Mono on *nix.
#
# Mirrors the matrix used in .github/workflows/_test-units.yml.
#
set -euo pipefail

PROJECT="tests/Mindee.UnitTests/Mindee.UnitTests.csproj"

case "$(uname -s 2>/dev/null || echo Windows)" in
MINGW*|MSYS*|CYGWIN*|Windows*)
FRAMEWORKS=("net6.0" "net8.0" "net10.0" "net472" "net48")
;;
*)
FRAMEWORKS=("net8.0" "net10.0")
;;
esac

echo "[husky] Running unit tests for: ${FRAMEWORKS[*]}"

for tfm in "${FRAMEWORKS[@]}"; do
echo "[husky] --- $tfm ---"
dotnet test "$PROJECT" -f "$tfm" --nologo -v:quiet
done
30 changes: 30 additions & 0 deletions .husky/task-runner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "https://alirezanet.github.io/Husky.Net/schema.json",
"tasks": [
{
"name": "dotnet-format-staged",
"group": "pre-commit",
"command": "dotnet",
"args": [ "format", "Mindee.sln", "--include", "${staged}", "--verify-no-changes", "--no-restore" ],
"include": [ "**/*.cs" ]
},
{
"name": "build",
"group": "pre-commit",
"command": "dotnet",
"args": [ "build", "Mindee.sln", "--nologo", "-clp:NoSummary", "-v:quiet" ]
},
{
"name": "license-check",
"group": "pre-push",
"command": "bash",
"args": [ ".husky/check-licenses.sh" ]
},
{
"name": "unit-tests",
"group": "pre-push",
"command": "bash",
"args": [ ".husky/run-unit-tests.sh" ]
}
]
}
17 changes: 17 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
<PackageReleaseNotes>CHANGELOG.md</PackageReleaseNotes>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAuditLevel>low</NuGetAuditLevel>
</PropertyGroup>

<PropertyGroup>
<!-- Obsolete warnings are more of a warning for users than for us. -->
<NoWarn>$(NoWarn);S1133</NoWarn>
<!-- Async file reads (incompatible with 472/48) -->
<NoWarn>$(NoWarn);S6966</NoWarn>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -91,4 +101,11 @@
<PublicSign>false</PublicSign>
<NoWarn>$(NoWarn);CS8002</NoWarn>
</PropertyGroup>

<!-- Analyzers and Bug Spotters (DevDependencies) -->
<ItemGroup>
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.30.0.144632" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<PackageReference Include="Roslynator.Analyzers" Version="4.15.0" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7" PrivateAssets="all" IncludeAssets="runtime; build; native; contentfiles; analyzers; buildtransitive" />
</ItemGroup>
</Project>
6 changes: 3 additions & 3 deletions src/Mindee.Cli/Commands/V1/PredictCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@

namespace Mindee.Cli.Commands.V1
{
internal struct CommandOptions(string name, string description, bool allWords, bool fullText, bool sync, bool async)
internal struct CommandOptions(string name, string description, bool allWords, bool fullText, bool sync, bool isAsync)
{
public readonly string Name = name;
public readonly string Description = description;
public readonly bool AllWords = allWords;
public readonly bool FullText = fullText;
public readonly bool Async = async;
public readonly bool IsAsync = isAsync;
public readonly bool Sync = sync;
}

Expand Down Expand Up @@ -72,7 +72,7 @@ public PredictCommand(CommandOptions options)
Options.Add(_fullTextOption);
}

switch (options.Async)
switch (options.IsAsync)
{
case true when !options.Sync:
{
Expand Down
2 changes: 1 addition & 1 deletion src/Mindee.Cli/Commands/V2/BaseCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ abstract class BaseCommand : Command
{
protected readonly Option<string?> ApiKeyOption;

public BaseCommand(string name, string description) : base(name, description)
protected BaseCommand(string name, string description) : base(name, description)
{
ApiKeyOption = new Option<string?>("--api-key", "-k") { Description = "Mindee V2 API key." };
Options.Add(ApiKeyOption);
Expand Down
3 changes: 1 addition & 2 deletions src/Mindee.Cli/Commands/V2/InferenceCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
using Mindee.V2.Product.Ocr.Params;
using Mindee.V2.Product.Split;
using Mindee.V2.Product.Split.Params;
using SettingsV2 = Mindee.V2.Http.Settings;
using V2Client = Mindee.V2.Client;

namespace Mindee.Cli.Commands.V2
Expand Down Expand Up @@ -240,7 +239,7 @@ private async Task<int> EnqueueAndGetResultAsync(InferenceOptions options, strin
new OcrParameters(options.ModelId, options.Alias)),
"split" => await mindeeClient.EnqueueAndGetResultAsync<SplitResponse>(inputSource,
new SplitParameters(options.ModelId, options.Alias)),
_ => throw new ArgumentOutOfRangeException(nameof(options.Product))
_ => throw new ArgumentOutOfRangeException(productName)
};

PrintToConsole(Console.Out, options, response);
Expand Down
5 changes: 2 additions & 3 deletions src/Mindee.Cli/Commands/V2/SearchModelsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using Microsoft.Extensions.Options;
using Mindee.V2.Parsing.Search;
using Mindee.V2.Search.Models;
using SettingsV2 = Mindee.V2.Http.Settings;
using V2Client = Mindee.V2.Client;

namespace Mindee.Cli.Commands.V2
Expand All @@ -19,7 +18,7 @@ class SearchModelsCommand : BaseCommand
private readonly Option<bool>? _rawOption;

/// <summary>
///
/// Creates a new instance of <see cref="SearchModelsCommand"/>.
/// </summary>
public SearchModelsCommand() : base("search-models", "Search available models.")
{
Expand Down Expand Up @@ -52,7 +51,7 @@ Filter by exact model type (case sensitive).
}

/// <summary>
///
/// Configures an action.
/// </summary>
/// <param name="services">Service provider for dependency resolution</param>
public void ConfigureAction(IServiceProvider services)
Expand Down
6 changes: 2 additions & 4 deletions src/Mindee.Cli/Commands/V2/SearchRagDocumentsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
using Microsoft.Extensions.Options;
using Mindee.V2.Parsing.Search;
using Mindee.V2.Search.Model;
using Mindee.V2.Search.Models;
using SettingsV2 = Mindee.V2.Http.Settings;
using V2Client = Mindee.V2.Client;

namespace Mindee.Cli.Commands.V2
Expand All @@ -20,7 +18,7 @@ class SearchRagDocumentsCommand : BaseCommand
private readonly Option<bool>? _rawOption;

/// <summary>
///
/// Creates a new instance of <see cref="SearchRagDocumentsCommand"/>.
/// </summary>
public SearchRagDocumentsCommand() : base("search-rag-docs", "Search available RAG documents for a given model.")
{
Expand All @@ -44,7 +42,7 @@ class SearchRagDocumentsCommand : BaseCommand
}

/// <summary>
///
/// Configures an action.
/// </summary>
/// <param name="services">Service provider for dependency resolution</param>
public void ConfigureAction(IServiceProvider services)
Expand Down
1 change: 1 addition & 0 deletions src/Mindee/Geometry/Bbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Mindee.Geometry
public class Bbox
{
/// <summary>
/// BBox from 4 coordinates.
/// </summary>
/// <param name="minX">
/// <see cref="MinX" />
Expand Down
5 changes: 3 additions & 2 deletions src/Mindee/Geometry/Point.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace Mindee.Geometry
public class Point : List<double>
{
/// <summary>
/// Point from x and y coordinates.
/// </summary>
/// <param name="x">
/// <see cref="X" />
Expand All @@ -26,12 +27,12 @@ public Point(double x, double y)
/// <summary>
/// X coordinate.
/// </summary>
public double X => this.First();
public double X => this[0];

/// <summary>
/// Y coordinate.
/// </summary>
public double Y => this.Last();
public double Y => this[1];

/// <summary>
/// The default string representation.
Expand Down
Loading