mime-types 3.7.0.pre1 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fbc8ea5f8e0271da1f1b5ad79011d66be1ab6eaf2e51ccefb7a6b1744ab7a60c
4
- data.tar.gz: c8bef17d139d55505852440b1f8103d0ed218093e7e6f0b999c58cfaa6a7f302
3
+ metadata.gz: ab73da0cc6bf48c9f8406807103d5e80aeba86c2b019b056143356899a5db481
4
+ data.tar.gz: 78cd6d48759acffabc96ce33160fe19715bb4730cc5bf6bd693dfb07e99c26a4
5
5
  SHA512:
6
- metadata.gz: 8a30479ab4fd1589bcdf9dd21b145786038799fb4f3e0b8bc0ba4ad14fd23c38e88265323752faca4750de2d5e23f30ecbbb4e9bc33fca2dd93ddf45032a5f40
7
- data.tar.gz: 3b5dd2e2a4628096ab7b44a3a5cb43d1c2c0c5404fa8e16909f8e20481ad0521bbe957fc5e0410b807c6e834d5e086dd5bbe40ffbb13a289c41efc9e3f5585be
6
+ metadata.gz: acbf4c390f33a56481c0b9100a83eaea8816a530d2dbd2e4617ceeaebe97bdb3734ea5d6af898a6d6ae32829116c514208121c8c0bd7ccbe38826bd6223b1200
7
+ data.tar.gz: 7fd36208270f89ebf99dd70905dae556c4652c461009b72fb3975c7bb9e49c78acfc564bd034309fe967685cab95118cd8ef56fc970d750b8df8ed3a79975bbe
data/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 3.7.0.pre1 / YYYY-MM-DD
3
+ ## 3.7.0 / 2025-05-07
4
4
 
5
5
  - Deprecated `MIME::Type#priority_compare`. In a future release, this will be
6
6
  will be renamed to `MIME::Type#<=>`. This method is used in tight loops, so
@@ -19,6 +19,14 @@
19
19
  none, as explicit support for several special values (which should have caused
20
20
  errors in any case) have been removed.
21
21
 
22
+ - When sorting the result of `MIME::Types#type_for`, provided a priority boost
23
+ if one of the target extensions is the type's preferred extension. This means
24
+ that for the case in [#148][issue-148], when getting the type for `foo.webm`,
25
+ the type `video/webm` will be returned before the type `audio/webm`, because
26
+ `.webm` is the preferred extension for `video/webm` but not `audio/webm`
27
+ (which has a preferred extension of `.weba`). Added tests to ensure MIME types
28
+ are retrieved in a stable order (which is alphabetical).
29
+
22
30
  ## 3.6.2 / 2025-03-25
23
31
 
24
32
  - Updated the reference to the changelog in the README, fixing RubyGems metadata
@@ -369,6 +377,7 @@ there are some validation changes and updated code with formatting.
369
377
  [issue-127]: https://github.com/mime-types/ruby-mime-types/issues/127
370
378
  [issue-134]: https://github.com/mime-types/ruby-mime-types/issues/134
371
379
  [issue-136]: https://github.com/mime-types/ruby-mime-types/issues/136
380
+ [issue-148]: https://github.com/mime-types/ruby-mime-types/issues/148
372
381
  [issue-166]: https://github.com/mime-types/ruby-mime-types/issues/166
373
382
  [issue-177]: https://github.com/mime-types/ruby-mime-types/issues/177
374
383
  [mime-types-data]: https://github.com/mime-types/mime-types-data
data/README.md CHANGED
@@ -6,10 +6,8 @@
6
6
  - rdoc :: http://rdoc.info/gems/mime-types/
7
7
  - changelog ::
8
8
  https://github.com/mime-types/ruby-mime-types/blob/main/CHANGELOG.md
9
- - continuous integration ::
10
- {<img src="https://github.com/mime-types/ruby-mime-types/actions/workflows/ci.yml/badge.svg" alt="Build Status" />}[https://github.com/mime-types/ruby-mime-types/actions/workflows/ci.yml]
11
- - test coverage ::
12
- {<img src="https://coveralls.io/repos/mime-types/ruby-mime-types/badge.svg?branch=master&service=github" alt="Coverage Status" />}[https://coveralls.io/github/mime-types/ruby-mime-types?branch=master]
9
+ - continuous integration :: [![Build Status][ci-badge]][ci-workflow]
10
+ - test coverage :: [![Coverage][coveralls-badge]][coveralls]
13
11
 
14
12
  ## Description
15
13
 
@@ -21,10 +19,9 @@ MIME type definitions.
21
19
  Version 3.0 is a major release that requires Ruby 2.0 compatibility and removes
22
20
  deprecated functions. The columnar registry format introduced in 2.6 has been
23
21
  made the primary format; the registry data has been extracted from this library
24
- and put into {mime-types-data}[https://github.com/mime-types/mime-types-data].
25
- Additionally, mime-types is now licensed exclusively under the MIT licence and
26
- there is a code of conduct in effect. There are a number of other smaller
27
- changes described in the History file.
22
+ and put into [mime-types-data][data]. Additionally, mime-types is now licensed
23
+ exclusively under the MIT licence and there is a code of conduct in effect.
24
+ There are a number of other smaller changes described in the History file.
28
25
 
29
26
  ### About MIME Media Types
30
27
 
@@ -35,9 +32,8 @@ entities (provided as an enumerable collection of MIME::Type objects) to be
35
32
  determined and used. There are many types defined by RFCs and vendors, so the
36
33
  list is long but by definition incomplete; don't hesitate to add additional type
37
34
  definitions. MIME type definitions found in mime-types are from RFCs, W3C
38
- recommendations, the {IANA Media Types
39
- registry}[https://www.iana.org/assignments/media-types/media-types.xhtml], and
40
- user contributions. It conforms to RFCs 2045 and 2231.
35
+ recommendations, the [IANA Media Types registry][registry], and user
36
+ contributions. It conforms to RFCs 2045 and 2231.
41
37
 
42
38
  ### mime-types 3.x
43
39
 
@@ -197,3 +193,8 @@ removed until mime-types 4.x or possibly later.
197
193
  [pull-96-comment]: https://github.com/mime-types/ruby-mime-types/pull/96#issuecomment-100725400
198
194
  [semver]: https://semver.org
199
195
  [data]: https://github.com/mime-types/mime-types-data
196
+ [ci-badge]: https://github.com/mime-types/ruby-mime-types/actions/workflows/ci.yml/badge.svg
197
+ [ci-workflow]: https://github.com/mime-types/ruby-mime-types/actions/workflows/ci.yml
198
+ [coveralls-badge]: https://coveralls.io/repos/mime-types/ruby-mime-types/badge.svg?branch=main&service=github
199
+ [coveralls]: https://coveralls.io/github/mime-types/ruby-mime-types?branch=main
200
+ [registry]: https://www.iana.org/assignments/media-types/media-types.xhtml
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ spec = Hoe.spec "mime-types" do
26
26
  val.merge!({"rubygems_mfa_required" => "true"})
27
27
  }
28
28
 
29
- extra_deps << ["mime-types-data", "~> 3.2025", ">= 3.2025.0506.pre1"]
29
+ extra_deps << ["mime-types-data", "~> 3.2025", ">= 3.2025.0507"]
30
30
  extra_deps << ["logger", ">= 0"]
31
31
 
32
32
  extra_dev_deps << ["hoe", "~> 4.0"]
@@ -41,7 +41,6 @@ class MIME::Type::Columnar < MIME::Type
41
41
  :signature?, :provisional, :provisional=, :provisional?, file: "flags"
42
42
  column :xrefs, :xrefs=, :xref_urls
43
43
  column :use_instead, :use_instead=
44
- column :extension_priorities, :extension_priorities=
45
44
 
46
45
  def encode_with(coder) # :nodoc:
47
46
  @container.send(:load_friendly)
@@ -51,7 +50,6 @@ class MIME::Type::Columnar < MIME::Type
51
50
  @container.send(:load_use_instead)
52
51
  @container.send(:load_xrefs)
53
52
  @container.send(:load_preferred_extension)
54
- @container.send(:load_extension_priorities)
55
53
  super
56
54
  end
57
55
 
data/lib/mime/type.rb CHANGED
@@ -134,7 +134,6 @@ class MIME::Type
134
134
  @friendly = {}
135
135
  @obsolete = @registered = @provisional = false
136
136
  @preferred_extension = @docs = @use_instead = @__sort_priority = nil
137
- __extension_priorities
138
137
 
139
138
  self.extensions = []
140
139
 
@@ -196,12 +195,11 @@ class MIME::Type
196
195
  simplified <=> other
197
196
  end
198
197
 
199
- # Compares the +other+ MIME::Type using the simplified representation, then
200
- # a pre-computed sort priority value. Used by MIME::Types#[] to sort types.
198
+ # Compares the +other+ MIME::Type using a pre-computed sort priority value,
199
+ # then the simplified representation for an alphabetical sort.
201
200
  #
202
- # While this method is public, its direct use is strongly discouraged by
203
- # consumers of mime-types. For the next major version of MIME::Types, this
204
- # method will become #<=> and #priority_compare will be removed.
201
+ # For the next major version of MIME::Types, this method will become #<=> and
202
+ # #priority_compare will be removed.
205
203
  def priority_compare(other)
206
204
  if (cmp = __sort_priority <=> other.__sort_priority) == 0
207
205
  simplified <=> other.simplified
@@ -210,6 +208,33 @@ class MIME::Type
210
208
  end
211
209
  end
212
210
 
211
+ # Uses a modified pre-computed sort priority value based on whether one of the provided
212
+ # extensions is the preferred extension for a type.
213
+ #
214
+ # This is an internal function. If an extension provided is a preferred extension either
215
+ # for this instance or the compared instance, the corresponding extension has its top
216
+ # _extension_ bit cleared from its sort priority. That means that a type with between
217
+ # 0 and 8 extensions will be treated as if it had 9 extensions.
218
+ def __extension_priority_compare(other, exts) # :nodoc:
219
+ tsp = __sort_priority
220
+
221
+ if exts.include?(preferred_extension) && tsp & 0b1000 != 0
222
+ tsp = tsp & 0b11110111 | 0b0111
223
+ end
224
+
225
+ osp = other.__sort_priority
226
+
227
+ if exts.include?(other.preferred_extension) && osp & 0b1000 != 0
228
+ osp = osp & 0b11110111 | 0b0111
229
+ end
230
+
231
+ if (cmp = tsp <=> osp) == 0
232
+ simplified <=> other.simplified
233
+ else
234
+ cmp
235
+ end
236
+ end
237
+
213
238
  # Returns +true+ if the +other+ object is a MIME::Type and the content types
214
239
  # match.
215
240
  def eql?(other)
@@ -330,38 +355,10 @@ class MIME::Type
330
355
 
331
356
  ##
332
357
  def preferred_extension=(value) # :nodoc:
333
- if value
334
- add_extensions(value)
335
- set_preferred_extension_priority(value)
336
- elsif instance_variable_defined?(:@preferred_extension)
337
- clear_extension_priority(@preferred_extension)
338
- end
358
+ add_extensions(value) if value
339
359
  @preferred_extension = value
340
360
  end
341
361
 
342
- ##
343
- # Optional extension priorities for this MIME type. This is a map of
344
- # extensions to relative priority values (+-20..20+) similar to +nice(1)+.
345
- # Unless otherwise specified in the data, an explicitly set
346
- # +preferred_extension+ is automatically given a relative priority of +-10+.
347
- #
348
- # :attr_reader: extension_priorities
349
- attr_accessor :extension_priorities
350
-
351
- ##
352
- # Returns the priority for the provided extension or extensions. If a priority
353
- # is not set, the default priority is +0+. The range for priorities is
354
- # +-20..20+, inclusive.
355
- #
356
- # Obsolete MIME types have a <code>+3</code> penalty applied to their
357
- # extension priority and unregistered MIME types have a <code>+2</code>
358
- # penalty to their extension priority, meaning that the highest priority an
359
- # obsolete, unregistered MIME type can have is +-15+. The lowest priority is
360
- # always <code>+20</code>.
361
- def extension_priority(*exts)
362
- exts.map { |ext| get_extension_priority(ext) }.min
363
- end
364
-
365
362
  ##
366
363
  # The encoding (+7bit+, +8bit+, <tt>quoted-printable</tt>, or +base64+)
367
364
  # required to transport the data of this content type safely across a
@@ -583,7 +580,6 @@ class MIME::Type
583
580
  coder["provisional"] = provisional? if provisional?
584
581
  coder["signature"] = signature? if signature?
585
582
  coder["sort-priority"] = __sort_priority || 0b11111111
586
- coder["extension-priorities"] = __extension_priorities unless __extension_priorities.empty?
587
583
  coder
588
584
  end
589
585
 
@@ -604,7 +600,6 @@ class MIME::Type
604
600
  self.signature = coder["signature"]
605
601
  self.xrefs = coder["xrefs"] || {}
606
602
  self.use_instead = coder["use-instead"]
607
- self.extension_priorities = coder["extension-priorities"]
608
603
 
609
604
  friendly(coder["friendly"] || {})
610
605
 
@@ -662,24 +657,8 @@ class MIME::Type
662
657
  end
663
658
  end
664
659
 
665
- def __extension_priorities # :nodoc:
666
- @extension_priorities ||= {}
667
- end
668
-
669
660
  private
670
661
 
671
- def clear_extension_priority(ext)
672
- __extension_priorities.delete(ext) if ext
673
- end
674
-
675
- def get_extension_priority(ext)
676
- [[-20, (__extension_priorities[ext] || 0) + __priority_penalty].max, 20].min
677
- end
678
-
679
- def set_preferred_extension_priority(ext)
680
- __extension_priorities[ext] = -10 unless __extension_priorities.has_key?(ext)
681
- end
682
-
683
662
  def clear_sort_priority
684
663
  @__sort_priority = nil
685
664
  end
@@ -709,13 +688,6 @@ class MIME::Type
709
688
  extension_count = [0, 16 - extension_count].max
710
689
 
711
690
  @__sort_priority = obsolete | registered | provisional | complete | extension_count
712
- @__priority_penalty = ((instance_variable_defined?(:@obsolete) && @obsolete) ? 3 : 0) +
713
- ((instance_variable_defined?(:@registered) && @registered) ? 0 : 2)
714
- end
715
-
716
- def __priority_penalty
717
- update_sort_priority if @__priority_penalty.nil?
718
- @__priority_penalty
719
691
  end
720
692
 
721
693
  def content_type=(type_string)
@@ -89,7 +89,7 @@ module MIME::Types::Columnar
89
89
  def load_encoding
90
90
  each_file_line("encoding") do |type, line|
91
91
  pool ||= {}
92
- type.instance_variable_set(:@encoding, (pool[line] ||= line))
92
+ type.instance_variable_set(:@encoding, pool[line] ||= line)
93
93
  end
94
94
  end
95
95
 
@@ -133,14 +133,6 @@ module MIME::Types::Columnar
133
133
  end
134
134
  end
135
135
 
136
- def load_extension_priorities
137
- each_file_line("extpri") do |type, line|
138
- type.instance_variable_set(:@extension_priorities, dict(line, transform: :extension_priority))
139
- end
140
- rescue
141
- # This path preserves backwards compatibility.
142
- end
143
-
144
136
  def dict(line, transform: nil)
145
137
  if line == "-"
146
138
  {}
@@ -79,7 +79,7 @@ class MIME::Types::Loader
79
79
  #
80
80
  # This will load from columnar files (#load_columnar) if <tt>columnar:
81
81
  # true</tt> is provided in +options+ and there are columnar files in +path+.
82
- def load(options = {columnar: false})
82
+ def load(options = {columnar: true})
83
83
  if options[:columnar] && !Dir[columnar_path].empty?
84
84
  load_columnar
85
85
  else
@@ -4,7 +4,7 @@
4
4
  module MIME
5
5
  class Types
6
6
  # The released version of the mime-types library.
7
- VERSION = "3.7.0.pre1"
7
+ VERSION = "3.7.0"
8
8
  end
9
9
 
10
10
  class Type
data/lib/mime/types.rb CHANGED
@@ -130,9 +130,7 @@ class MIME::Types
130
130
  @type_variants[MIME::Type.simplified(type_id)]
131
131
  end
132
132
 
133
- prune_matches(matches, complete, registered).sort { |a, b|
134
- a.priority_compare(b)
135
- }
133
+ prune_matches(matches, complete, registered).sort
136
134
  end
137
135
 
138
136
  # Return the list of MIME::Types which belongs to the file based on its
@@ -148,16 +146,14 @@ class MIME::Types
148
146
  # puts MIME::Types.type_for(%w(citydesk.xml citydesk.gif))
149
147
  # => [application/xml, image/gif, text/xml]
150
148
  def type_for(filename)
151
- Array(filename).flat_map { |fn|
152
- @extension_index[fn.chomp.downcase[/\.?([^.]*?)\z/m, 1]]
153
- }.compact.inject(Set.new, :+).sort { |a, b|
154
- by_ext = a.extension_priority(*a.extensions) <=> b.extension_priority(*b.extensions)
155
-
156
- if by_ext.zero?
157
- a.priority_compare(b)
158
- else
159
- by_ext
160
- end
149
+ wanted = Array(filename).map { |fn| fn.chomp.downcase[/\.?([^.]*?)\z/m, 1] }
150
+
151
+ wanted
152
+ .flat_map { |ext| @extension_index[ext] }
153
+ .compact
154
+ .reduce(Set.new, :+)
155
+ .sort { |a, b|
156
+ a.__extension_priority_compare(b, wanted)
161
157
  }
162
158
  end
163
159
  alias_method :of, :type_for
@@ -230,6 +226,12 @@ class MIME::Types
230
226
  k =~ pattern
231
227
  }.values.inject(Set.new, :+)
232
228
  end
229
+
230
+ # def stable_sort(list)
231
+ # list.lazy.each_with_index.sort { |(a, ai), (b, bi)|
232
+ # a.priority_compare(b).nonzero? || ai <=> bi
233
+ # }.map(&:first)
234
+ # end
233
235
  end
234
236
 
235
237
  require "mime/types/cache"
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- $debug = false
4
-
5
3
  gem "minitest"
6
4
  require "minitest/focus"
7
5
  require "minitest/hooks"
@@ -12,7 +12,8 @@ describe MIME::Types do
12
12
  MIME::Type.new("content-type" => "application/x-wordperfect6.1"),
13
13
  MIME::Type.new("content-type" => "application/x-www-form-urlencoded", "registered" => true),
14
14
  MIME::Type.new("content-type" => "application/x-gzip", "extensions" => %w[gz]),
15
- MIME::Type.new("content-type" => "application/gzip", "extensions" => "gz", "registered" => true)
15
+ MIME::Type.new("content-type" => "application/gzip", "extensions" => "gz", "registered" => true),
16
+ *MIME::Types.type_for("foo.webm")
16
17
  )
17
18
  }
18
19
  end
@@ -33,8 +34,8 @@ describe MIME::Types do
33
34
  end
34
35
 
35
36
  it "is countable with an enumerator" do
36
- assert_equal 6, mime_types.each.count
37
- assert_equal 6, mime_types.lazy.count
37
+ assert_equal 8, mime_types.each.count
38
+ assert_equal 8, mime_types.lazy.count
38
39
  end
39
40
  end
40
41
 
@@ -139,7 +140,7 @@ describe MIME::Types do
139
140
  end
140
141
 
141
142
  it "finds multiple extensions" do
142
- assert_equal %w[image/jpeg text/plain],
143
+ assert_equal %w[text/plain image/jpeg],
143
144
  mime_types.type_for(%w[foo.txt foo.jpeg])
144
145
  end
145
146
 
@@ -158,11 +159,15 @@ describe MIME::Types do
158
159
  it "handles newline characters correctly" do
159
160
  assert_includes mime_types.type_for("test.pdf\n.txt"), "text/plain"
160
161
  end
162
+
163
+ it "returns a stable order for types with equal priority" do
164
+ assert_equal %w[text/x-vcalendar text/x-vcard], MIME::Types[/text\/x-vca/]
165
+ end
161
166
  end
162
167
 
163
168
  describe "#count" do
164
169
  it "can count the number of types inside" do
165
- assert_equal 6, mime_types.count
170
+ assert_equal 8, mime_types.count
166
171
  end
167
172
  end
168
173
  end
@@ -87,7 +87,10 @@ describe MIME::Types, "registry" do
87
87
  end
88
88
 
89
89
  it "finds multiple extensions ordered by the filename list" do
90
- assert_equal %w[text/plain image/jpeg], MIME::Types.type_for(%w[foo.txt foo.jpeg])
90
+ result = MIME::Types.type_for(%w[foo.txt foo.jpeg])
91
+
92
+ # assert_equal %w[text/plain image/jpeg], MIME::Types.type_for(%w[foo.txt foo.jpeg])
93
+ assert_equal %w[text/plain image/jpeg], result
91
94
  end
92
95
 
93
96
  it "does not find unknown extensions" do
@@ -104,6 +107,10 @@ describe MIME::Types, "registry" do
104
107
  assert_includes MIME::Types.type_for("test.pdf\n.txt"), "text/plain"
105
108
  assert_includes MIME::Types.type_for("test.txt\n.pdf"), "application/pdf"
106
109
  end
110
+
111
+ it "returns a stable order for types with equal priority" do
112
+ assert_equal %w[text/x-vcalendar text/x-vcard], MIME::Types[/text\/x-vca/]
113
+ end
107
114
  end
108
115
 
109
116
  describe ".count" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mime-types
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.0.pre1
4
+ version: 3.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Austin Ziegler
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-04-04 00:00:00.000000000 Z
10
+ date: 2025-05-07 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: mime-types-data
@@ -18,7 +18,7 @@ dependencies:
18
18
  version: '3.2025'
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: 3.2025.0506.pre1
21
+ version: 3.2025.0507
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -28,7 +28,7 @@ dependencies:
28
28
  version: '3.2025'
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: 3.2025.0506.pre1
31
+ version: 3.2025.0507
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: logger
34
34
  requirement: !ruby/object:Gem::Requirement
@@ -198,10 +198,9 @@ description: |-
198
198
  Version 3.0 is a major release that requires Ruby 2.0 compatibility and removes
199
199
  deprecated functions. The columnar registry format introduced in 2.6 has been
200
200
  made the primary format; the registry data has been extracted from this library
201
- and put into {mime-types-data}[https://github.com/mime-types/mime-types-data].
202
- Additionally, mime-types is now licensed exclusively under the MIT licence and
203
- there is a code of conduct in effect. There are a number of other smaller
204
- changes described in the History file.
201
+ and put into [mime-types-data][data]. Additionally, mime-types is now licensed
202
+ exclusively under the MIT licence and there is a code of conduct in effect.
203
+ There are a number of other smaller changes described in the History file.
205
204
  email:
206
205
  - halostatue@gmail.com
207
206
  executables: []