Compare commits
7 Commits
8cfc6605c9
...
333636b524
| Author | SHA1 | Date | |
|---|---|---|---|
| 333636b524 | |||
| e954a2b09a | |||
| da8f008f1a | |||
| 7c0966be30 | |||
| c1019afa7a | |||
| 1a619d7bb4 | |||
| fc0d1b569c |
61
README.md
61
README.md
@@ -5,7 +5,7 @@ CLI tools for interacting with the Gitea API. Use interactively to talk to your
|
||||
## Usage
|
||||
|
||||
```txt
|
||||
Usage: gt-tools --url <GITEA_URL> --repo <REPO> <COMMAND>
|
||||
Usage: gt-tool [OPTIONS] <COMMAND>
|
||||
|
||||
Commands:
|
||||
list-releases
|
||||
@@ -16,6 +16,7 @@ Commands:
|
||||
Options:
|
||||
-u, --url <GITEA_URL> [env: GTTOOL_GITEA_URL=]
|
||||
-r, --repo <REPO> [env: GTTOOL_FQRN=]
|
||||
-p, --project <PROJECT> Path to project (relative or absolute). Used to select configuration.
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
```
|
||||
@@ -40,6 +41,12 @@ The repository name must be provided with `--repo` or `-u` on the command line,
|
||||
|
||||
E.g.: `--repo "go-gitea/gitea"` would name the Gitea repo belonging to the go-gitea organization.
|
||||
|
||||
### `<PROJECT>`
|
||||
|
||||
Override the default (current-directory) project name when searching through the config files for this project's settings.
|
||||
|
||||
See [configuration](#configuration) for details on format and file locations.
|
||||
|
||||
### `<COMMAND>`:
|
||||
|
||||
One of these, defaults to `help`:
|
||||
@@ -51,3 +58,55 @@ One of these, defaults to `help`:
|
||||
| upload-release | Uploads one-or-more files to an existing release, identified by it's tag name. |
|
||||
| help | prints the help text (the usage summary above). |
|
||||
|
||||
## Configuration
|
||||
|
||||
Instead of specifying everything on the command line every single run, some TOML files can be used to persist project settings.
|
||||
|
||||
> Exporting some environment variables would be similar, but that would be *more* annoying when working on multiple projects. One would have to constantly re-export the settings or use two shells. But then there's the issue of losing track of which shell has which settings.
|
||||
|
||||
Settings are retrieved from a table named the same as the project's path on disk. For example, gt_tool itself could have an entry as follows:
|
||||
|
||||
```toml
|
||||
["/home/robert/projects/gt-tool"]
|
||||
gitea_url = "https://demo.gitea.com/"
|
||||
owner = "dummy"
|
||||
repo = "gt-tool"
|
||||
token = "fake-token"
|
||||
```
|
||||
|
||||
Some may apply to all projects. For this, one can use the special `[all]` table.
|
||||
|
||||
```toml
|
||||
[all]
|
||||
gitea_url = "https://demo.gitea.com/"
|
||||
```
|
||||
|
||||
Since the more-specific settings are preferred, these can be combined to have an override effect.
|
||||
|
||||
```toml
|
||||
[all]
|
||||
gitea_url = "https://demo.gitea.com/"
|
||||
owner = "robert"
|
||||
# no `repo = ` section because that must be project specific.
|
||||
token = "fake-token"
|
||||
|
||||
# Override Gitea target so I can test my uploads privately.
|
||||
["/home/robert/projects/gt-tool"]
|
||||
gitea_url = "http://localhost:3000"
|
||||
repo = "gt-tool"
|
||||
```
|
||||
|
||||
Similar to how unspecified project settings will fall back to those in the "`[all]`" table, whole files will fall back to other, lower priority files. First, each dir in `$XDG_CONFIG_DIRS` is scanned for a `gt-tool.toml` file. Then, `/etc/gt-tool.toml`.
|
||||
|
||||
> All config files **MUST** be named named `gt-tool.toml`.
|
||||
|
||||
### Recognized Keys
|
||||
|
||||
| Key | Description |
|
||||
|-|-|
|
||||
| gitea_url | URL of the Gitea server. Same as `-u`, `--url`, and `$GTTOOL_GITEA_URL`. |
|
||||
| owner | Owner of the repository (individual, or organization). Combined with "repo" key to produce the fully-qualified-repo-name. Front-half of `-r`, `--repo`, and `$GTTOOL_FQRN` |
|
||||
| repo | Name of the repository on the Gitea server. Combined with "owner" key to produce the fully-qualified-repo-name. Back-half of `-r`, `--repo`, and `$GTTOOL_FQRN` |
|
||||
| token | Gitea auth token, exactly the same as `$RELEASE_KEY_GITEA` |
|
||||
|
||||
Additional keys are quietly ignored. The config loading is done by querying a HashMap, so anything not touched doesn't get inspected. The only requirements are that the file is valid TOML, and that these keys are all strings.h
|
||||
|
||||
10
src/cli.rs
10
src/cli.rs
@@ -5,8 +5,16 @@ use clap::{Parser, Subcommand};
|
||||
pub struct Args {
|
||||
#[arg(short = 'u', long = "url", env = "GTTOOL_GITEA_URL")]
|
||||
pub gitea_url: Option<String>,
|
||||
#[arg(short = 'r', long = "repo", env = "GTTOOL_FQRN")]
|
||||
#[arg(short = 'o', long = "owner", env = "GTTOOL_OWNER")]
|
||||
pub owner: Option<String>,
|
||||
#[arg(short = 'r', long = "repo", env = "GTTOOL_REPO")]
|
||||
pub repo: Option<String>,
|
||||
#[arg(
|
||||
short = 'p',
|
||||
long = "project",
|
||||
help = "Path to project (relative or absolute). Used to override configuration selection."
|
||||
)]
|
||||
pub project: Option<String>,
|
||||
|
||||
#[command(subcommand)]
|
||||
pub command: Commands,
|
||||
|
||||
@@ -23,6 +23,8 @@ pub enum Error {
|
||||
Placeholder, // TODO: Enumerate error modes
|
||||
MissingGiteaUrl, // the gitea URL wasn't specified on the CLI, env, or config file.
|
||||
MissingRepoFRQN, // either the owner, repo, or both weren't specified in the loaded PartialConfig
|
||||
MissingRepoOwner,
|
||||
MissingRepoName,
|
||||
WrappedConfigErr(config::Error),
|
||||
WrappedReqwestErr(reqwest::Error),
|
||||
MissingAuthToken,
|
||||
|
||||
48
src/main.rs
48
src/main.rs
@@ -1,4 +1,4 @@
|
||||
use std::path;
|
||||
use std::path::{self, PathBuf};
|
||||
|
||||
use gt_tool::cli::Args;
|
||||
use gt_tool::structs::release::{CreateReleaseOption, Release};
|
||||
@@ -12,12 +12,15 @@ use reqwest::header::ACCEPT;
|
||||
async fn main() -> Result<(), gt_tool::Error> {
|
||||
let args = Args::parse();
|
||||
|
||||
// TODO: Heuristics to guess project path
|
||||
// See issue #8: https://git.gelvin.dev/robert/gt-tool/issues/8
|
||||
let pwd = std::env::current_dir()
|
||||
.map_err(|_e| gt_tool::Error::WrappedConfigErr(gt_tool::config::Error::CouldntReadFile))?;
|
||||
let project_path =
|
||||
args.project
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or(std::env::current_dir().map_err(|_e| {
|
||||
gt_tool::Error::WrappedConfigErr(gt_tool::config::Error::CouldntReadFile)
|
||||
})?);
|
||||
let config = gt_tool::config::get_config(
|
||||
pwd.to_str()
|
||||
project_path
|
||||
.to_str()
|
||||
.expect("I assumed the path can be UTF-8, but that didn't work out..."),
|
||||
gt_tool::config::default_paths(),
|
||||
)?;
|
||||
@@ -27,21 +30,17 @@ async fn main() -> Result<(), gt_tool::Error> {
|
||||
.gitea_url
|
||||
.or(config.gitea_url)
|
||||
.ok_or(gt_tool::Error::MissingGiteaUrl)?;
|
||||
// Config files split the repo FQRN into "owner" and "repo" (confusing naming, sorry)
|
||||
// These must be merged back together and passed along.
|
||||
let conf_fqrn = config
|
||||
.owner
|
||||
.ok_or(gt_tool::Error::MissingRepoFRQN)
|
||||
.and_then(|mut own| {
|
||||
let repo = config.repo.ok_or(gt_tool::Error::MissingRepoFRQN)?;
|
||||
own.push('/');
|
||||
own.push_str(&repo);
|
||||
Ok(own)
|
||||
});
|
||||
let repo_fqrn = args
|
||||
.repo
|
||||
.ok_or(gt_tool::Error::MissingRepoFRQN)
|
||||
.or(conf_fqrn)?;
|
||||
|
||||
let owner = args.owner
|
||||
.or(config.owner)
|
||||
.ok_or(gt_tool::Error::MissingRepoOwner)?;
|
||||
|
||||
let repo = args.repo
|
||||
.or(config.repo)
|
||||
.or_else(infer_repo)
|
||||
.ok_or(gt_tool::Error::MissingRepoName)?;
|
||||
|
||||
let repo_fqrn = String::from(format!("{owner}/{repo}"));
|
||||
|
||||
let mut headers = reqwest::header::HeaderMap::new();
|
||||
headers.append(ACCEPT, header::HeaderValue::from_static("application/json"));
|
||||
@@ -171,3 +170,10 @@ fn match_release_by_tag(tag: &String, releases: Vec<Release>) -> Option<Release>
|
||||
}
|
||||
release
|
||||
}
|
||||
|
||||
fn infer_repo() -> Option<String> {
|
||||
let pwd = std::env::current_dir().ok()?;
|
||||
let file_name = pwd.file_name()?;
|
||||
let file_name_string = file_name.to_str()?;
|
||||
Some(String::from(file_name_string))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user