-
Notifications
You must be signed in to change notification settings - Fork 13
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
Integrate clap-markdown
in ghciwatch
#248
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ edition = "2021" | |
authors = [ | ||
"Rebecca Turner <[email protected]>" | ||
] | ||
description = "ghci-based file watcher and recompiler for Haskell projects" | ||
description = "Ghciwatch loads a GHCi session for a Haskell project and reloads it when source files change." | ||
readme = "README.md" | ||
homepage = "https://github.com/MercuryTechnologies/ghciwatch" | ||
repository = "https://github.com/MercuryTechnologies/ghciwatch" | ||
|
@@ -41,6 +41,7 @@ backoff = { version = "0.4.0", default-features = false } | |
camino = "1.1.4" | ||
# Clap 4.4 is the last version supporting Rust 1.72. | ||
clap = { version = "~4.4", features = ["derive", "wrap_help", "env", "string"] } | ||
clap-markdown = { path = "clap-markdown", optional = true } | ||
clearscreen = "2.0.1" | ||
command-group = { version = "2.1.0", features = ["tokio", "with-tokio"] } | ||
crossterm = { version = "0.27.0", features = ["event-stream"] } | ||
|
@@ -51,7 +52,7 @@ indoc = "1.0.6" | |
itertools = "0.11.0" | ||
line-span = "0.1.5" | ||
miette = { version = "5.9.0", features = ["fancy"] } | ||
nix = { version = "0.26.2", default_features = false, features = ["process", "signal"] } | ||
nix = { version = "0.26.2", default-features = false, features = ["process", "signal"] } | ||
notify-debouncer-full = "0.3.1" | ||
once_cell = "1.18.0" | ||
owo-colors = { version = "3.5.0", features = ["supports-colors"] } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
//! Command-line argument parser and argument access. | ||
#![allow(rustdoc::bare_urls)] | ||
|
||
use std::time::Duration; | ||
|
||
use camino::Utf8PathBuf; | ||
|
@@ -14,10 +12,47 @@ use crate::clonable_command::ClonableCommand; | |
use crate::ignore::GlobMatcher; | ||
use crate::normal_path::NormalPath; | ||
|
||
/// A `ghci`-based file watcher and Haskell recompiler. | ||
/// Ghciwatch loads a GHCi session for a Haskell project and reloads it | ||
/// when source files change. | ||
/// | ||
/// ## Examples | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding some examples. This is a sort of weird compromise; these look decent in
|
||
/// | ||
/// Load `cabal v2-repl` and watch for changes in `src`: | ||
/// | ||
/// ghciwatch | ||
/// | ||
/// Load a custom GHCi session and watch for changes in multiple locations: | ||
/// | ||
/// ghciwatch --command "cabal v2-repl lib:test-dev" \ | ||
/// --watch src --watch test | ||
/// | ||
/// Run tests after reloads: | ||
/// | ||
/// ghciwatch --test-ghci TestMain.testMain \ | ||
/// --after-startup-ghci ':set args "--match=/OnlyRunSomeTests/"' | ||
/// | ||
/// Use `hpack` to regenerate `.cabal` files: | ||
/// | ||
/// ghciwatch --before-startup-shell hpack \ | ||
/// --restart-glob '**/package.yaml' | ||
/// | ||
/// Also reload the session when `.persistentmodels` change: | ||
/// | ||
/// ghciwatch --watch config/modelsFiles \ | ||
/// --reload-glob '**/*.persistentmodels' | ||
/// | ||
/// Don't reload for `README.md` files: | ||
/// | ||
/// ghciwatch --reload-glob '!src/**/README.md' | ||
#[allow(rustdoc::invalid_rust_codeblocks)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And |
||
#[derive(Debug, Clone, Parser)] | ||
#[command(version, author, about)] | ||
#[command(max_term_width = 100)] | ||
#[command( | ||
version, | ||
author, | ||
verbatim_doc_comment, | ||
max_term_width = 100, | ||
override_usage = "ghciwatch [--command SHELL_COMMAND] [--watch PATH] [OPTIONS ...]" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
)] | ||
pub struct Opts { | ||
/// A shell command which starts a `ghci` REPL, e.g. `ghci` or `cabal v2-repl` or similar. | ||
/// | ||
|
@@ -27,11 +62,13 @@ pub struct Opts { | |
#[arg(long, value_name = "SHELL_COMMAND")] | ||
pub command: Option<ClonableCommand>, | ||
|
||
/// A file to write compilation errors to. This is analogous to `ghcid.txt`. | ||
/// A file to write compilation errors to. | ||
/// | ||
/// The output format is compatible with `ghcid`'s `--outputfile` option. | ||
#[arg(long, alias = "outputfile", alias = "errors")] | ||
pub error_file: Option<Utf8PathBuf>, | ||
|
||
/// Enable evaluating commands. | ||
/// Evaluate Haskell code in comments. | ||
/// | ||
/// This parses line commands starting with `-- $>` or multiline commands delimited by `{- $>` | ||
/// and `<$ -}` and evaluates them after reloads. | ||
|
@@ -52,6 +89,11 @@ pub struct Opts { | |
#[arg(long, hide = true)] | ||
pub tui: bool, | ||
|
||
/// Generate Markdown CLI documentation. | ||
#[cfg(feature = "clap-markdown")] | ||
#[arg(long, hide = true)] | ||
pub generate_markdown_help: bool, | ||
|
||
/// Lifecycle hooks and commands to run at various points. | ||
#[command(flatten)] | ||
pub hooks: crate::hooks::HookOpts, | ||
|
@@ -69,8 +111,10 @@ pub struct Opts { | |
#[derive(Debug, Clone, clap::Args)] | ||
#[clap(next_help_heading = "File watching options")] | ||
pub struct WatchOpts { | ||
/// Use polling with the given interval rather than notification-based file watching. Polling | ||
/// tends to be more reliable and less performant. | ||
/// Use polling with the given interval rather than notification-based file watching. | ||
/// | ||
/// Polling tends to be more reliable and less performant. In particular, notification-based | ||
/// watching often misses updates on macOS. | ||
#[arg(long, value_name = "DURATION", value_parser = crate::clap::DurationValueParser::default())] | ||
pub poll: Option<Duration>, | ||
|
||
|
@@ -88,33 +132,40 @@ pub struct WatchOpts { | |
)] | ||
pub debounce: Duration, | ||
|
||
/// A path to watch for changes. Directories are watched recursively. Can be given multiple times. | ||
#[arg(long = "watch")] | ||
/// A path to watch for changes. | ||
/// | ||
/// Directories are watched recursively. Can be given multiple times. | ||
#[arg(long = "watch", value_name = "PATH")] | ||
pub paths: Vec<NormalPath>, | ||
|
||
/// Reload the `ghci` session when paths matching this glob change. Can be given multiple | ||
/// times. The last matching glob will determine if a reload is triggered. | ||
/// Reload the `ghci` session when paths matching this glob change. | ||
/// | ||
/// By default, only changes to Haskell source files trigger reloads. If you'd like to exclude | ||
/// some files from that, you can add an ignore glob here, like `!src/my-special-dir/**/*.hs`. | ||
/// | ||
/// Globs provided here have precisely the same semantics as a single line in a `gitignore` | ||
/// file (`man gitignore`), where the meaning of `!` is inverted: namely, `!` at the beginning | ||
/// of a glob will ignore a file. | ||
/// | ||
/// The last matching glob will determine if a reload is triggered. | ||
/// | ||
/// Can be given multiple times. | ||
#[arg(long = "reload-glob")] | ||
pub reload_globs: Vec<String>, | ||
|
||
/// Restart the `ghci` session when paths matching this glob change. Can be given multiple | ||
/// times. | ||
/// Restart the `ghci` session when paths matching this glob change. | ||
/// | ||
/// By default, only changes to `.cabal` or `.ghci` files or Haskell source files being | ||
/// moved/removed will trigger restarts. | ||
/// | ||
/// Due to a `ghci` bug, the `ghci` session must be restarted when Haskell modules are removed | ||
/// or renamed: https://gitlab.haskell.org/ghc/ghc/-/issues/11596 | ||
/// Due to [a `ghci` bug][1], the `ghci` session must be restarted when Haskell modules are removed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kinda clumsy to have markdown link syntax in the It'd be nice to have a system that let us do some more advanced templating to add more detail in the manual... |
||
/// or renamed. | ||
/// | ||
/// See `--reload-globs` for more details. | ||
#[allow(rustdoc::bare_urls)] | ||
/// | ||
/// Can be given multiple times. | ||
/// | ||
/// [1]: https://gitlab.haskell.org/ghc/ghc/-/issues/11596 | ||
#[arg(long = "restart-glob")] | ||
pub restart_globs: Vec<String>, | ||
} | ||
|
@@ -147,9 +198,11 @@ pub struct LoggingOpts { | |
/// The grammar is: `target[span{field=value}]=level`, where `target` is a module path, `span` | ||
/// is a span name, and `level` is one of the levels listed above. | ||
/// | ||
/// See: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html | ||
/// See [documentation in `tracing-subscriber`][1]. | ||
/// | ||
/// A nice value is `ghciwatch=debug`. | ||
/// | ||
/// A nice value is "ghciwatch=debug". | ||
/// [1]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html | ||
#[arg(long, default_value = "ghciwatch=info")] | ||
pub log_filter: String, | ||
|
||
|
@@ -169,6 +222,8 @@ pub struct LoggingOpts { | |
pub trace_spans: Vec<FmtSpan>, | ||
|
||
/// Path to write JSON logs to. | ||
/// | ||
/// JSON logs are not yet stable and the format may change on any release. | ||
#[arg(long, value_name = "PATH")] | ||
pub log_json: Option<Utf8PathBuf>, | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got a warning about this, maybe a toolchain update caught it? IDK.