@@ -5,8 +5,9 @@ use directories::ProjectDirs;
5
5
use error_stack:: ResultExt ;
6
6
use serde:: { Deserialize , Serialize } ;
7
7
use std:: path:: PathBuf ;
8
+ use std:: str:: FromStr ;
8
9
use std:: sync:: LazyLock ;
9
- use tracing :: { debug , trace } ;
10
+ use toml :: de :: Error ;
10
11
11
12
pub static PROJECT_DIRS : LazyLock < ProjectDirs > = LazyLock :: new ( || {
12
13
ProjectDirs :: from ( "net" , "octyl" , "jpre" ) . expect ( "Could not determine project directories" )
@@ -54,12 +55,7 @@ impl JpreConfig {
54
55
. attach_printable_lazy ( || {
55
56
format ! ( "Could not open config file at {:?}" , * CONFIG_PATH )
56
57
} ) ?;
57
- let contents = std:: fs:: read_to_string ( & * CONFIG_PATH )
58
- . change_context ( JpreError :: Unexpected )
59
- . attach_printable_lazy ( || {
60
- format ! ( "Could not read config file at {:?}" , * CONFIG_PATH )
61
- } ) ?;
62
- let config = toml:: from_str :: < JpreConfig > ( & contents) ;
58
+ let ( contents, config) = Self :: read_config ( ) ?;
63
59
match config {
64
60
Ok ( mut config) => {
65
61
if let Some ( distribution) = config. distribution {
@@ -90,19 +86,35 @@ impl JpreConfig {
90
86
format ! ( "Could not parse config file at {:?}" , * CONFIG_PATH )
91
87
} ) ;
92
88
}
93
- // jpre 0.2 config format
94
- let new_config = JpreConfig {
95
- default_jdk : Some ( VersionKey {
89
+
90
+ let mut new_config = toml_edit:: DocumentMut :: new ( ) ;
91
+ new_config[ "default_jdk" ] = toml_edit:: value (
92
+ VersionKey {
96
93
major : * major as u32 ,
97
94
pre_release : PreRelease :: None ,
98
- } ) ,
99
- distribution : None ,
100
- distributions : default_distribution ( ) ,
101
- forced_architecture : None ,
102
- forced_os : None ,
103
- } ;
104
- new_config. save ( ) ?;
105
- return Ok ( new_config) ;
95
+ }
96
+ . to_string ( ) ,
97
+ ) ;
98
+ let mut distributions = toml_edit:: Array :: new ( ) ;
99
+ distributions. push ( "temurin" ) ;
100
+ new_config[ "distributions" ] = toml_edit:: value ( distributions) ;
101
+
102
+ // Ensure whatever is in the config is valid.
103
+ toml:: from_str :: < JpreConfig > ( & new_config. to_string ( ) )
104
+ . expect ( "New config is invalid" ) ;
105
+
106
+ std:: fs:: write ( & * CONFIG_PATH , new_config. to_string ( ) )
107
+ . change_context ( JpreError :: Unexpected )
108
+ . attach_printable_lazy ( || {
109
+ format ! ( "Could not write config file at {:?}" , * CONFIG_PATH )
110
+ } ) ?;
111
+
112
+ return Self :: read_config ( ) ?
113
+ . 1
114
+ . change_context ( JpreError :: Unexpected )
115
+ . attach_printable_lazy ( || {
116
+ format ! ( "Could not parse config file at {:?}" , * CONFIG_PATH )
117
+ } ) ;
106
118
}
107
119
Err ( e)
108
120
. change_context ( JpreError :: Unexpected )
@@ -113,16 +125,36 @@ impl JpreConfig {
113
125
}
114
126
}
115
127
116
- pub fn save ( & self ) -> ESResult < ( ) , JpreError > {
117
- let contents = toml:: to_string ( self )
128
+ fn read_config ( ) -> ESResult < ( String , Result < JpreConfig , Error > ) , JpreError > {
129
+ let contents = std:: fs:: read_to_string ( & * CONFIG_PATH )
130
+ . change_context ( JpreError :: Unexpected )
131
+ . attach_printable_lazy ( || {
132
+ format ! ( "Could not read config file at {:?}" , * CONFIG_PATH )
133
+ } ) ?;
134
+ let config = toml:: from_str :: < JpreConfig > ( & contents) ;
135
+ Ok ( ( contents, config) )
136
+ }
137
+
138
+ pub fn edit_config < F : FnOnce ( & mut toml_edit:: DocumentMut ) > (
139
+ & mut self ,
140
+ editor : F ,
141
+ ) -> ESResult < ( ) , JpreError > {
142
+ let contents = Self :: read_config ( ) ?. 0 ;
143
+ let mut config = toml_edit:: DocumentMut :: from_str ( & contents)
118
144
. change_context ( JpreError :: Unexpected )
119
- . attach_printable ( "Could not serialize config to TOML" ) ?;
120
- debug ! ( "Writing config to {:?}" , * CONFIG_PATH ) ;
121
- trace ! ( "Config: {}" , contents) ;
122
- std:: fs:: write ( & * CONFIG_PATH , contents)
145
+ . attach_printable_lazy ( || {
146
+ format ! ( "Could not parse config file at {:?}" , * CONFIG_PATH )
147
+ } ) ?;
148
+ editor ( & mut config) ;
149
+
150
+ // Ensure whatever is in the config is valid, and update ourselves to it.
151
+ * self = toml:: from_str :: < JpreConfig > ( & config. to_string ( ) )
152
+ . unwrap_or_else ( |e| panic ! ( "Edited config is invalid: {}" , e) ) ;
153
+
154
+ std:: fs:: write ( & * CONFIG_PATH , config. to_string ( ) )
123
155
. change_context ( JpreError :: Unexpected )
124
156
. attach_printable_lazy ( || {
125
- format ! ( "Could not write config file to {:?}" , * CONFIG_PATH )
157
+ format ! ( "Could not write config file at {:?}" , * CONFIG_PATH )
126
158
} ) ?;
127
159
Ok ( ( ) )
128
160
}
0 commit comments