Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate_to ignores given argument and derives its own #1898

Closed
alerque opened this issue May 2, 2020 · 3 comments · Fixed by #2434
Closed

generate_to ignores given argument and derives its own #1898

alerque opened this issue May 2, 2020 · 3 comments · Fixed by #2434
Labels
A-completion Area: completion generator C-bug Category: Updating dependencies
Milestone

Comments

@alerque
Copy link
Contributor

alerque commented May 2, 2020

Trying to get shell completion generators working on my app (porting from StructOpt) I ran into trouble using the generate_to() function.

pub fn generate_to<G, S, T>(app: &mut clap::App, bin_name: S, out_dir: T)
where
G: Generator,
S: Into<String>,
T: Into<OsString>,
{
let out_dir = PathBuf::from(out_dir.into());
let file_name = G::file_name(app.get_bin_name().unwrap());
let mut file = match File::create(out_dir.join(file_name)) {
Err(why) => panic!("couldn't create completion file: {}", why),
Ok(file) => file,
};
generate::<G, S>(app, bin_name, &mut file)
}

Even with code pretty much copied out of the docs (marked as ignore):

let outdir = match env::var_os("OUT_DIR") {
    None => return,
    Some(outdir) => outdir,
};

let mut app = build_cli();
generate_to::<Bash, _, _>(
    &mut app,     // We need to specify what generator to use
    "myapp",      // We need to specify the bin name manually
    outdir,       // We need to specify where to write to
);

This code explicitly passes a value for bin_name, yet it is unused. L130 of the function above is fetching the bin name out of the app definition and using that to build a file path, ignoring the value we passed.

Furthermore if the app doesn't happen to have a bin_name set already, the code will panic!

@pksunkara pksunkara added this to the 3.0 milestone May 3, 2020
@pksunkara pksunkara added the C-bug Category: Updating dependencies label May 3, 2020
@pksunkara
Copy link
Member

Thanks for reporting. This actually ties into #1764. We might want just one file name but different bin names.

@kbknapp
Copy link
Member

kbknapp commented May 4, 2020

I'm trying to remember exactly, but I think the reason I originally had the user pass in the binary name was because the App's bin_name doesn't get determined until runtime, however many shell completion script generations happen in a build.rs at compile time. So we need a way to tell the generating code what the binary would be called.

Of course this can be fixed by making App::bin_name or App::set_bin_name mandatory (side note we should fix the naming of those methods so they're less confusing. I know they one is &self and returns Sefl while other is just &mut self...I think the Rust idiom here is to make the &mut self's method name end in _mut...but I digress). But that should be well documented, or this invariant should be checked inside genereate_* methods via assert!s.

@CreepySkeleton CreepySkeleton added the A-completion Area: completion generator label Jun 30, 2020
@saecki
Copy link

saecki commented Feb 15, 2021

So just a follow up as I encountered this myself. How about using the passed bin_name as a file name if the app doesn't have one. Or providing a more helpful error message with expect instead of unwrap that says "App is missing a bin_name, consider adding one by using App::bin_name" or something similar.

@pksunkara pksunkara linked a pull request Apr 6, 2021 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-completion Area: completion generator C-bug Category: Updating dependencies
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants