Skip to content

Commit 10a2cef

Browse files
committed
chore: use IANA and Apache MIME sources only
1 parent b411a6d commit 10a2cef

11 files changed

Lines changed: 462 additions & 2228 deletions

File tree

.github/workflows/mime-sync.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ jobs:
2828
- name: Run MIME sync tool
2929
run: >
3030
dotnet run --project ManagedCode.MimeTypes.Sync --configuration Release --
31-
--prefer-remote
3231
--template-concurrency 8
3332
3433
- name: Detect MIME database changes
@@ -72,14 +71,15 @@ jobs:
7271
run: dotnet test --configuration Release --no-restore --verbosity normal
7372

7473
- name: Create Pull Request
74+
if: steps.mime_changes.outputs.changed == 'true'
7575
uses: peter-evans/create-pull-request@v6
7676
with:
7777
token: ${{ secrets.GITHUB_TOKEN }}
7878
commit-message: "chore: sync MIME database"
7979
title: "chore: sync MIME database"
8080
body: |
8181
Automated update of the MIME database from the IANA media types registry,
82-
mime-db, Apache mime.types, and curated ManagedCode overrides.
82+
and Apache mime.types.
8383
8484
When MIME data changes, this PR also bumps the package patch version.
8585
See the workflow summary for the IANA registry date, source counts, and version bump.

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
<RepositoryUrl>https://github.com/managedcode/MimeTypes</RepositoryUrl>
1818
<PackageProjectUrl>https://github.com/managedcode/MimeTypes</PackageProjectUrl>
1919
<Product>Managed Code - MimeTypes</Product>
20-
<Version>10.0.2</Version>
21-
<PackageVersion>10.0.2</PackageVersion>
20+
<Version>10.0.4</Version>
21+
<PackageVersion>10.0.4</PackageVersion>
2222

2323
</PropertyGroup>
2424
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">

ManagedCode.MimeTypes.Sync/Program.cs

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ internal static partial class MimeTypeSyncTool
2222

2323
private static readonly string[] DefaultSupplementalSources =
2424
[
25-
"https://raw.githubusercontent.com/jshttp/mime-db/master/db.json",
2625
"https://raw.githubusercontent.com/apache/httpd/trunk/docs/conf/mime.types"
2726
];
2827

@@ -58,9 +57,9 @@ public static async Task<int> RunAsync(string[] args)
5857
sourceMappings.AddRange(ParseSupplementalSource(source, raw, kind));
5958
}
6059

61-
sourceMappings.AddRange(CustomMappings().Select(static kvp => new SourceMapping(kvp.Key, kvp.Value, MimeSourceKind.Curated)));
62-
63-
var existing = LoadExisting(options.OutputPath);
60+
var existing = options.PreserveExisting
61+
? LoadExisting(options.OutputPath)
62+
: new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
6463
var merged = MergeMappings(sourceMappings, existing, options.PreferRemote);
6564
var mergedMetadata = BuildMergedMetadata(metadata, merged);
6665

@@ -502,24 +501,6 @@ private static IReadOnlyDictionary<string, MimeMetadata> BuildMergedMetadata(Dic
502501
.ToDictionary(static kvp => kvp.Key, static kvp => kvp.Value.NormalizeForOutput(), StringComparer.OrdinalIgnoreCase);
503502
}
504503

505-
private static IEnumerable<KeyValuePair<string, string>> CustomMappings()
506-
{
507-
yield return new KeyValuePair<string, string>("tar.gz", "application/gzip");
508-
yield return new KeyValuePair<string, string>("gz", "application/gzip");
509-
yield return new KeyValuePair<string, string>("tar.bz2", "application/x-bzip2");
510-
yield return new KeyValuePair<string, string>("tar.xz", "application/x-xz");
511-
yield return new KeyValuePair<string, string>("tar.zst", "application/zstd");
512-
yield return new KeyValuePair<string, string>("d.ts", "application/typescript");
513-
yield return new KeyValuePair<string, string>("cjs", "application/node");
514-
yield return new KeyValuePair<string, string>("mjs", "text/javascript");
515-
yield return new KeyValuePair<string, string>("wasm", "application/wasm");
516-
yield return new KeyValuePair<string, string>("heic", "image/heic");
517-
yield return new KeyValuePair<string, string>("heif", "image/heif");
518-
yield return new KeyValuePair<string, string>("ics", "text/calendar");
519-
yield return new KeyValuePair<string, string>("ps1", "application/x-powershell");
520-
yield return new KeyValuePair<string, string>("appx", "application/vnd.ms-appx");
521-
}
522-
523504
private static void WriteMimeMap(string outputPath, IReadOnlyDictionary<string, MergedMapping> data)
524505
{
525506
Directory.CreateDirectory(Path.GetDirectoryName(outputPath)!);
@@ -844,19 +825,13 @@ private static string FormatXref(XElement xref)
844825

845826
private static MimeSourceKind ClassifySupplementalSource(string source)
846827
{
847-
if (source.Contains("jshttp/mime-db", StringComparison.OrdinalIgnoreCase) ||
848-
source.EndsWith("db.json", StringComparison.OrdinalIgnoreCase))
849-
{
850-
return MimeSourceKind.MimeDb;
851-
}
852-
853828
if (source.Contains("apache", StringComparison.OrdinalIgnoreCase) ||
854829
source.EndsWith("mime.types", StringComparison.OrdinalIgnoreCase))
855830
{
856831
return MimeSourceKind.Apache;
857832
}
858833

859-
return MimeSourceKind.MimeDb;
834+
return MimeSourceKind.Custom;
860835
}
861836

862837
[GeneratedRegex(@"^\s*(?<name>[A-Za-z][A-Za-z0-9 /&().+\-]*(?:\(s\))?)\s*:\s*(?<value>.*)$", RegexOptions.Compiled)]
@@ -897,6 +872,7 @@ internal sealed record SyncOptions(
897872
bool PreferRemote,
898873
bool UseIana,
899874
bool SkipIanaTemplates,
875+
bool PreserveExisting,
900876
int TemplateConcurrency)
901877
{
902878
public static SyncOptions Parse(string[] args)
@@ -908,6 +884,7 @@ public static SyncOptions Parse(string[] args)
908884
bool preferRemote = false;
909885
bool useIana = true;
910886
bool skipIanaTemplates = false;
887+
bool preserveExisting = false;
911888
var templateConcurrency = 8;
912889
var customSupplementalSources = false;
913890

@@ -952,13 +929,16 @@ public static SyncOptions Parse(string[] args)
952929
case "--prefer-remote":
953930
preferRemote = true;
954931
break;
932+
case "--preserve-existing":
933+
preserveExisting = true;
934+
break;
955935
}
956936
}
957937

958938
output ??= Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "ManagedCode.MimeTypes", "mimeTypes.json"));
959939
metadataOutput ??= Path.Combine(Path.GetDirectoryName(output)!, "mimeTypes.metadata.json");
960940

961-
return new SyncOptions(ianaSource, supplementalSources, output, metadataOutput, preferRemote, useIana, skipIanaTemplates, templateConcurrency);
941+
return new SyncOptions(ianaSource, supplementalSources, output, metadataOutput, preferRemote, useIana, skipIanaTemplates, preserveExisting, templateConcurrency);
962942
}
963943

964944
private static void AddSources(List<string> sources, string value)
@@ -975,10 +955,9 @@ internal enum MimeSourceKind
975955
{
976956
Existing,
977957
Apache,
978-
MimeDb,
958+
Custom,
979959
Iana,
980-
ExistingPreferred,
981-
Curated
960+
ExistingPreferred
982961
}
983962

984963
internal static class MimeSourceKindExtensions
@@ -990,9 +969,8 @@ public static int Priority(this MimeSourceKind kind)
990969
MimeSourceKind.Existing => 0,
991970
MimeSourceKind.Apache => 10,
992971
MimeSourceKind.Iana => 15,
993-
MimeSourceKind.MimeDb => 20,
972+
MimeSourceKind.Custom => 20,
994973
MimeSourceKind.ExistingPreferred => 35,
995-
MimeSourceKind.Curated => 40,
996974
_ => 0
997975
};
998976
}
@@ -1002,9 +980,8 @@ public static string SourceName(this MimeSourceKind kind)
1002980
return kind switch
1003981
{
1004982
MimeSourceKind.Apache => "apache",
1005-
MimeSourceKind.MimeDb => "mime-db",
983+
MimeSourceKind.Custom => "custom",
1006984
MimeSourceKind.Iana => "iana",
1007-
MimeSourceKind.Curated => "curated",
1008985
MimeSourceKind.ExistingPreferred => "existing",
1009986
_ => "existing"
1010987
};

ManagedCode.MimeTypes.Tests/GeneratorTests.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public void ExtensionsTest()
1515
MimeHelper.GetMimeType("C:\\\\users\\file.txt").ShouldBe(MimeHelper.TXT);
1616
MimeHelper.GetMimeType("https://cdn.example.com/assets/image.png?version=1").ShouldBe(MimeHelper.PNG);
1717
MimeHelper.GetMimeType("ARCHIVE.TAR.GZ").ShouldBe(MimeHelper.GZ);
18-
MimeHelper.GetMimeType("module.d.ts").ShouldBe(MimeHelper.D_TS);
1918
}
2019

2120
[Fact]
@@ -30,13 +29,11 @@ public void EmptyExtensionsTest()
3029
public void GeneratedPropertiesTest()
3130
{
3231
// Test static properties generated from mimeTypes.json
33-
const string eventStreamMime = "text/event-stream";
3432
MimeHelper.PDF.ShouldBe(MimeHelper.GetMimeType(".pdf"));
3533
MimeHelper.DOCX.ShouldBe(MimeHelper.GetMimeType(".docx"));
3634
MimeHelper.PNG.ShouldBe(MimeHelper.GetMimeType(".png"));
3735
MimeHelper.MP4.ShouldBe(MimeHelper.GetMimeType(".mp4"));
3836
MimeHelper._7Z.ShouldBe(MimeHelper.GetMimeType(".7z"));
39-
MimeHelper.EVENT_STREAM.ShouldBe(eventStreamMime);
4037
}
4138

4239
[Fact]

ManagedCode.MimeTypes.Tests/MimeMetadataTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void GetKnownMimeTypes_ShouldIncludeIanaAndSupplementalMetadata()
3434
var known = MimeHelper.GetKnownMimeTypes();
3535

3636
known.ShouldContain(static info => info.Mime == "application/pdf" && info.IsIanaRegistered);
37-
known.ShouldContain(static info => info.Mime == "application/x-powershell" && !info.IsIanaRegistered && info.Source == "curated");
37+
known.ShouldContain(static info => info.Mime == "application/x-7z-compressed" && !info.IsIanaRegistered && info.Source == "apache");
3838
}
3939

4040
[Fact]

ManagedCode.MimeTypes.Tests/StreamProbeTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
namespace ManagedCode.MimeTypes.Tests;
88

99
/// <summary>
10-
/// Exercises stream-based MIME detection against the curated sample set.
10+
/// Exercises stream-based MIME detection against the local sample set.
1111
/// </summary>
1212
public class StreamProbeTests
1313
{

ManagedCode.MimeTypes.Tests/SyncToolTests.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,17 @@ public void MergeMappings_ShouldApplySourcePrecedence()
7070
{
7171
new SourceMapping("conflict", "application/apache", MimeSourceKind.Apache),
7272
new SourceMapping("conflict", "application/iana", MimeSourceKind.Iana),
73-
new SourceMapping("conflict", "application/mime-db", MimeSourceKind.MimeDb),
74-
new SourceMapping("iana-only", "application/iana", MimeSourceKind.Iana),
75-
new SourceMapping("mjs", "application/x-old", MimeSourceKind.Iana),
76-
new SourceMapping("mjs", "text/javascript", MimeSourceKind.Curated)
73+
new SourceMapping("conflict", "application/custom", MimeSourceKind.Custom),
74+
new SourceMapping("iana-only", "application/iana", MimeSourceKind.Iana)
7775
};
7876

7977
var preferRemote = MimeTypeSyncTool.MergeMappings(mappings, existing, preferRemote: true);
80-
preferRemote["conflict"].Mime.ShouldBe("application/mime-db");
78+
preferRemote["conflict"].Mime.ShouldBe("application/custom");
8179
preferRemote["iana-only"].Mime.ShouldBe("application/iana");
8280
preferRemote["local"].Mime.ShouldBe("application/existing-local");
83-
preferRemote["mjs"].Mime.ShouldBe("text/javascript");
8481

8582
var preferExisting = MimeTypeSyncTool.MergeMappings(mappings, existing, preferRemote: false);
8683
preferExisting["conflict"].Mime.ShouldBe("application/existing");
87-
preferExisting["mjs"].Mime.ShouldBe("text/javascript");
8884
}
8985

9086
private const string IanaXml = """

ManagedCode.MimeTypes/ManagedCode.MimeTypes.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
<PropertyGroup>
2222
<Title>ManagedCode.MimeTypes</Title>
2323
<PackageId>ManagedCode.MimeTypes</PackageId>
24-
<Description>MimeTypes for .NET</Description>
25-
<PackageTags>managedcode, mimetypes, mime</PackageTags>
24+
<Description>Official IANA and Apache MIME/media type lookup, metadata, categorisation, and content detection for .NET</Description>
25+
<PackageTags>managedcode, mimetypes, mime, media-types, iana, apache, content-detection, file-signatures, magic-numbers, mime-sniffing</PackageTags>
2626
</PropertyGroup>
2727

2828
<ItemGroup>

0 commit comments

Comments
 (0)