@@ -801,6 +801,58 @@ pub fn rig_app() -> Command {
801801
802802 cmd_system = cmd_system. subcommand ( cmd_system_detect_platform) ;
803803
804+ // `--arch` only changes the answer on Windows, where the admin mode R
805+ // installation root is architecture dependent, so it is hidden elsewhere.
806+ // It is still defined on every platform, so that scripts do not break, and
807+ // it must not have a default value: `_default_arch` is empty on Linux and
808+ // would fail the value parser. (This is why `rig add --arch` and
809+ // `rig available --arch` need a `#[cfg]` block and this one does not.)
810+ fn arch_arg ( ) -> Arg {
811+ Arg :: new ( "arch" )
812+ . help ( "Architecture of the R installation root (default: native arch)." )
813+ . short ( 'a' )
814+ . long ( "arch" )
815+ . required ( false )
816+ . value_parser ( [ "x86_64" , "aarch64" , "arm64" ] )
817+ . platform ( "windows" )
818+ }
819+
820+ let cmd_system_dirs = Command :: new ( "dirs" )
821+ . about ( ABOUT_SYSTEM_DIRS )
822+ . long_about ( HELP_SYSTEM_DIRS )
823+ . display_order ( 0 )
824+ . arg (
825+ Arg :: new ( "json" )
826+ . help ( "JSON output" )
827+ . long ( "json" )
828+ . num_args ( 0 )
829+ . required ( false ) ,
830+ )
831+ . arg ( arch_arg ( ) ) ;
832+
833+ let cmd_system_r_dir = Command :: new ( "r-dir" )
834+ . about ( ABOUT_SYSTEM_R_DIR )
835+ . long_about ( HELP_SYSTEM_R_DIR )
836+ . display_order ( 0 )
837+ . arg ( arch_arg ( ) ) ;
838+
839+ let cmd_system_rtools_dir = Command :: new ( "rtools-dir" )
840+ . about ( ABOUT_SYSTEM_RTOOLS_DIR )
841+ . long_about ( HELP_SYSTEM_RTOOLS_DIR )
842+ . display_order ( 0 )
843+ . platform ( "windows" ) ;
844+
845+ let cmd_system_binary_dir = Command :: new ( "binary-dir" )
846+ . about ( ABOUT_SYSTEM_BINARY_DIR )
847+ . long_about ( HELP_SYSTEM_BINARY_DIR )
848+ . display_order ( 0 ) ;
849+
850+ cmd_system = cmd_system
851+ . subcommand ( cmd_system_dirs)
852+ . subcommand ( cmd_system_r_dir)
853+ . subcommand ( cmd_system_rtools_dir)
854+ . subcommand ( cmd_system_binary_dir) ;
855+
804856 cmd_system = cmd_system
805857 . subcommand ( cmd_system_links)
806858 . subcommand ( cmd_system_lib)
@@ -1868,4 +1920,62 @@ mod tests {
18681920 let cmdargs: Vec < & String > = run. get_many :: < String > ( "command" ) . unwrap ( ) . collect ( ) ;
18691921 assert_eq ! ( cmdargs, [ "check" , "--no-manual" , "." ] ) ;
18701922 }
1923+
1924+ // The `rig system dirs` family. These tests run on every platform, so they
1925+ // are also the guard that the items that are merely *hidden* off Windows
1926+ // stay defined everywhere.
1927+
1928+ fn sysargs ( argv : & [ & str ] ) -> ArgMatches {
1929+ let m = rig_app ( ) . try_get_matches_from ( argv) . unwrap ( ) ;
1930+ m. subcommand_matches ( "system" ) . unwrap ( ) . to_owned ( )
1931+ }
1932+
1933+ #[ test]
1934+ fn test_system_dirs_args ( ) {
1935+ let m = sysargs ( & [ "rig" , "system" , "dirs" ] ) ;
1936+ let dirs = m. subcommand_matches ( "dirs" ) . unwrap ( ) ;
1937+ assert ! ( !dirs. get_flag( "json" ) ) ;
1938+
1939+ let m = sysargs ( & [ "rig" , "system" , "dirs" , "--json" ] ) ;
1940+ assert ! ( m. subcommand_matches( "dirs" ) . unwrap( ) . get_flag( "json" ) ) ;
1941+
1942+ // The global --json also works, and must precede the subcommand.
1943+ let m = rig_app ( )
1944+ . try_get_matches_from ( [ "rig" , "--json" , "system" , "dirs" ] )
1945+ . unwrap ( ) ;
1946+ assert ! ( m. get_flag( "json" ) ) ;
1947+ }
1948+
1949+ #[ test]
1950+ fn test_system_dir_commands_are_defined_on_all_platforms ( ) {
1951+ // `rtools-dir` is hidden off Windows, but it must still parse, so that
1952+ // scripts can call it unconditionally.
1953+ let m = sysargs ( & [ "rig" , "system" , "rtools-dir" ] ) ;
1954+ assert ! ( m. subcommand_matches( "rtools-dir" ) . is_some( ) ) ;
1955+
1956+ let m = sysargs ( & [ "rig" , "system" , "binary-dir" ] ) ;
1957+ assert ! ( m. subcommand_matches( "binary-dir" ) . is_some( ) ) ;
1958+ }
1959+
1960+ #[ test]
1961+ fn test_system_r_dir_arch ( ) {
1962+ // Same as above: --arch is hidden off Windows, but always defined.
1963+ let m = sysargs ( & [ "rig" , "system" , "r-dir" , "--arch" , "aarch64" ] ) ;
1964+ let rdir = m. subcommand_matches ( "r-dir" ) . unwrap ( ) ;
1965+ assert_eq ! ( rdir. get_one:: <String >( "arch" ) , Some ( & "aarch64" . to_string( ) ) ) ;
1966+
1967+ // No default value: an empty one would fail the value parser on Linux.
1968+ let m = sysargs ( & [ "rig" , "system" , "r-dir" ] ) ;
1969+ let rdir = m. subcommand_matches ( "r-dir" ) . unwrap ( ) ;
1970+ assert_eq ! ( rdir. get_one:: <String >( "arch" ) , None ) ;
1971+
1972+ // `dirs` takes --arch as well.
1973+ let m = sysargs ( & [ "rig" , "system" , "dirs" , "-a" , "arm64" ] ) ;
1974+ let dirs = m. subcommand_matches ( "dirs" ) . unwrap ( ) ;
1975+ assert_eq ! ( dirs. get_one:: <String >( "arch" ) , Some ( & "arm64" . to_string( ) ) ) ;
1976+
1977+ assert ! ( rig_app( )
1978+ . try_get_matches_from( [ "rig" , "system" , "r-dir" , "--arch" , "amd64" ] )
1979+ . is_err( ) ) ;
1980+ }
18711981}
0 commit comments