@@ -23,9 +23,6 @@ struct Cli {
2323 /// Debug mode - sets the RUST_LOG level to debug, defaults to warning level
2424 #[ clap( long, action, default_value = "false" , global = true ) ]
2525 debug : bool ,
26- /// Directories to search for ontologies. If not provided, the current directory is used.
27- #[ clap( long, short, num_args = 1 .., global = true ) ]
28- search_directories : Option < Vec < PathBuf > > ,
2926 /// Resolution policy for determining which ontology to use when there are multiple with the same name
3027 #[ clap( long, short, default_value = "default" , global = true ) ]
3128 policy : Option < String > ,
@@ -50,14 +47,17 @@ struct Cli {
5047 /// Do not search for ontologies in the search directories
5148 #[ clap( long = "no-search" , short = 'n' , action, global = true ) ]
5249 no_search : bool ,
50+ /// Directories to search for ontologies. If not provided, the current directory is used.
51+ #[ clap( global = true ) ]
52+ locations : Option < Vec < PathBuf > > ,
5353}
5454
5555#[ derive( Debug , Subcommand ) ]
5656enum Commands {
5757 /// Create a new ontology environment
5858 Init {
5959 /// Overwrite the environment if it already exists
60- #[ clap( long, short , default_value = "false" ) ]
60+ #[ clap( long, default_value = "false" ) ]
6161 overwrite : bool ,
6262 /// A JSON file containing a list of ontologies to add to the environment
6363 #[ clap( long = "list" , short = 'l' ) ]
@@ -155,7 +155,7 @@ fn main() -> Result<()> {
155155
156156 let config: Config = Config :: new (
157157 current_dir ( ) ?,
158- cmd. search_directories ,
158+ cmd. locations ,
159159 & cmd. includes ,
160160 & cmd. excludes ,
161161 cmd. require_ontology_names ,
@@ -166,17 +166,6 @@ fn main() -> Result<()> {
166166 cmd. temporary ,
167167 ) ?;
168168
169- // if not temporary and not init, check if the .ontoenv directory exists
170- // if it does not exist, raise an error
171- if !cmd. temporary && cmd. command . to_string ( ) != "Init" {
172- let path = current_dir ( ) ?. join ( ".ontoenv" ) ;
173- if !path. exists ( ) {
174- return Err ( anyhow:: anyhow!(
175- "OntoEnv not found. Run `ontoenv init` to create a new OntoEnv."
176- ) ) ;
177- }
178- }
179-
180169 // create the env object to use in the subcommand.
181170 // - if temporary is true, create a new env object each time
182171 // - if temporary is false, load the env from the .ontoenv directory if it exists
@@ -188,7 +177,10 @@ fn main() -> Result<()> {
188177 e. update ( ) ?;
189178 env = Some ( e) ;
190179 } else if cmd. command . to_string ( ) != "Init" {
191- env = Some ( OntoEnv :: load_from_directory ( current_dir ( ) ?) ?) ;
180+ // if .ontoenv exists, load it
181+ if current_dir ( ) ?. join ( ".ontoenv" ) . exists ( ) {
182+ env = Some ( OntoEnv :: load_from_directory ( current_dir ( ) ?) ?) ;
183+ }
192184 }
193185
194186 match cmd. command {
@@ -225,12 +217,11 @@ fn main() -> Result<()> {
225217 ) ;
226218 }
227219 Commands :: Status => {
228- if let Some ( ref env) = env {
229- // load env from .ontoenv/ontoenv.json
230- let status = env. status ( ) ?;
231- // pretty print the status
232- println ! ( "{}" , status) ;
233- }
220+ let env = require_ontoenv ( env) ?;
221+ // load env from .ontoenv/ontoenv.json
222+ let status = env. status ( ) ?;
223+ // pretty print the status
224+ println ! ( "{}" , status) ;
234225 }
235226 Commands :: Refresh => {
236227 // if temporary, raise an error
@@ -239,10 +230,9 @@ fn main() -> Result<()> {
239230 "Cannot refresh in temporary mode. Run `ontoenv init` to create a new OntoEnv."
240231 ) ) ;
241232 }
242- if let Some ( ref mut env) = env {
243- env. update ( ) ?;
244- env. save_to_directory ( ) ?;
245- }
233+ let mut env = require_ontoenv ( env) ?;
234+ env. update ( ) ?;
235+ env. save_to_directory ( ) ?;
246236 }
247237 Commands :: GetClosure {
248238 ontology,
@@ -252,114 +242,123 @@ fn main() -> Result<()> {
252242 } => {
253243 // make ontology an IRI
254244 let iri = NamedNode :: new ( ontology) . map_err ( |e| anyhow:: anyhow!( e. to_string( ) ) ) ?;
255- if let Some ( ref mut env) = env {
256- let graphid = env
257- . resolve ( ResolveTarget :: Graph ( iri. clone ( ) ) )
258- . ok_or ( anyhow:: anyhow!( format!( "Ontology {} not found" , iri) ) ) ?;
259- let closure = env. get_dependency_closure ( & graphid) ?;
260- let ( graph, _successful, failed_imports) =
261- env. get_union_graph ( & closure, rewrite_sh_prefixes, remove_owl_imports) ?;
262- if let Some ( failed_imports) = failed_imports {
263- for imp in failed_imports {
264- eprintln ! ( "{}" , imp) ;
265- }
245+ let mut env = require_ontoenv ( env) ?;
246+ let graphid = env
247+ . resolve ( ResolveTarget :: Graph ( iri. clone ( ) ) )
248+ . ok_or ( anyhow:: anyhow!( format!( "Ontology {} not found" , iri) ) ) ?;
249+ let closure = env. get_dependency_closure ( & graphid) ?;
250+ let union = env. get_union_graph ( & closure, rewrite_sh_prefixes, remove_owl_imports) ?;
251+ if let Some ( failed_imports) = union. failed_imports {
252+ for imp in failed_imports {
253+ eprintln ! ( "{}" , imp) ;
266254 }
267- // write the graph to a file
268- let destination = destination. unwrap_or_else ( || "output.ttl" . to_string ( ) ) ;
269- write_dataset_to_file ( & graph, & destination) ?;
270255 }
256+ // write the graph to a file
257+ let destination = destination. unwrap_or_else ( || "output.ttl" . to_string ( ) ) ;
258+ write_dataset_to_file ( & union. dataset , & destination) ?;
271259 }
272260 Commands :: Add { url, file } => {
273261 let location: OntologyLocation = match ( url, file) {
274262 ( Some ( url) , None ) => OntologyLocation :: Url ( url) ,
275263 ( None , Some ( file) ) => OntologyLocation :: File ( PathBuf :: from ( file) ) ,
276264 _ => return Err ( anyhow:: anyhow!( "Must specify either --url or --file" ) ) ,
277265 } ;
278- if let Some ( ref mut env) = env {
279- env. add ( location, true ) ?;
280- env. save_to_directory ( ) ?;
281- }
266+ let mut env = require_ontoenv ( env) ?;
267+ env. add ( location, true ) ?;
268+ env. save_to_directory ( ) ?;
282269 }
283270 Commands :: ListOntologies => {
284- if let Some ( ref env) = env {
285- // print list of ontology URLs from env.ontologies.values() sorted alphabetically
286- let mut ontologies: Vec < & GraphIdentifier > = env. ontologies ( ) . keys ( ) . collect ( ) ;
287- ontologies. sort_by ( |a, b| a. name ( ) . cmp ( & b. name ( ) ) ) ;
288- ontologies. dedup_by ( |a, b| a. name ( ) == b. name ( ) ) ;
289- for ont in ontologies {
290- println ! ( "{}" , ont. name( ) . as_str( ) ) ;
291- }
271+ let env = require_ontoenv ( env) ?;
272+ // print list of ontology URLs from env.ontologies.values() sorted alphabetically
273+ let mut ontologies: Vec < & GraphIdentifier > = env. ontologies ( ) . keys ( ) . collect ( ) ;
274+ ontologies. sort_by ( |a, b| a. name ( ) . cmp ( & b. name ( ) ) ) ;
275+ ontologies. dedup_by ( |a, b| a. name ( ) == b. name ( ) ) ;
276+ for ont in ontologies {
277+ println ! ( "{}" , ont. name( ) . as_str( ) ) ;
292278 }
293279 }
294280 Commands :: ListLocations => {
295- if let Some ( ref env) = env {
296- let mut ontologies: Vec < & GraphIdentifier > = env. ontologies ( ) . keys ( ) . collect ( ) ;
297- ontologies. sort_by ( |a, b| a. location ( ) . as_str ( ) . cmp ( b. location ( ) . as_str ( ) ) ) ;
298- for ont in ontologies {
299- println ! ( "{}" , ont. location( ) . as_str( ) ) ;
300- }
281+ let env = require_ontoenv ( env) ?;
282+ let mut ontologies: Vec < & GraphIdentifier > = env. ontologies ( ) . keys ( ) . collect ( ) ;
283+ ontologies. sort_by ( |a, b| a. location ( ) . as_str ( ) . cmp ( b. location ( ) . as_str ( ) ) ) ;
284+ for ont in ontologies {
285+ println ! ( "{}" , ont. location( ) . as_str( ) ) ;
301286 }
302287 }
303288 Commands :: Dump { contains } => {
304- if let Some ( ref env) = env {
305- env. dump ( contains. as_deref ( ) ) ;
306- }
289+ let env = require_ontoenv ( env) ?;
290+ env. dump ( contains. as_deref ( ) ) ;
307291 }
308292 Commands :: DepGraph { roots, output } => {
309- if let Some ( ref mut env) = env {
310- let dot = if let Some ( roots) = roots {
311- let roots: Vec < GraphIdentifier > = roots
312- . iter ( )
313- . map ( |iri| {
314- env. resolve ( ResolveTarget :: Graph ( NamedNode :: new ( iri) . unwrap ( ) ) )
315- . unwrap ( )
316- . clone ( )
317- } )
318- . collect ( ) ;
319- env. rooted_dep_graph_to_dot ( roots) ?
320- } else {
321- env. dep_graph_to_dot ( ) ?
322- } ;
323- // call graphviz to generate PDF
324- let dot_path = current_dir ( ) ?. join ( "dep_graph.dot" ) ;
325- std:: fs:: write ( & dot_path, dot) ?;
326- let output_path = output. unwrap_or_else ( || "dep_graph.pdf" . to_string ( ) ) ;
327- let output = std:: process:: Command :: new ( "dot" )
328- . args ( [ "-Tpdf" , dot_path. to_str ( ) . unwrap ( ) , "-o" , & output_path] )
329- . output ( ) ?;
330- if !output. status . success ( ) {
331- return Err ( anyhow:: anyhow!(
332- "Failed to generate PDF: {}" ,
333- String :: from_utf8_lossy( & output. stderr)
334- ) ) ;
335- }
293+ let env = require_ontoenv ( env) ?;
294+ let dot = if let Some ( roots) = roots {
295+ let roots: Vec < GraphIdentifier > = roots
296+ . iter ( )
297+ . map ( |iri| {
298+ env. resolve ( ResolveTarget :: Graph ( NamedNode :: new ( iri) . unwrap ( ) ) )
299+ . unwrap ( )
300+ . clone ( )
301+ } )
302+ . collect ( ) ;
303+ env. rooted_dep_graph_to_dot ( roots) ?
304+ } else {
305+ env. dep_graph_to_dot ( ) ?
306+ } ;
307+ // call graphviz to generate PDF
308+ let dot_path = current_dir ( ) ?. join ( "dep_graph.dot" ) ;
309+ std:: fs:: write ( & dot_path, dot) ?;
310+ let output_path = output. unwrap_or_else ( || "dep_graph.pdf" . to_string ( ) ) ;
311+ let output = std:: process:: Command :: new ( "dot" )
312+ . args ( [ "-Tpdf" , dot_path. to_str ( ) . unwrap ( ) , "-o" , & output_path] )
313+ . output ( ) ?;
314+ if !output. status . success ( ) {
315+ return Err ( anyhow:: anyhow!(
316+ "Failed to generate PDF: {}" ,
317+ String :: from_utf8_lossy( & output. stderr)
318+ ) ) ;
336319 }
337320 }
338321 Commands :: Dependents { ontologies } => {
339- if let Some ( ref mut env) = env {
340- for ont in ontologies {
341- let iri = NamedNode :: new ( ont) . map_err ( |e| anyhow:: anyhow!( e. to_string( ) ) ) ?;
342- let dependents = env. get_dependents ( & iri) ?;
343- println ! ( "Dependents of {}: " , iri) ;
344- for dep in dependents {
345- println ! ( "{}" , dep) ;
346- }
322+ let mut env = require_ontoenv ( env) ?;
323+ for ont in ontologies {
324+ let iri = NamedNode :: new ( ont) . map_err ( |e| anyhow:: anyhow!( e. to_string( ) ) ) ?;
325+ let dependents = env. get_dependents ( & iri) ?;
326+ println ! ( "Dependents of {}: " , iri) ;
327+ for dep in dependents {
328+ println ! ( "{}" , dep) ;
347329 }
348330 }
349331 }
350332 Commands :: Doctor => {
351- if let Some ( ref mut env) = env {
352- env. doctor ( ) ;
353- }
333+ let env = require_ontoenv ( env) ?;
334+ env. doctor ( ) ;
354335 }
355336 Commands :: Reset => {
356337 // remove .ontoenv directory
357338 let path = current_dir ( ) ?. join ( ".ontoenv" ) ;
339+ println ! ( "Removing .ontoenv directory at {}..." , path. display( ) ) ;
358340 if path. exists ( ) {
341+ // check delete? [y/N]
342+ let mut input = String :: new ( ) ;
343+ println ! ( "Are you sure you want to delete the .ontoenv directory? [y/N]" ) ;
344+ std:: io:: stdin ( )
345+ . read_line ( & mut input)
346+ . expect ( "Failed to read line" ) ;
347+ let input = input. trim ( ) ;
348+ if input != "y" && input != "Y" {
349+ println ! ( "Aborting..." ) ;
350+ return Ok ( ( ) ) ;
351+ }
359352 std:: fs:: remove_dir_all ( path) ?;
360353 }
361354 }
362355 }
363356
364357 Ok ( ( ) )
365358}
359+
360+ fn require_ontoenv ( env : Option < OntoEnv > ) -> Result < OntoEnv > {
361+ env. ok_or_else ( || {
362+ anyhow:: anyhow!( "OntoEnv not found. Run `ontoenv init` to create a new OntoEnv." )
363+ } )
364+ }
0 commit comments