From: Ian Jackson Date: Sat, 15 May 2021 22:42:57 +0000 (+0100) Subject: library listing: Rework library patterns X-Git-Tag: otter-0.6.0~248 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=f7695c8a2e664671f48f1fc6387225f9ba4871c3;p=otter.git library listing: Rework library patterns Signed-off-by: Ian Jackson --- diff --git a/apitest/at-otter.rs b/apitest/at-otter.rs index 646ae347..c3b8bfad 100644 --- a/apitest/at-otter.rs +++ b/apitest/at-otter.rs @@ -543,7 +543,7 @@ impl Ctx { prepare_game(&self.su().ds, &self.prctx, TABLE)?; let command = self.su().ds.ss( - "library-list @table@ wikimedia chess-yellow-?" + "library-list @table@ chess-yellow-?" )?; let output: String = self.otter(&command)?.into(); assert!( Regex::new("(?m)^wikimedia *chess-yellow-K *the yellow king$")? @@ -552,7 +552,7 @@ impl Ctx { "got: {}", &output); let command = self.su().ds.ss( - "library-add @table@ wikimedia chess-blue-?" + "library-add --lib wikimedia @table@ chess-blue-?" )?; let added = self.some_library_add(&command)?; assert_eq!(added.len(), 6); @@ -733,7 +733,7 @@ impl Ctx { let st = Command::new("cmp").args(&[&bundle_file, "00000.zip"]).status()?; if ! st.success() { panic!("cmp failed {}", st) } - let command = ds.ss("library-add @table@ lemon example-lemon")?; + let command = ds.ss("library-add --lib lemon @table@ example-lemon")?; let added = self.some_library_add(&command)?; assert_eq!( added.len(), 1 ); diff --git a/daemon/cmdlistener.rs b/daemon/cmdlistener.rs index 9f29763a..9b354037 100644 --- a/daemon/cmdlistener.rs +++ b/daemon/cmdlistener.rs @@ -368,17 +368,23 @@ fn execute_and_respond(cs: &mut CommandStreamData, cmd: MgmtCommand, MR::Libraries(libs) } - MC::LibraryListByGlob { game, glob: spec } => { + MC::LibraryListByGlob { game, lib, pat } => { let (ag, gref) = start_access_game(&game)?; let (results, _auth) = access_bundles( cs,&ag,&gref, &[TP::UploadBundles], &mut |ig, _| { let regs = ig.all_shapelibs(); - let libs = regs.lib_name_lookup(&spec.lib)?; let mut results: Vec = default(); - for lib in &*libs { - results.extend(lib.list_glob(&spec.item)?); + let libss = if let Some(lib) = &lib { + vec![regs.lib_name_lookup(lib)?] + } else { + regs.all_libs().collect() + }; + for libs in libss { + for lib in libs { + results.extend(lib.list_glob(&pat)?); + } } Ok(results) })?; diff --git a/src/bin/otter.rs b/src/bin/otter.rs index 98d05ce9..514b3de3 100644 --- a/src/bin/otter.rs +++ b/src/bin/otter.rs @@ -991,17 +991,13 @@ mod delete_game { //---------- library-list ---------- -#[derive(Debug)] +#[derive(Debug,Default)] struct LibGlobArgs { table_name: String, - pat: shapelib::ItemSpec, + lib: Option, + pat: Option, } -impl Default for LibGlobArgs { fn default() -> Self { Self { - table_name: default(), - pat: shapelib::ItemSpec { lib: default(), item: default() }, -} } } - impl LibGlobArgs { fn add_arguments<'ap, 'tlg: 'ap>( &'tlg mut self, @@ -1010,12 +1006,19 @@ impl LibGlobArgs { use argparse::*; ap.refer(&mut self.table_name).required() .add_argument("TABLE-NAME",Store,"table name"); - // xxx allow lack of library name to list library names - ap.refer(&mut self.pat.lib).required() - .add_argument("LIB-NAME",Store,"library name"); - // xxx allow lack of pattern to list whole library - ap.refer(&mut self.pat.item).required() - .add_argument("ITEM-GLOB-PATTERN",Store,"item glob pattern"); + ap.refer(&mut self.lib).metavar("LIBRARY") + .add_option(&["--lib"],StoreOption,"look only in LIBRARY"); + ap.refer(&mut self.pat) + .add_argument("ITEM-GLOB-PATTERN",StoreOption,"item glob pattern"); + } + + fn lib(&self) -> Option { + self.lib.clone() + } + fn pat(&self) -> String { + self.pat.as_ref().map(Deref::deref) + .unwrap_or("*") + .into() } } @@ -1036,7 +1039,20 @@ mod library_list { let args = parse_args::(args, &subargs, &ok_id, None); let mut chan = access_game(&ma, &args.table_name)?; - let items = chan.list_items(&args.pat)?; + if args.lib.is_none() && args.pat.is_none() { + let game = chan.game.clone(); + let libs = match chan.cmd(&MC::LibraryListLibraries { game })? { + MgmtResponse::Libraries(libs) => libs, + x => throw!(anyhow!( + "unexpected response to LibrarylistLibraries: {:?}", &x)), + }; + for lib in libs { + println!("{}", lib); + } + return; + } + + let items = chan.list_items(args.lib.clone(), args.pat())?; for it in &items { println!("{}", it); } @@ -1245,7 +1261,7 @@ mod library_add { } } - let items = chan.list_items(&args.tlg.pat)?; + let items = chan.list_items(args.tlg.lib(), args.tlg.pat())?; let mut exitcode = 0; let mut insns = vec![]; @@ -1272,7 +1288,7 @@ mod library_add { } }; let spec = shapelib::ItemSpec { - lib: args.tlg.pat.lib.clone(), + lib: it.libname.clone(), item: it.itemname.as_str().to_owned(), }; let spec = PiecesSpec { diff --git a/src/commands.rs b/src/commands.rs index 6c02d48c..38d5a17e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -59,7 +59,8 @@ pub enum MgmtCommand { }, LibraryListByGlob { game: InstanceName, - glob: shapelib::ItemSpec, + lib: Option, + pat: String, }, LoadFakeRng(Vec), diff --git a/src/mgmtchannel.rs b/src/mgmtchannel.rs index 0edb7470..be4547f9 100644 --- a/src/mgmtchannel.rs +++ b/src/mgmtchannel.rs @@ -212,12 +212,12 @@ impl MgmtChannelForGame { } #[throws(AE)] - pub fn list_items(&mut self, pat: &shapelib::ItemSpec) + pub fn list_items(&mut self, lib: Option, pat: String) -> Vec { // xxx allow globbing of library names let cmd = MgmtCommand::LibraryListByGlob { game: self.game.clone(), - glob: pat.clone(), + lib, pat, }; let mut items = match self.cmd(&cmd)? { MgmtResponse::LibraryItems(items) => items,