@@ -87,23 +87,15 @@ defmodule Version do
87
87
import Kernel , except: [ match?: 2 ]
88
88
defstruct [ :major , :minor , :patch , :pre , :build ]
89
89
90
- @ type version :: String . t | t
91
- @ type requirement :: String . t | Version.Requirement . t
92
- @ type major :: String . t | non_neg_integer
93
- @ type minor :: non_neg_integer | nil
94
- @ type patch :: non_neg_integer | nil
95
- @ type pre :: [ String . t | non_neg_integer ]
96
- @ type build :: String . t | nil
97
- @ type matchable :: { major :: major ,
98
- minor :: minor ,
99
- patch :: patch ,
100
- pre :: pre }
101
- @ type t :: % __MODULE__ {
102
- major: major ,
103
- minor: minor ,
104
- patch: patch ,
105
- pre: pre ,
106
- build: build }
90
+ @ type version :: String . t ( ) | t
91
+ @ type requirement :: String . t ( ) | Version.Requirement . t ( )
92
+ @ type major :: String . t ( ) | non_neg_integer
93
+ @ type minor :: non_neg_integer | nil
94
+ @ type patch :: non_neg_integer | nil
95
+ @ type pre :: [ String . t ( ) | non_neg_integer ]
96
+ @ type build :: String . t ( ) | nil
97
+ @ type matchable :: { major :: major , minor :: minor , patch :: patch , pre :: pre }
98
+ @ type t :: % __MODULE__ { major: major , minor: minor , patch: patch , pre: pre , build: build }
107
99
108
100
defmodule Requirement do
109
101
@ moduledoc false
@@ -119,7 +111,7 @@ defmodule Version do
119
111
end
120
112
121
113
def message ( % { requirement: requirement } ) do
122
- "invalid requirement: #{ inspect requirement } "
114
+ "invalid requirement: #{ inspect ( requirement ) } "
123
115
end
124
116
end
125
117
@@ -131,7 +123,7 @@ defmodule Version do
131
123
end
132
124
133
125
def message ( % { version: version } ) do
134
- "invalid version: #{ inspect version } "
126
+ "invalid version: #{ inspect ( version ) } "
135
127
end
136
128
end
137
129
@@ -172,6 +164,7 @@ defmodule Version do
172
164
case parse_requirement ( requirement ) do
173
165
{ :ok , requirement } ->
174
166
match? ( version , requirement , opts )
167
+
175
168
:error ->
176
169
raise InvalidRequirementError , requirement
177
170
end
@@ -254,16 +247,16 @@ defmodule Version do
254
247
:error
255
248
256
249
"""
257
- @ spec parse ( String . t ) :: { :ok , t } | :error
250
+ @ spec parse ( String . t ( ) ) :: { :ok , t } | :error
258
251
def parse ( string ) when is_binary ( string ) do
259
252
case Version.Parser . parse_version ( string ) do
260
253
{ :ok , { major , minor , patch , pre , build_parts } } ->
261
254
build = if build_parts == [ ] , do: nil , else: Enum . join ( build_parts , "" )
262
- version = % Version { major: major , minor: minor , patch: patch ,
263
- pre: pre , build: build }
255
+ version = % Version { major: major , minor: minor , patch: patch , pre: pre , build: build }
264
256
{ :ok , version }
265
- :error ->
266
- :error
257
+
258
+ :error ->
259
+ :error
267
260
end
268
261
end
269
262
@@ -281,7 +274,7 @@ defmodule Version do
281
274
** (Version.InvalidVersionError) invalid version: "2.0-alpha1"
282
275
283
276
"""
284
- @ spec parse! ( String . t ) :: t | no_return
277
+ @ spec parse! ( String . t ( ) ) :: t | no_return
285
278
def parse! ( string ) when is_binary ( string ) do
286
279
case parse ( string ) do
287
280
{ :ok , version } -> version
@@ -302,11 +295,12 @@ defmodule Version do
302
295
:error
303
296
304
297
"""
305
- @ spec parse_requirement ( String . t ) :: { :ok , Requirement . t } | :error
298
+ @ spec parse_requirement ( String . t ( ) ) :: { :ok , Requirement . t ( ) } | :error
306
299
def parse_requirement ( string ) when is_binary ( string ) do
307
300
case Version.Parser . parse_requirement ( string ) do
308
301
{ :ok , spec } ->
309
302
{ :ok , % Requirement { source: string , matchspec: spec , compiled: false } }
303
+
310
304
:error ->
311
305
:error
312
306
end
@@ -321,7 +315,7 @@ defmodule Version do
321
315
can not be sent to a process on another node and still remain a valid
322
316
compiled match_spec, nor can it be stored on disk).
323
317
"""
324
- @ spec compile_requirement ( Requirement . t ) :: Requirement . t
318
+ @ spec compile_requirement ( Requirement . t ( ) ) :: Requirement . t ( )
325
319
def compile_requirement ( % Requirement { matchspec: spec } = req ) do
326
320
% { req | matchspec: :ets . match_spec_compile ( spec ) , compiled: true }
327
321
end
@@ -334,6 +328,7 @@ defmodule Version do
334
328
case Version.Parser . parse_version ( string ) do
335
329
{ :ok , { major , minor , patch , pre , _build_parts } } ->
336
330
{ major , minor , patch , pre , allow_pre? }
331
+
337
332
:error ->
338
333
raise InvalidVersionError , string
339
334
end
@@ -352,8 +347,9 @@ defmodule Version do
352
347
{ "!=" , :!= } ,
353
348
{ "!" , :!= } ,
354
349
{ " or " , :|| } ,
355
- { " and " , :&& } ,
350
+ { " and " , :&& }
356
351
]
352
+
357
353
for { string_op , atom_op } <- operators do
358
354
def lexer ( unquote ( string_op ) <> rest , acc ) do
359
355
lexer ( rest , [ unquote ( atom_op ) | acc ] )
@@ -373,8 +369,10 @@ defmodule Version do
373
369
case head do
374
370
head when is_binary ( head ) ->
375
371
[ << head :: binary , char :: utf8 >> | acc ]
372
+
376
373
head when head in [ :|| , :&& ] ->
377
374
[ << char :: utf8 >> , :== , head | acc ]
375
+
378
376
_other ->
379
377
[ << char :: utf8 >> , head | acc ]
380
378
end
@@ -386,13 +384,13 @@ defmodule Version do
386
384
Enum . reverse ( acc )
387
385
end
388
386
389
- @ spec parse_requirement ( String . t ) :: { :ok , term } | :error
387
+ @ spec parse_requirement ( String . t ( ) ) :: { :ok , term } | :error
390
388
def parse_requirement ( source ) do
391
389
lexed = lexer ( source , [ ] )
392
390
to_matchspec ( lexed )
393
391
end
394
392
395
- @ spec parse_version ( String . t ) :: { :ok , Version . matchable } | :error
393
+ @ spec parse_version ( String . t ( ) ) :: { :ok , Version . matchable ( ) } | :error
396
394
def parse_version ( string , approximate? \\ false ) when is_binary ( string ) do
397
395
destructure [ version_with_pre , build ] , String . split ( string , "+" , parts: 2 )
398
396
destructure [ version , pre ] , String . split ( version_with_pre , "-" , parts: 2 )
@@ -412,6 +410,7 @@ defmodule Version do
412
410
end
413
411
414
412
defp require_digits ( nil ) , do: :error
413
+
415
414
defp require_digits ( string ) do
416
415
if leading_zero? ( string ) , do: :error , else: parse_digits ( string , "" )
417
416
end
@@ -421,18 +420,19 @@ defmodule Version do
421
420
422
421
defp parse_digits ( << char , rest :: binary >> , acc ) when char in ?0 .. ?9 ,
423
422
do: parse_digits ( rest , << acc :: binary , char >> )
424
- defp parse_digits ( << >> , acc ) when byte_size ( acc ) > 0 ,
425
- do: { :ok , String . to_integer ( acc ) }
426
- defp parse_digits ( _ , _acc ) ,
427
- do: :error
423
+
424
+ defp parse_digits ( << >> , acc ) when byte_size ( acc ) > 0 , do: { :ok , String . to_integer ( acc ) }
425
+ defp parse_digits ( _ , _acc ) , do: :error
428
426
429
427
defp maybe_patch ( patch , approximate? )
430
428
defp maybe_patch ( nil , true ) , do: { :ok , nil }
431
429
defp maybe_patch ( patch , _ ) , do: require_digits ( patch )
432
430
433
431
defp optional_dot_separated ( nil ) , do: { :ok , [ ] }
432
+
434
433
defp optional_dot_separated ( string ) do
435
434
parts = String . split ( string , "." )
435
+
436
436
if Enum . all? ( parts , & ( & 1 != "" and valid_identifier? ( & 1 ) ) ) do
437
437
{ :ok , parts }
438
438
else
@@ -448,6 +448,7 @@ defmodule Version do
448
448
else
449
449
convert_parts_to_integer ( rest , [ integer | acc ] )
450
450
end
451
+
451
452
:error ->
452
453
convert_parts_to_integer ( rest , [ part | acc ] )
453
454
end
@@ -482,17 +483,17 @@ defmodule Version do
482
483
end
483
484
484
485
# or <op> | and <op>
485
- defp valid_requirement? ( a , [ b | next ] ) when is_atom ( a ) and is_atom ( b ) and a in [ :'||' , :'&&' ] do
486
+ defp valid_requirement? ( a , [ b | next ] ) when is_atom ( a ) and is_atom ( b ) and a in [ :|| , :&& ] do
486
487
valid_requirement? ( b , next )
487
488
end
488
489
489
490
# <version> or | <version> and
490
- defp valid_requirement? ( a , [ b | next ] ) when is_binary ( a ) and is_atom ( b ) and b in [ :'||' , :'&&' ] do
491
+ defp valid_requirement? ( a , [ b | next ] ) when is_binary ( a ) and is_atom ( b ) and b in [ :|| , :&& ] do
491
492
valid_requirement? ( b , next )
492
493
end
493
494
494
495
# or <version> | and <version>
495
- defp valid_requirement? ( a , [ b | next ] ) when is_atom ( a ) and is_binary ( b ) and a in [ :'||' , :'&&' ] do
496
+ defp valid_requirement? ( a , [ b | next ] ) when is_atom ( a ) and is_binary ( b ) and a in [ :|| , :&& ] do
496
497
valid_requirement? ( b , next )
497
498
end
498
499
@@ -518,8 +519,8 @@ defmodule Version do
518
519
defp to_matchspec ( lexed ) do
519
520
if valid_requirement? ( lexed ) do
520
521
first = to_condition ( lexed )
521
- rest = Enum . drop ( lexed , 2 )
522
- { :ok , [ { { :'$1' , :'$2' , :'$3' , :'$4' , :'$5' } , [ to_condition ( first , rest ) ] , [ :'$_' ] } ] }
522
+ rest = Enum . drop ( lexed , 2 )
523
+ { :ok , [ { { :"$1" , :"$2" , :"$3" , :"$4" , :"$5" } , [ to_condition ( first , rest ) ] , [ :"$_" ] } ] }
523
524
else
524
525
:error
525
526
end
@@ -534,46 +535,54 @@ defmodule Version do
534
535
535
536
defp to_condition ( [ :!= , version | _ ] ) do
536
537
matchable = parse_condition ( version )
537
- main_condition ( :'/=' , matchable )
538
+ main_condition ( :"/=" , matchable )
538
539
end
539
540
540
541
defp to_condition ( [ :~> , version | _ ] ) do
541
542
from = parse_condition ( version , true )
542
- to = approximate_upper ( from )
543
+ to = approximate_upper ( from )
543
544
544
- { :andalso , to_condition ( [ :>= , matchable_to_string ( from ) ] ) ,
545
- to_condition ( [ :< , matchable_to_string ( to ) ] ) }
545
+ {
546
+ :andalso ,
547
+ to_condition ( [ :>= , matchable_to_string ( from ) ] ) ,
548
+ to_condition ( [ :< , matchable_to_string ( to ) ] )
549
+ }
546
550
end
547
551
548
552
defp to_condition ( [ :> , version | _ ] ) do
549
553
{ major , minor , patch , pre } = parse_condition ( version )
550
554
551
- { :andalso , { :orelse , main_condition ( :> , { major , minor , patch } ) ,
552
- { :andalso , main_condition ( :== , { major , minor , patch } ) ,
553
- pre_condition ( :> , pre ) } } ,
554
- no_pre_condition ( pre ) }
555
+ {
556
+ :andalso ,
557
+ {
558
+ :orelse ,
559
+ main_condition ( :> , { major , minor , patch } ) ,
560
+ { :andalso , main_condition ( :== , { major , minor , patch } ) , pre_condition ( :> , pre ) }
561
+ } ,
562
+ no_pre_condition ( pre )
563
+ }
555
564
end
556
565
557
566
defp to_condition ( [ :>= , version | _ ] ) do
558
567
matchable = parse_condition ( version )
559
568
560
- { :orelse , main_condition ( :== , matchable ) ,
561
- to_condition ( [ :> , version ] ) }
569
+ { :orelse , main_condition ( :== , matchable ) , to_condition ( [ :> , version ] ) }
562
570
end
563
571
564
572
defp to_condition ( [ :< , version | _ ] ) do
565
573
{ major , minor , patch , pre } = parse_condition ( version )
566
574
567
- { :orelse , main_condition ( :< , { major , minor , patch } ) ,
568
- { :andalso , main_condition ( :== , { major , minor , patch } ) ,
569
- pre_condition ( :< , pre ) } }
575
+ {
576
+ :orelse ,
577
+ main_condition ( :< , { major , minor , patch } ) ,
578
+ { :andalso , main_condition ( :== , { major , minor , patch } ) , pre_condition ( :< , pre ) }
579
+ }
570
580
end
571
581
572
582
defp to_condition ( [ :<= , version | _ ] ) do
573
583
matchable = parse_condition ( version )
574
584
575
- { :orelse , main_condition ( :== , matchable ) ,
576
- to_condition ( [ :< , version ] ) }
585
+ { :orelse , main_condition ( :== , matchable ) , to_condition ( [ :< , version ] ) }
577
586
end
578
587
579
588
defp to_condition ( current , [ ] ) do
@@ -591,52 +600,65 @@ defmodule Version do
591
600
defp parse_condition ( version , approximate? \\ false ) do
592
601
case parse_version ( version , approximate? ) do
593
602
{ :ok , { major , minor , patch , pre , _build } } -> { major , minor , patch , pre }
594
- :error -> throw :invalid_matchspec
603
+ :error -> throw ( :invalid_matchspec )
595
604
end
596
605
end
597
606
598
607
defp main_condition ( op , version ) when tuple_size ( version ) == 3 do
599
- { op , { { :'$1' , :'$2' , :'$3' } } ,
600
- { :const , version } }
608
+ { op , { { :"$1" , :"$2" , :"$3" } } , { :const , version } }
601
609
end
602
610
603
611
defp main_condition ( op , version ) when tuple_size ( version ) == 4 do
604
- { op , { { :'$1' , :'$2' , :'$3' , :'$4' } } ,
605
- { :const , version } }
612
+ { op , { { :"$1" , :"$2" , :"$3" , :"$4" } } , { :const , version } }
606
613
end
607
614
608
615
defp pre_condition ( :> , pre ) do
609
616
length_pre = length ( pre )
610
617
611
- { :orelse , { :andalso , { :== , { :length , :'$4' } , 0 } ,
612
- { :const , length_pre != 0 } } ,
613
- { :andalso , { :const , length_pre != 0 } ,
614
- { :orelse , { :> , { :length , :'$4' } , length_pre } ,
615
- { :andalso , { :== , { :length , :'$4' } , length_pre } ,
616
- { :> , :'$4' , { :const , pre } } } } } }
618
+ {
619
+ :orelse ,
620
+ { :andalso , { :== , { :length , :"$4" } , 0 } , { :const , length_pre != 0 } } ,
621
+ {
622
+ :andalso ,
623
+ { :const , length_pre != 0 } ,
624
+ {
625
+ :orelse ,
626
+ { :> , { :length , :"$4" } , length_pre } ,
627
+ { :andalso , { :== , { :length , :"$4" } , length_pre } , { :> , :"$4" , { :const , pre } } }
628
+ }
629
+ }
630
+ }
617
631
end
618
632
619
633
defp pre_condition ( :< , pre ) do
620
634
length_pre = length ( pre )
621
635
622
- { :orelse , { :andalso , { :'/=' , { :length , :'$4' } , 0 } ,
623
- { :const , length_pre == 0 } } ,
624
- { :andalso , { :'/=' , { :length , :'$4' } , 0 } ,
625
- { :orelse , { :< , { :length , :'$4' } , length_pre } ,
626
- { :andalso , { :== , { :length , :'$4' } , length_pre } ,
627
- { :< , :'$4' , { :const , pre } } } } } }
636
+ {
637
+ :orelse ,
638
+ { :andalso , { :"/=" , { :length , :"$4" } , 0 } , { :const , length_pre == 0 } } ,
639
+ {
640
+ :andalso ,
641
+ { :"/=" , { :length , :"$4" } , 0 } ,
642
+ {
643
+ :orelse ,
644
+ { :< , { :length , :"$4" } , length_pre } ,
645
+ { :andalso , { :== , { :length , :"$4" } , length_pre } , { :< , :"$4" , { :const , pre } } }
646
+ }
647
+ }
648
+ }
628
649
end
629
650
630
651
defp no_pre_condition ( [ ] ) do
631
- { :orelse , :'$5' , { :== , { :length , :'$4' } , 0 } }
652
+ { :orelse , :"$5" , { :== , { :length , :"$4" } , 0 } }
632
653
end
654
+
633
655
defp no_pre_condition ( _pre ) do
634
656
{ :const , true }
635
657
end
636
658
637
659
defp matchable_to_string ( { major , minor , patch , pre } ) do
638
660
patch = if patch , do: "#{ patch } " , else: "0"
639
- pre = if pre != [ ] , do: "-#{ Enum . join ( pre , "." ) } "
661
+ pre = if pre != [ ] , do: "-#{ Enum . join ( pre , "." ) } "
640
662
"#{ major } .#{ minor } .#{ patch } #{ pre } "
641
663
end
642
664
end
0 commit comments