Skip to content

Commit

Permalink
Generate mangpages from CLI help
Browse files Browse the repository at this point in the history
Fixes #88.
  • Loading branch information
bradlarsen committed Feb 22, 2024
1 parent c640978 commit f23facc
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 541 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- WireGuard Private Key ([#104](https://github.com/praetorian-inc/noseyparker/pull/104))
- WireGuard Preshared Key ([#104](https://github.com/praetorian-inc/noseyparker/pull/104))

- A new `generate` command has been added, which generates various assets that are included in prebuilt releases:

- Shell completion scripts via `generate shell-completions`
- A JSON Schema for the `report -f json` output via `generate json-schema` ((#128)[https://github.com/praetorian-inc/noseyparker/issues/128])
- Manpages via `generate manpages` ((#88)[https://github.com/praetorian-inc/noseyparker/issues/88])

### Fixes
- Fixed several rules that in certain circumstances would fail to match and produce a runtime error message:

Expand Down Expand Up @@ -90,6 +96,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
Previously, this would automatically and silently be done when opening a datastore from an older version.
Explicit support for datastore migration may be added back in a future release.

- The `shell-completions` command has been moved from the top level to a subcommand of `generate`.


## [v0.16.0](https://github.com/praetorian-inc/noseyparker/releases/v0.16.0) (2023-12-06)

Expand Down
17 changes: 17 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/noseyparker-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ anyhow = { version = "1.0" }
bstr = { version = "1.0" }
clap = { version = "4.3", features = ["cargo", "derive", "env", "unicode", "wrap_help"] }
clap_complete = "4.4"
clap_mangen = "0.2"
console = "0.15"
content-guesser = { path = "../content-guesser" }
crossbeam-channel = "0.5"
Expand Down
79 changes: 60 additions & 19 deletions crates/noseyparker-cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use clap::{crate_description, crate_version, ArgAction, Args, Parser, Subcommand, ValueEnum, ValueHint};
use std::io::IsTerminal;
use std::path::PathBuf;
use std::path::{PathBuf, Path};
use strum::Display;
use url::Url;

Expand Down Expand Up @@ -187,13 +187,11 @@ pub enum Command {
#[command(display_order = 30)]
Rules(RulesArgs),

/// Generate shell completions
#[command(display_order = 40, hide=true)]
ShellCompletions(ShellCompletionsArgs),

/// Generate the JSON schema for the output of the `report` command
#[command(display_order = 50, hide=true)]
JsonSchema(JsonSchemaArgs),
/// Generate Nosey Parker release assets
///
/// This command is used primarily for generation of artifacts to be included in releases.
#[command(display_order = 40)]
Generate(GenerateArgs),
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -780,7 +778,30 @@ pub struct ReportArgs {


// -----------------------------------------------------------------------------
// `shell-completions` command
// `generate` command
// -----------------------------------------------------------------------------
#[derive(Args, Debug)]
pub struct GenerateArgs {
#[command(subcommand)]
pub command: GenerateCommand,
}


#[derive(Subcommand, Debug)]
pub enum GenerateCommand {
/// Generate man pages
#[command(name="manpages")]
ManPages(ManPagesArgs),

/// Generate the JSON schema for the output of the `report` command
JsonSchema(JsonSchemaArgs),

/// Generate shell completions
ShellCompletions(ShellCompletionsArgs),
}

// -----------------------------------------------------------------------------
// `generate shell-completions` command
// -----------------------------------------------------------------------------
#[derive(ValueEnum, Debug, Display, Clone)]
#[clap(rename_all = "lower")]
Expand All @@ -800,10 +821,25 @@ pub struct ShellCompletionsArgs {
}

// -----------------------------------------------------------------------------
// `json-schema` command
// `generate json-schema` command
// -----------------------------------------------------------------------------
#[derive(Args, Debug)]
pub struct JsonSchemaArgs {
/// Write output to the specified path
///
/// If this argument is not provided, stdout will be used.
#[arg(long, short, value_name = "PATH", value_hint = ValueHint::FilePath)]
pub output: Option<PathBuf>,
}

// -----------------------------------------------------------------------------
// `generate manpages` command
// -----------------------------------------------------------------------------
#[derive(Args, Debug)]
pub struct ManPagesArgs {
/// Write output to the specified directory
#[arg(long, short, value_name = "PATH", value_hint = ValueHint::DirPath, default_value="manpages")]
pub output: PathBuf,
}

// -----------------------------------------------------------------------------
Expand All @@ -827,15 +863,20 @@ pub struct OutputArgs<Format: ValueEnum + Send + Sync + 'static> {
impl <Format: ValueEnum + Send + Sync> OutputArgs<Format> {
/// Get a writer for the specified output destination.
pub fn get_writer(&self) -> std::io::Result<Box<dyn std::io::Write>> {
use std::fs::File;
use std::io::BufWriter;

match &self.output {
None => Ok(Box::new(BufWriter::new(std::io::stdout()))),
Some(p) => {
let f = File::create(p)?;
Ok(Box::new(BufWriter::new(f)))
}
get_writer_for_file_or_stdout(self.output.as_ref())
}
}

/// Get a writer for the file at the specified output destination, or stdout if not specified.
pub fn get_writer_for_file_or_stdout<P: AsRef<Path>>(path: Option<P>) -> std::io::Result<Box<dyn std::io::Write>> {
use std::fs::File;
use std::io::BufWriter;

match path.as_ref() {
None => Ok(Box::new(BufWriter::new(std::io::stdout()))),
Some(p) => {
let f = File::create(p)?;
Ok(Box::new(BufWriter::new(f)))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use anyhow::Result;
use tracing::info;

use crate::args::{GlobalArgs, JsonSchemaArgs, get_writer_for_file_or_stdout};
use crate::cmd_report::Finding;

pub fn run(_global_args: &GlobalArgs, args: &JsonSchemaArgs) -> Result<()> {
let schema = schemars::schema_for!(Vec<Finding>);

let mut writer = get_writer_for_file_or_stdout(args.output.as_ref())?;
writeln!(writer, "{}", serde_json::to_string_pretty(&schema).unwrap())?;
if let Some(output) = &args.output {
info!("Wrote JSON schema to {}", output.display());
}
return Ok(());
}
10 changes: 0 additions & 10 deletions crates/noseyparker-cli/src/cmd_json_schema.rs

This file was deleted.

6 changes: 2 additions & 4 deletions crates/noseyparker-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ use tracing::debug;

mod args;
mod cmd_datastore;
mod cmd_generate;
mod cmd_github;
mod cmd_json_schema;
mod cmd_report;
mod cmd_rules;
mod cmd_scan;
mod cmd_shell_completions;
mod cmd_summarize;
mod rule_loader;
mod reportable;
Expand Down Expand Up @@ -104,8 +103,7 @@ fn try_main(args: &CommandLineArgs) -> Result<()> {
args::Command::Scan(args) => cmd_scan::run(global_args, args),
args::Command::Summarize(args) => cmd_summarize::run(global_args, args),
args::Command::Report(args) => cmd_report::run(global_args, args),
args::Command::ShellCompletions(args) => cmd_shell_completions::run(global_args, args),
args::Command::JsonSchema(args) => cmd_json_schema::run(global_args, args),
args::Command::Generate(args) => cmd_generate::run(global_args, args),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Commands:
github Interact with GitHub
datastore Manage datastores
rules Manage rules
generate Generate Nosey Parker release assets
help Print this message or the help of the given subcommand(s)

Options:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Commands:
github Interact with GitHub
datastore Manage datastores
rules Manage rules
generate Generate Nosey Parker release assets
help Print this message or the help of the given subcommand(s)

Options:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Commands:
github Interact with GitHub
datastore Manage datastores
rules Manage rules
generate Generate Nosey Parker release assets
help Print this message or the help of the given subcommand(s)

Options:
Expand Down
49 changes: 32 additions & 17 deletions scripts/create-release.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ echo "CARGO_FEATURES: $CARGO_FEATURES"


################################################################################
# Create release
# Create release directory tree
################################################################################
# Go to the repository root
cd "$HERE/.."
Expand All @@ -97,20 +97,27 @@ RELEASE_DIR="release"
# Where does `cargo` build stuff?
CARGO_BUILD_DIR="target/release"

# What is the name of the program?
NOSEYPARKER="noseyparker"

mkdir "$RELEASE_DIR" || fatal "could not create release directory"
mkdir "$RELEASE_DIR"/{bin,share,share/completions,share/noseyparker} || fatal "could not create release directory tree"
mkdir "$RELEASE_DIR"/{bin,share,share/completions,share/man,share/man/man1,share/"${NOSEYPARKER}"} || fatal "could not create release directory tree"

# Build release version of noseyparker into the release dir
################################################################################
# Build release version of noseyparker
################################################################################
banner "Building release with Cargo"
cargo build --locked --profile release --features "$CARGO_FEATURES" || fatal "failed to build noseyparker"
cargo build --locked --profile release --features "$CARGO_FEATURES" || fatal "failed to build ${NOSEYPARKER}"

################################################################################
# Copy artifacts into the release directory tree
################################################################################
banner "Assembling release dir"
# Copy binary into release dir
NP="$PWD/$RELEASE_DIR/bin/noseyparker"
cp -p "$CARGO_BUILD_DIR/noseyparker-cli" "$NP"
NP="$PWD/$RELEASE_DIR/bin/${NOSEYPARKER}"
cp -p "$CARGO_BUILD_DIR/noseyparker-cli" "$NP" || fatal "failed to copy ${NOSEYPARKER}"

# Copy CHANGELOG.md, LICENSE, and README.md
cp -p CHANGELOG.md LICENSE README.md "$RELEASE_DIR/"
cp -p CHANGELOG.md LICENSE README.md "$RELEASE_DIR/" || fatal "failed to copy assets"

################################################################################
# Strip release binary if requested
Expand All @@ -121,16 +128,24 @@ if (( $DO_STRIP )); then
fi

################################################################################
# Shell completion generation
# Generate shell completion scripts
################################################################################
banner "Generating shell completion scripts"
for SHELL in bash zsh fish powershell elvish; do
"$NP" shell-completions --shell zsh >"$RELEASE_DIR/share/completions/noseyparker.$SHELL"
"$NP" generate shell-completions --shell zsh >"${RELEASE_DIR}/share/completions/${NOSEYPARKER}.$SHELL"
done

################################################################################
# Copy assets
# Generate manpages
################################################################################
banner "Generating manpages"
"$NP" generate manpages --output "${RELEASE_DIR}/share/man/man1"

################################################################################
# Generate JSON schema
################################################################################
cp -p share/noseyparker/* "$RELEASE_DIR/share/noseyparker/"
banner "Generating JSON schema"
"$NP" generate json-schema --output "${RELEASE_DIR}/share/${NOSEYPARKER}/report-schema.json"

################################################################################
# Sanity checking
Expand All @@ -142,24 +157,24 @@ banner "Release disk use"
find "$RELEASE_DIR" -type f -print0 | xargs -0 du -shc | sort -h -k1,1

if [[ $PLATFORM == 'linux' ]]; then
banner "ldd output for noseyparker"
banner "ldd output for ${NOSEYPARKER}"
ldd "$NP" || true

banner "readelf -d output for noseyparker"
banner "readelf -d output for ${NOSEYPARKER}"
readelf -d "$NP"

elif [[ $PLATFORM == 'macos' ]]; then
banner "otool -L output for noseyparker"
banner "otool -L output for ${NOSEYPARKER}"
otool -L "$NP"

banner "otool -l output for noseyparker"
banner "otool -l output for ${NOSEYPARKER}"
otool -l "$NP"

else
fatal "unknown platform $PLATFORM"
fi

banner "noseyparker --version"
banner "${NOSEYPARKER} --version"
"$NP" --version

banner "Complete!"
Loading

0 comments on commit f23facc

Please sign in to comment.