@mbe24/99problems 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/.github/ISSUE_TEMPLATE/01-feature.yml +65 -0
  2. package/.github/ISSUE_TEMPLATE/02-bug.yml +122 -0
  3. package/.github/ISSUE_TEMPLATE/99-custom.yml +33 -0
  4. package/.github/ISSUE_TEMPLATE/config.yml +1 -0
  5. package/.github/dependabot.yml +20 -0
  6. package/.github/scripts/publish.js +1 -1
  7. package/.github/workflows/ci.yml +32 -6
  8. package/.github/workflows/man-drift.yml +26 -0
  9. package/.github/workflows/release.yml +7 -7
  10. package/CONTRIBUTING.md +38 -50
  11. package/Cargo.lock +150 -107
  12. package/Cargo.toml +7 -2
  13. package/README.md +107 -85
  14. package/artifacts/binary-aarch64-apple-darwin/99problems +0 -0
  15. package/artifacts/binary-aarch64-unknown-linux-gnu/99problems +0 -0
  16. package/artifacts/binary-x86_64-apple-darwin/99problems +0 -0
  17. package/artifacts/binary-x86_64-pc-windows-msvc/99problems.exe +0 -0
  18. package/artifacts/binary-x86_64-unknown-linux-gnu/99problems +0 -0
  19. package/docs/man/99problems-completions.1 +31 -0
  20. package/docs/man/99problems-config.1 +50 -0
  21. package/docs/man/99problems-get.1 +114 -0
  22. package/docs/man/99problems-help.1 +25 -0
  23. package/docs/man/99problems-man.1 +32 -0
  24. package/docs/man/99problems.1 +52 -0
  25. package/npm/install.js +90 -3
  26. package/package.json +7 -7
  27. package/rust-toolchain.toml +4 -0
  28. package/src/cmd/config/key.rs +126 -0
  29. package/src/cmd/config/mod.rs +218 -0
  30. package/src/cmd/config/render.rs +33 -0
  31. package/src/cmd/config/store.rs +318 -0
  32. package/src/cmd/config/write.rs +173 -0
  33. package/src/cmd/get.rs +658 -0
  34. package/src/cmd/man.rs +117 -0
  35. package/src/cmd/mod.rs +3 -0
  36. package/src/config.rs +618 -118
  37. package/src/error.rs +254 -0
  38. package/src/format/json.rs +59 -18
  39. package/src/format/jsonl.rs +52 -0
  40. package/src/format/mod.rs +25 -3
  41. package/src/format/text.rs +73 -0
  42. package/src/format/yaml.rs +64 -15
  43. package/src/lib.rs +1 -0
  44. package/src/logging.rs +54 -0
  45. package/src/main.rs +225 -138
  46. package/src/model.rs +9 -1
  47. package/src/source/bitbucket/cloud/api.rs +67 -0
  48. package/src/source/bitbucket/cloud/mod.rs +178 -0
  49. package/src/source/bitbucket/cloud/model.rs +211 -0
  50. package/src/source/bitbucket/datacenter/api.rs +74 -0
  51. package/src/source/bitbucket/datacenter/mod.rs +181 -0
  52. package/src/source/bitbucket/datacenter/model.rs +327 -0
  53. package/src/source/bitbucket/mod.rs +90 -0
  54. package/src/source/bitbucket/query.rs +169 -0
  55. package/src/source/bitbucket/shared/auth.rs +54 -0
  56. package/src/source/bitbucket/shared/http.rs +59 -0
  57. package/src/source/bitbucket/shared/mod.rs +5 -0
  58. package/src/source/github/api.rs +128 -0
  59. package/src/source/github/mod.rs +191 -0
  60. package/src/source/github/model.rs +84 -0
  61. package/src/source/github/query.rs +50 -0
  62. package/src/source/gitlab/api.rs +282 -0
  63. package/src/source/gitlab/mod.rs +225 -0
  64. package/src/source/gitlab/model.rs +102 -0
  65. package/src/source/gitlab/query.rs +177 -0
  66. package/src/source/jira/api.rs +222 -0
  67. package/src/source/jira/mod.rs +161 -0
  68. package/src/source/jira/model.rs +99 -0
  69. package/src/source/jira/query.rs +153 -0
  70. package/src/source/mod.rs +65 -7
  71. package/tests/integration.rs +404 -33
  72. package/src/source/github_issues.rs +0 -227
package/src/cmd/man.rs ADDED
@@ -0,0 +1,117 @@
1
+ use anyhow::{Result, anyhow};
2
+ use clap::{Args, Command};
3
+ use clap_mangen::Man;
4
+ use std::fs;
5
+ use std::io::Write;
6
+ use std::path::{Path, PathBuf};
7
+
8
+ #[derive(Args, Debug)]
9
+ pub(crate) struct ManArgs {
10
+ /// Output directory to write generated man pages
11
+ #[arg(short = 'o', long)]
12
+ pub(crate) output: Option<PathBuf>,
13
+
14
+ /// Man section number to use in generated filenames
15
+ #[arg(long, default_value_t = 1)]
16
+ pub(crate) section: u8,
17
+ }
18
+
19
+ /// Run the `man` command.
20
+ ///
21
+ /// # Errors
22
+ ///
23
+ /// Returns an error if man-page generation fails or output files cannot be written.
24
+ pub(crate) fn run(root_command: Command, args: &ManArgs) -> Result<()> {
25
+ let pages = build_man_pages(root_command, args.section)?;
26
+ if let Some(output_dir) = args.output.as_deref() {
27
+ write_pages(output_dir, &pages)?;
28
+ return Ok(());
29
+ }
30
+
31
+ let root_page = pages
32
+ .iter()
33
+ .find(|page| page.file_stem == "99problems")
34
+ .ok_or_else(|| anyhow!("generated man pages did not contain a root page"))?;
35
+ print!("{}", root_page.contents);
36
+ Ok(())
37
+ }
38
+
39
+ #[derive(Debug, Clone)]
40
+ struct ManPage {
41
+ file_stem: String,
42
+ section: u8,
43
+ contents: String,
44
+ }
45
+
46
+ fn build_man_pages(mut root: Command, section: u8) -> Result<Vec<ManPage>> {
47
+ root.build();
48
+ let root_name = root.get_name().to_string();
49
+
50
+ let mut pages = vec![render_page(root.clone(), root_name.clone(), section)?];
51
+ for sub in root.get_subcommands().cloned() {
52
+ let file_stem = format!("{root_name}-{}", sub.get_name());
53
+ pages.push(render_page(sub, file_stem, section)?);
54
+ }
55
+ pages.sort_by(|a, b| a.file_stem.cmp(&b.file_stem));
56
+ Ok(pages)
57
+ }
58
+
59
+ fn render_page(command: Command, file_stem: String, section: u8) -> Result<ManPage> {
60
+ let mut buffer = Vec::new();
61
+ let man = Man::new(command);
62
+ man.render(&mut buffer)?;
63
+ let contents =
64
+ String::from_utf8(buffer).map_err(|_| anyhow!("generated man page was not valid UTF-8"))?;
65
+ Ok(ManPage {
66
+ file_stem,
67
+ section,
68
+ contents,
69
+ })
70
+ }
71
+
72
+ fn write_pages(output_dir: &Path, pages: &[ManPage]) -> Result<()> {
73
+ fs::create_dir_all(output_dir)?;
74
+ for page in pages {
75
+ let file_name = format!("{}.{}", page.file_stem, page.section);
76
+ let path = output_dir.join(file_name);
77
+ let mut file = fs::File::create(path)?;
78
+ file.write_all(page.contents.as_bytes())?;
79
+ }
80
+ Ok(())
81
+ }
82
+
83
+ #[cfg(test)]
84
+ mod tests {
85
+ use super::*;
86
+ use clap::CommandFactory;
87
+
88
+ #[derive(clap::Parser, Debug)]
89
+ struct ExampleCli {
90
+ #[command(subcommand)]
91
+ command: ExampleCommands,
92
+ }
93
+
94
+ #[derive(clap::Subcommand, Debug)]
95
+ enum ExampleCommands {
96
+ Get,
97
+ Man(ManArgs),
98
+ }
99
+
100
+ #[test]
101
+ fn build_pages_includes_root_and_subcommands() {
102
+ let command = ExampleCli::command();
103
+ let root_name = command.get_name().to_string();
104
+ let pages = build_man_pages(command, 1).expect("expected man generation");
105
+ assert!(pages.iter().any(|p| p.file_stem == root_name));
106
+ assert!(
107
+ pages
108
+ .iter()
109
+ .any(|p| p.file_stem == format!("{root_name}-get"))
110
+ );
111
+ assert!(
112
+ pages
113
+ .iter()
114
+ .any(|p| p.file_stem == format!("{root_name}-man"))
115
+ );
116
+ }
117
+ }
package/src/cmd/mod.rs ADDED
@@ -0,0 +1,3 @@
1
+ pub(crate) mod config;
2
+ pub(crate) mod get;
3
+ pub(crate) mod man;