@@ -556,11 +556,6 @@ pub fn uu_app() -> Command {
556
556
. num_args ( 0 ..)
557
557
. require_equals ( true )
558
558
. value_name ( "ATTR_LIST" )
559
- . overrides_with_all ( [
560
- options:: ARCHIVE ,
561
- options:: PRESERVE_DEFAULT_ATTRIBUTES ,
562
- options:: NO_PRESERVE ,
563
- ] )
564
559
// -d sets this option
565
560
// --archive sets this option
566
561
. help (
@@ -572,19 +567,18 @@ pub fn uu_app() -> Command {
572
567
Arg :: new ( options:: PRESERVE_DEFAULT_ATTRIBUTES )
573
568
. short ( 'p' )
574
569
. long ( options:: PRESERVE_DEFAULT_ATTRIBUTES )
575
- . overrides_with_all ( [ options:: PRESERVE , options:: NO_PRESERVE , options:: ARCHIVE ] )
576
570
. help ( "same as --preserve=mode,ownership(unix only),timestamps" )
577
571
. action ( ArgAction :: SetTrue ) ,
578
572
)
579
573
. arg (
580
574
Arg :: new ( options:: NO_PRESERVE )
581
575
. long ( options:: NO_PRESERVE )
576
+ . action ( ArgAction :: Append )
577
+ . use_value_delimiter ( true )
578
+ . value_parser ( ShortcutValueParser :: new ( PRESERVABLE_ATTRIBUTES ) )
579
+ . num_args ( 0 ..)
580
+ . require_equals ( true )
582
581
. value_name ( "ATTR_LIST" )
583
- . overrides_with_all ( [
584
- options:: PRESERVE_DEFAULT_ATTRIBUTES ,
585
- options:: PRESERVE ,
586
- options:: ARCHIVE ,
587
- ] )
588
582
. help ( "don't preserve the specified attributes" ) ,
589
583
)
590
584
. arg (
@@ -621,11 +615,6 @@ pub fn uu_app() -> Command {
621
615
Arg :: new ( options:: ARCHIVE )
622
616
. short ( 'a' )
623
617
. long ( options:: ARCHIVE )
624
- . overrides_with_all ( [
625
- options:: PRESERVE_DEFAULT_ATTRIBUTES ,
626
- options:: PRESERVE ,
627
- options:: NO_PRESERVE ,
628
- ] )
629
618
. help ( "Same as -dR --preserve=all" )
630
619
. action ( ArgAction :: SetTrue ) ,
631
620
)
@@ -839,6 +828,42 @@ impl Attributes {
839
828
}
840
829
}
841
830
831
+ pub fn diff ( self , other : & Self ) -> Self {
832
+ Self {
833
+ #[ cfg( unix) ]
834
+ ownership : if matches ! ( other. ownership, Preserve :: Yes { .. } ) {
835
+ Preserve :: No { explicit : true }
836
+ } else {
837
+ self . ownership
838
+ } ,
839
+ mode : if matches ! ( other. mode, Preserve :: Yes { .. } ) {
840
+ Preserve :: No { explicit : true }
841
+ } else {
842
+ self . mode
843
+ } ,
844
+ timestamps : if matches ! ( other. timestamps, Preserve :: Yes { .. } ) {
845
+ Preserve :: No { explicit : true }
846
+ } else {
847
+ self . timestamps
848
+ } ,
849
+ context : if matches ! ( other. context, Preserve :: Yes { .. } ) {
850
+ Preserve :: No { explicit : true }
851
+ } else {
852
+ self . context
853
+ } ,
854
+ links : if matches ! ( other. links, Preserve :: Yes { .. } ) {
855
+ Preserve :: No { explicit : true }
856
+ } else {
857
+ self . links
858
+ } ,
859
+ xattr : if matches ! ( other. xattr, Preserve :: Yes { .. } ) {
860
+ Preserve :: No { explicit : true }
861
+ } else {
862
+ self . xattr
863
+ } ,
864
+ }
865
+ }
866
+
842
867
pub fn parse_iter < T > ( values : impl Iterator < Item = T > ) -> Result < Self , Error >
843
868
where
844
869
T : AsRef < str > ,
@@ -926,34 +951,65 @@ impl Options {
926
951
}
927
952
} ;
928
953
929
- // Parse attributes to preserve
930
- let mut attributes =
931
- if let Some ( attribute_strs) = matches. get_many :: < String > ( options:: PRESERVE ) {
932
- if attribute_strs. len ( ) == 0 {
933
- Attributes :: DEFAULT
934
- } else {
935
- Attributes :: parse_iter ( attribute_strs) ?
954
+ let mut overiding_priority = [
955
+ options:: ARCHIVE ,
956
+ options:: PRESERVE ,
957
+ options:: NO_PRESERVE ,
958
+ options:: PRESERVE_DEFAULT_ATTRIBUTES ,
959
+ options:: NO_DEREFERENCE_PRESERVE_LINKS ,
960
+ ] ;
961
+ overiding_priority. sort_by ( |a, b| {
962
+ let a_index = matches. indices_of ( a) . and_then ( |v| v. last ( ) ) ;
963
+ let b_index = matches. indices_of ( b) . and_then ( |v| v. last ( ) ) ;
964
+ match ( a_index, b_index) {
965
+ ( None , None ) => Ordering :: Equal ,
966
+ ( None , Some ( _) ) => Ordering :: Greater ,
967
+ ( Some ( _) , None ) => Ordering :: Less ,
968
+ ( Some ( a) , Some ( b) ) => {
969
+ if a < b {
970
+ Ordering :: Less
971
+ } else {
972
+ Ordering :: Greater
973
+ }
936
974
}
937
- } else if matches. get_flag ( options:: ARCHIVE ) {
938
- // --archive is used. Same as --preserve=all
939
- Attributes :: ALL
940
- } else if matches. get_flag ( options:: NO_DEREFERENCE_PRESERVE_LINKS ) {
941
- Attributes :: LINKS
942
- } else if matches. get_flag ( options:: PRESERVE_DEFAULT_ATTRIBUTES ) {
943
- Attributes :: DEFAULT
944
- } else {
945
- Attributes :: NONE
946
- } ;
975
+ }
976
+ } ) ;
947
977
948
- // handling no-preserve options and adjusting the attributes
949
- if let Some ( attribute_strs) = matches. get_many :: < String > ( options:: NO_PRESERVE ) {
950
- if attribute_strs. len ( ) > 0 {
951
- let no_preserve_attributes = Attributes :: parse_iter ( attribute_strs) ?;
952
- if matches ! ( no_preserve_attributes. links, Preserve :: Yes { .. } ) {
953
- attributes. links = Preserve :: No { explicit : true } ;
954
- } else if matches ! ( no_preserve_attributes. mode, Preserve :: Yes { .. } ) {
955
- attributes. mode = Preserve :: No { explicit : true } ;
978
+ let mut attributes = Attributes :: NONE ;
979
+
980
+ for option in overiding_priority {
981
+ match option {
982
+ options:: ARCHIVE => {
983
+ if matches. get_flag ( options:: ARCHIVE ) {
984
+ attributes = Attributes :: ALL ;
985
+ }
986
+ }
987
+ options:: PRESERVE_DEFAULT_ATTRIBUTES => {
988
+ if matches. get_flag ( options:: PRESERVE_DEFAULT_ATTRIBUTES ) {
989
+ attributes = attributes. union ( & Attributes :: DEFAULT ) ;
990
+ }
991
+ }
992
+ options:: NO_DEREFERENCE_PRESERVE_LINKS => {
993
+ if matches. get_flag ( options:: NO_DEREFERENCE_PRESERVE_LINKS ) {
994
+ attributes = attributes. union ( & Attributes :: LINKS ) ;
995
+ }
996
+ }
997
+ options:: PRESERVE => {
998
+ if let Some ( attribute_strs) = matches. get_many :: < String > ( options:: PRESERVE ) {
999
+ if attribute_strs. len ( ) == 0 {
1000
+ attributes = attributes. union ( & Attributes :: DEFAULT ) ;
1001
+ }
1002
+ attributes = attributes. union ( & Attributes :: parse_iter ( attribute_strs) ?) ;
1003
+ }
1004
+ }
1005
+ options:: NO_PRESERVE => {
1006
+ if let Some ( attribute_strs) = matches. get_many :: < String > ( options:: NO_PRESERVE ) {
1007
+ if attribute_strs. len ( ) > 0 {
1008
+ attributes = attributes. diff ( & Attributes :: parse_iter ( attribute_strs) ?) ;
1009
+ }
1010
+ }
956
1011
}
1012
+ _ => ( ) ,
957
1013
}
958
1014
}
959
1015
0 commit comments