Skip to content

Commit

Permalink
Add Bash completion and man page
Browse files Browse the repository at this point in the history
Also fixed clippy warnings
  • Loading branch information
hwittenborn committed Jun 14, 2022
1 parent acae1fa commit eec22b7
Show file tree
Hide file tree
Showing 11 changed files with 694 additions and 18 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[package]
name = "mpr"
version = "0.1.1"
authors = ["Hunter Wittenborn <[email protected]"]
description = "The official command-line interface for the makedeb Package Repository"
edition = "2021"

Expand Down
123 changes: 123 additions & 0 deletions completions/mpr.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
_mpr_get_pkglist() {
mapfile -t opts < <("${words[0]}" pkglist)
}

_mpr_gen_compreply() {
mapfile -t COMPREPLY < <(compgen -W "${1}" -- "${2}")
}

_mpr_pkg_specified_check() {
if [[ "${#nonopts[@]}" -gt 3 ]]; then
_mpr_gen_compreply '${opts[@]}' "${cur}"
else
_mpr_get_pkglist
_mpr_gen_compreply '${opts[@]}' "${cur}"
fi
}

_mpr() {
local cur prev words cword
_init_completion || return

local cmds=(
'clone'
'comment'
'help'
'info'
'list-comments'
'search'
'whoami'
)
local opts=(
'--mpr-url'
'--token'
)

# Get a list of arguments that are nonoptions.
mapfile -t nonopts < <(printf '%s\n' "${words[@]}" | grep -v '^-')

if [[ "${#words[@]}" == 2 ]]; then
mapfile -t COMPREPLY < <(compgen -W '${cmds[@]}' "${cur}")
return
fi

case "${nonopts[1]}" in
clone|info|search)
case "${prev}" in
--token|--mpr-url)
return
;;
esac

case "${cur}" in
-*)
_mpr_gen_compreply '${opts[@]}' "${cur}"
return
;;
*)
_mpr_pkg_specified_check
return
;;
esac
;;
comment)
case "${prev}" in
--token|--mpr-url|--msg)
return
;;
esac

opts+=('--msg')
case "${cur}" in
-*)
_mpr_gen_compreply '${opts[@]}' "${cur}"
return
;;
*)
_mpr_pkg_specified_check
return
;;
esac
;;
help)
return
;;
list-comments)
case "${prev}" in
--token|--mpr-url)
return
;;
--paging)
opts=('auto' 'never' 'always')
_mpr_gen_compreply '${opts[@]}' "${cur}"
return
;;
esac

opts+=('--paging')
case "${cur}" in
-*)
_mpr_gen_compreply '${opts[@]}' "${cur}"
return
;;
*)
_mpr_pkg_specified_check
return
;;
esac
;;
whoami)
case "${prev}" in
--token|--mpr-url)
return
;;
esac

_mpr_gen_compreply '${opts[@]}' "${cur}"
return
;;
esac
}

complete -F _mpr mpr
# vim: set sw=4 expandtab:
17 changes: 14 additions & 3 deletions makedeb/PKGBUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,15 @@ pkgver=0.3.0
pkgrel=1
pkgdesc='The official command-line interface for the makedeb Package Repository'
arch=('any')
optdepends=('r!less')
makedepends=('cargo' 'libssl-dev' 'pkg-config')
optdepends=(
'r!less'
)
makedepends=(
'asciidoctor'
'cargo'
'libssl-dev'
'pkg-config'
)
license=('GPL3')
url='https://github.com/makedeb/mpr-cli'

Expand All @@ -15,11 +22,15 @@ sha256sums=('SKIP')
build() {
cd "${pkgname}-${pkgver}/"
cargo build --release

sed "s|\$\${MPR_VERSION}|${pkgver}|" man/mpr.8.adoc
}

package() {
cd "${pkgname}-${pkgver}/"
install -Dm 755 "target/release/mpr" "${pkgdir}/usr/bin/mpr"
install -Dm 755 target/release/mpr "${pkgdir}/usr/bin/mpr"
asciidoctor -b manpage -o - man/mpr.1.adoc | install -Dm 644 /dev/stdin "${pkgdir}/usr/share/man/man1/mpr.1"
install -Dm 644 completions/mpr.bash "${pkgdir}/usr/share/bash-completion/completions/mpr"
}

# vim: set sw=4 expandtab:
59 changes: 59 additions & 0 deletions man/mpr.1.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
= MAKEDEB(1)
:doctype: manpage
:hardbreaks:
:manmanual: MPR CLI
:mansource: MAKEDEB $${MPR_VERSION}

== NAME
mpr - The official command-line interface for the makedeb Package Repository

== SYNOPSIS
*mpr* clone _pkgbase_ [_options_] ...
*mpr* comment _pkgbase_ [_options_] ...
*mpr* info _pkgname_ [_options_] ...
*mpr* list-comments _pkgbase_ [_options_] ...
*mpr* search _query_ ... [_options_] ...
*mpr* whoami [_options_] ...

== DESCRIPTION
*mpr* is a command-line interface for interacting with the makedeb Package Repository.

The *comment* and *whoami* commands both require authentication via an API key in order to run. An API key can be obtained via the MPR web interface on the user's account page, and can be passed into this program via the *--token* argument or the *MPR_TOKEN* environment variable, the former being described in *OPTIONS*, and the latter in *ENVIRONMENT*.

*clone*::
Clone the build files for a package base from the MPR.

*comment*::
Comment on a package base's page on the MPR.

*info*::
Get information about a package on the MPR.

*list-comments*::
List comments of a package base on the MPR.

*search*::
Search the package list on the MPR.

*whoami*::
Show the currently authenticated user.

== OPTIONS
Run each command with *--help* to see available options.

== BUGS
Issues, as well as feature requests, should be reported on the project's GitHub page:

https://github.com/makedeb/mpr-cli/issues

Matrix is also used as our primary method of real-time communication, being where most discussions (outside of the issue tracker) take place. All rooms are joined via a Matrix space, which can be accessed via the following:

#makedeb:hunterwittenborn.com

== AUTHORS
Hunter Wittenborn <\[email protected]>

A full list of contributors can be found by running *git shortlog -esn* in the MPR CLI's Git repository (linked under *BUGS*).

== SEE ALSO
*makedeb*(8)
112 changes: 112 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
use clap::{self, Arg, Command, PossibleValue};

#[rustfmt::skip]
pub fn get_cmd() -> Command<'static> {
Command::new(clap::crate_name!())
.version(clap::crate_version!())
.about(clap::crate_description!())
.arg_required_else_help(true)
.arg(
Arg::new("token")
.help("The API token to authenticate to the MPR with")
.long("token")
.env("MPR_TOKEN")
.hide_env_values(true)
.global(true)
.takes_value(true)
)
.arg(
Arg::new("mpr-url")
.help("URL to access the MPR from")
.long("mpr-url")
.env("MPR_URL")
.hide_env_values(true)
.global(true)
.takes_value(true)
.default_value("https://mpr.makedeb.org")
)
.subcommand(
Command::new("clone")
.about("Clone a package base from the MPR")
.arg(
Arg::new("pkg")
.help("The package to clone")
.required(true)
)
)
.subcommand(
Command::new("comment")
.arg_required_else_help(true)
.about("Comment on a package page")
.arg(
Arg::new("pkg")
.help("The package to comment on")
.required(true)
.takes_value(true)
)
.arg(
Arg::new("msg")
.help("The comment to post")
.short('m')
.long("msg")
)
)
.subcommand(
Command::new("info")
.arg_required_else_help(true)
.about("View information about a package")
.arg(
Arg::new("pkg")
.help("The package to view")
.required(true)
)
.arg(
Arg::new("web")
.help("Open the page for the package in a web browser")
.short('w')
.long("web")
)
)
.subcommand(
Command::new("list-comments")
.arg_required_else_help(true)
.about("List the comments on a package")
.arg(
Arg::new("pkg")
.help("The package to view comments for")
.required(true)
)
.arg(
Arg::new("paging")
.help("When to send output to a pager")
.long("paging")
.takes_value(true)
.default_value("auto")
.value_parser([
PossibleValue::new("auto"),
PossibleValue::new("always"),
PossibleValue::new("never")
])
)
)
// Used in autocompletions.
.subcommand(
Command::new("pkglist")
.hide(true)
)
.subcommand(
Command::new("search")
.about("Search the MPR for a package")
.arg_required_else_help(true)
.arg(
Arg::new("pkg")
.required(true)
.help("The query to search for")
.multiple_values(true)
)
)
.subcommand(
Command::new("whoami")
.about("Show the currently authenticated user")
)
}
2 changes: 1 addition & 1 deletion src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ pub fn comment(args: &clap::ArgMatches) {
let body = json!({ "msg": msg }).to_string();

let request = util::AuthenticatedRequest::new(api_token, mpr_url);
let resp_text = request.post(&format!("comment/{}", pkg), body.to_string());
let resp_text = request.post(&format!("comment/{}", pkg), body);

// Parse the message.
let json = serde_json::from_str::<CommentResult>(&resp_text).unwrap();
Expand Down
15 changes: 9 additions & 6 deletions src/list_comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,29 @@ struct Comment {
}

pub fn list_comments(args: &clap::ArgMatches) {
let pkg: &String = args.get_one("pkg").unwrap();
let pkgbase: &String = args.get_one("pkg").unwrap();
let mpr_url: &String = args.get_one("mpr-url").unwrap();
let paging = args.get_one::<String>("paging").unwrap().as_str();
let cache = mpr_cache::new(mpr_url);

let mut pkgnames: Vec<&String> = Vec::new();
let mut pkgbases: Vec<&String> = Vec::new();

// Get a list of packages.
for pkg in &cache {
pkgnames.push(&pkg.pkgname);
pkgbases.push(&pkg.pkgbase);
}

// Abort if the package base doesn't exist.
if !pkgnames.contains(&pkg) {
message::error(&format!("Package '{}' doesn't exist on the MPR.", pkg));
if !pkgbases.contains(&pkgbase) {
message::error(&format!(
"Package base '{}' doesn't exist on the MPR.",
pkgbase
));
quit::with_code(exitcode::USAGE);
}

// Get package comments.
let resp = match reqwest::blocking::get(format!("{}/api/list-comments/{}", mpr_url, pkg)) {
let resp = match reqwest::blocking::get(format!("{}/api/list-comments/{}", mpr_url, pkgbase)) {
Ok(resp) => resp,
Err(err) => {
message::error(&format!("Failed to make request. [{}]", err));
Expand Down
Loading

0 comments on commit eec22b7

Please sign in to comment.