yuki-cli 0.1.2__tar.gz → 0.1.4__tar.gz
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.
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/.github/workflows/ci.yml +15 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/.github/workflows/release.yml +80 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/CHANGELOG.md +10 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/Cargo.lock +1 -1
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/Cargo.toml +1 -1
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/PKG-INFO +3 -1
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/README.md +2 -0
- yuki_cli-0.1.4/prek.toml +36 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/init.rs +70 -7
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/.gitignore +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/CLAUDE.md +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/LICENSE +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/Makefile +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/pyproject.toml +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/accounts.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/admin.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/check.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/contacts.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/documents.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/invoices.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/mod.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/projects.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/upload.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/cli/vat.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/accounting.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/accounting_info.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/archive.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/contact.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/mod.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/sales.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/soap_client.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/client/vat.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/config.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/error.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/lib.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/main.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/output.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/period.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/src/schema.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/tests/config.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/tests/error.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/tests/output.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/tests/parsers.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/tests/period.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/tests/soap_client.rs +0 -0
- {yuki_cli-0.1.2 → yuki_cli-0.1.4}/yuki_cli_py/__init__.py +0 -0
|
@@ -35,6 +35,21 @@ jobs:
|
|
|
35
35
|
- name: Run tests
|
|
36
36
|
run: make test
|
|
37
37
|
|
|
38
|
+
coverage:
|
|
39
|
+
name: Coverage
|
|
40
|
+
runs-on: ubuntu-latest
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
44
|
+
- uses: taiki-e/install-action@cargo-tarpaulin
|
|
45
|
+
- name: Generate coverage
|
|
46
|
+
run: cargo tarpaulin --out xml
|
|
47
|
+
- name: Upload to Codecov
|
|
48
|
+
uses: codecov/codecov-action@v5
|
|
49
|
+
with:
|
|
50
|
+
files: cobertura.xml
|
|
51
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
52
|
+
|
|
38
53
|
all-checks-passed:
|
|
39
54
|
name: All checks passed
|
|
40
55
|
runs-on: ubuntu-latest
|
|
@@ -212,3 +212,83 @@ jobs:
|
|
|
212
212
|
echo "Dry run complete. Artifacts built but nothing published."
|
|
213
213
|
echo "Archives:"
|
|
214
214
|
find artifacts/release-* -type f | sort
|
|
215
|
+
|
|
216
|
+
update-homebrew:
|
|
217
|
+
needs: release
|
|
218
|
+
if: ${{ !inputs.dry_run }}
|
|
219
|
+
runs-on: ubuntu-latest
|
|
220
|
+
steps:
|
|
221
|
+
- uses: actions/download-artifact@v4
|
|
222
|
+
with:
|
|
223
|
+
path: /tmp/artifacts
|
|
224
|
+
|
|
225
|
+
- name: Compute SHA256 hashes
|
|
226
|
+
id: hashes
|
|
227
|
+
run: |
|
|
228
|
+
for target in x86_64-apple-darwin aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
|
|
229
|
+
sha=$(cat /tmp/artifacts/release-${target}/yuki-cli-${{ github.ref_name }}-${target}.tar.gz.sha256 | awk '{print $1}')
|
|
230
|
+
key=$(echo "${target}" | tr '-' '_')
|
|
231
|
+
echo "${key}=${sha}" >> "$GITHUB_OUTPUT"
|
|
232
|
+
done
|
|
233
|
+
|
|
234
|
+
- name: Update Homebrew formula
|
|
235
|
+
env:
|
|
236
|
+
GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
|
|
237
|
+
run: |
|
|
238
|
+
VERSION="${{ github.ref_name }}"
|
|
239
|
+
VERSION_NUM="${VERSION#v}"
|
|
240
|
+
|
|
241
|
+
cat > /tmp/yuki-cli.rb << 'FORMULA'
|
|
242
|
+
class YukiCli < Formula
|
|
243
|
+
desc "CLI for Yuki bookkeeping"
|
|
244
|
+
homepage "https://github.com/rvben/yuki-cli"
|
|
245
|
+
version "VERSION_NUM"
|
|
246
|
+
license "MIT"
|
|
247
|
+
|
|
248
|
+
on_macos do
|
|
249
|
+
if Hardware::CPU.arm?
|
|
250
|
+
url "https://github.com/rvben/yuki-cli/releases/download/VERSION/yuki-cli-VERSION-aarch64-apple-darwin.tar.gz"
|
|
251
|
+
sha256 "SHA_AARCH64_APPLE_DARWIN"
|
|
252
|
+
else
|
|
253
|
+
url "https://github.com/rvben/yuki-cli/releases/download/VERSION/yuki-cli-VERSION-x86_64-apple-darwin.tar.gz"
|
|
254
|
+
sha256 "SHA_X86_64_APPLE_DARWIN"
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
on_linux do
|
|
259
|
+
if Hardware::CPU.arm?
|
|
260
|
+
url "https://github.com/rvben/yuki-cli/releases/download/VERSION/yuki-cli-VERSION-aarch64-unknown-linux-gnu.tar.gz"
|
|
261
|
+
sha256 "SHA_AARCH64_UNKNOWN_LINUX_GNU"
|
|
262
|
+
else
|
|
263
|
+
url "https://github.com/rvben/yuki-cli/releases/download/VERSION/yuki-cli-VERSION-x86_64-unknown-linux-gnu.tar.gz"
|
|
264
|
+
sha256 "SHA_X86_64_UNKNOWN_LINUX_GNU"
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def install
|
|
269
|
+
bin.install "yuki"
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
test do
|
|
273
|
+
system "#{bin}/yuki", "--version"
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
FORMULA
|
|
277
|
+
|
|
278
|
+
sed -i "s/VERSION_NUM/${VERSION_NUM}/g" /tmp/yuki-cli.rb
|
|
279
|
+
sed -i "s/VERSION/${VERSION}/g" /tmp/yuki-cli.rb
|
|
280
|
+
sed -i "s/SHA_AARCH64_APPLE_DARWIN/${{ steps.hashes.outputs.aarch64_apple_darwin }}/g" /tmp/yuki-cli.rb
|
|
281
|
+
sed -i "s/SHA_X86_64_APPLE_DARWIN/${{ steps.hashes.outputs.x86_64_apple_darwin }}/g" /tmp/yuki-cli.rb
|
|
282
|
+
sed -i "s/SHA_AARCH64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.aarch64_unknown_linux_gnu }}/g" /tmp/yuki-cli.rb
|
|
283
|
+
sed -i "s/SHA_X86_64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.x86_64_unknown_linux_gnu }}/g" /tmp/yuki-cli.rb
|
|
284
|
+
|
|
285
|
+
# Clone tap repo, update formula, push
|
|
286
|
+
git clone https://x-access-token:${GH_TOKEN}@github.com/rvben/homebrew-tap.git /tmp/tap
|
|
287
|
+
mkdir -p /tmp/tap/Formula
|
|
288
|
+
cp /tmp/yuki-cli.rb /tmp/tap/Formula/yuki-cli.rb
|
|
289
|
+
cd /tmp/tap
|
|
290
|
+
git config user.name "github-actions[bot]"
|
|
291
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
292
|
+
git add Formula/yuki-cli.rb
|
|
293
|
+
git diff --cached --quiet || git commit -m "Update yuki-cli to ${VERSION}"
|
|
294
|
+
git push
|
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
6
6
|
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## [0.1.4](https://github.com/rvben/yuki-cli/compare/v0.1.3...v0.1.4) - 2026-04-03
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- **init**: add API key guidance, colored status, and next steps ([4a00b76](https://github.com/rvben/yuki-cli/commit/4a00b769c2529284f9b0d3a1d969873ed5d815fc))
|
|
14
|
+
|
|
15
|
+
## [0.1.3](https://github.com/rvben/yuki-cli/compare/v0.1.2...v0.1.3) - 2026-04-03
|
|
16
|
+
|
|
7
17
|
## [0.1.2](https://github.com/rvben/yuki-cli/compare/v0.1.1...v0.1.2) - 2026-04-03
|
|
8
18
|
|
|
9
19
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yuki-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: End Users/Desktop
|
|
@@ -20,6 +20,8 @@ Project-URL: Repository, https://github.com/rvben/yuki-cli.git
|
|
|
20
20
|
|
|
21
21
|
# yuki
|
|
22
22
|
|
|
23
|
+
[](https://codecov.io/gh/rvben/yuki-cli)
|
|
24
|
+
|
|
23
25
|
CLI client for the [Yuki](https://www.yukiworks.nl) bookkeeping SOAP API.
|
|
24
26
|
|
|
25
27
|
[Yuki](https://www.yukiworks.nl) is a Dutch bookkeeping SaaS used for accounting, VAT returns, and document archiving. This CLI lets you query your administration, find missing invoices, and upload documents — from the terminal or as part of automated workflows.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# yuki
|
|
2
2
|
|
|
3
|
+
[](https://codecov.io/gh/rvben/yuki-cli)
|
|
4
|
+
|
|
3
5
|
CLI client for the [Yuki](https://www.yukiworks.nl) bookkeeping SOAP API.
|
|
4
6
|
|
|
5
7
|
[Yuki](https://www.yukiworks.nl) is a Dutch bookkeeping SaaS used for accounting, VAT returns, and document archiving. This CLI lets you query your administration, find missing invoices, and upload documents — from the terminal or as part of automated workflows.
|
yuki_cli-0.1.4/prek.toml
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#:schema: https://www.schemastore.org/prek.json
|
|
2
|
+
|
|
3
|
+
[[repos]]
|
|
4
|
+
repo = "builtin"
|
|
5
|
+
hooks = [
|
|
6
|
+
{ id = "trailing-whitespace" },
|
|
7
|
+
{ id = "end-of-file-fixer" },
|
|
8
|
+
{ id = "check-added-large-files" },
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[[repos]]
|
|
12
|
+
repo = "local"
|
|
13
|
+
[[repos.hooks]]
|
|
14
|
+
id = "cargo-fmt"
|
|
15
|
+
name = "cargo fmt"
|
|
16
|
+
entry = "cargo fmt -- --check"
|
|
17
|
+
language = "system"
|
|
18
|
+
types = ["rust"]
|
|
19
|
+
pass_filenames = false
|
|
20
|
+
|
|
21
|
+
[[repos.hooks]]
|
|
22
|
+
id = "cargo-clippy"
|
|
23
|
+
name = "cargo clippy"
|
|
24
|
+
entry = "cargo clippy -- -D warnings"
|
|
25
|
+
language = "system"
|
|
26
|
+
types = ["rust"]
|
|
27
|
+
pass_filenames = false
|
|
28
|
+
|
|
29
|
+
[[repos.hooks]]
|
|
30
|
+
id = "cargo-test"
|
|
31
|
+
name = "cargo test"
|
|
32
|
+
entry = "cargo test"
|
|
33
|
+
language = "system"
|
|
34
|
+
types = ["rust"]
|
|
35
|
+
pass_filenames = false
|
|
36
|
+
stages = ["pre-push"]
|
|
@@ -1,9 +1,44 @@
|
|
|
1
1
|
use std::collections::BTreeMap;
|
|
2
2
|
use std::io::{self, BufRead, Write};
|
|
3
3
|
|
|
4
|
+
use owo_colors::OwoColorize;
|
|
5
|
+
|
|
4
6
|
use crate::client::accounting::AccountingClient;
|
|
5
7
|
use crate::config::{AdminEntry, Config};
|
|
6
8
|
use crate::error::YukiError;
|
|
9
|
+
use crate::output::is_tty;
|
|
10
|
+
|
|
11
|
+
fn sym_ok() -> String {
|
|
12
|
+
if is_tty() {
|
|
13
|
+
"✔".green().to_string()
|
|
14
|
+
} else {
|
|
15
|
+
"✔".to_owned()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
fn sym_fail() -> String {
|
|
20
|
+
if is_tty() {
|
|
21
|
+
"✖".red().to_string()
|
|
22
|
+
} else {
|
|
23
|
+
"✖".to_owned()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fn bold(s: &str) -> String {
|
|
28
|
+
if is_tty() {
|
|
29
|
+
s.bold().to_string()
|
|
30
|
+
} else {
|
|
31
|
+
s.to_owned()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
fn dim(s: &str) -> String {
|
|
36
|
+
if is_tty() {
|
|
37
|
+
s.dimmed().to_string()
|
|
38
|
+
} else {
|
|
39
|
+
s.to_owned()
|
|
40
|
+
}
|
|
41
|
+
}
|
|
7
42
|
|
|
8
43
|
/// Convert an administration name to a safe config key.
|
|
9
44
|
///
|
|
@@ -39,13 +74,14 @@ pub async fn run(api_key: Option<&str>, default_admin: Option<&str>) -> Result<(
|
|
|
39
74
|
|
|
40
75
|
config.api_key = key;
|
|
41
76
|
config.save_to(&path)?;
|
|
42
|
-
eprintln!("API key updated in {}", path.display());
|
|
77
|
+
eprintln!("{} API key updated in {}", sym_ok(), path.display());
|
|
43
78
|
return Ok(());
|
|
44
79
|
}
|
|
45
80
|
|
|
46
81
|
let api_key = match api_key {
|
|
47
82
|
Some(k) => k.trim().to_string(),
|
|
48
83
|
None => {
|
|
84
|
+
eprintln!(" {} Yuki Portal → Settings → API keys", dim("→"));
|
|
49
85
|
eprint!("Yuki API key: ");
|
|
50
86
|
io::stderr().flush().ok();
|
|
51
87
|
stdin
|
|
@@ -62,12 +98,29 @@ pub async fn run(api_key: Option<&str>, default_admin: Option<&str>) -> Result<(
|
|
|
62
98
|
return Err(YukiError::Config("API key cannot be empty".to_string()));
|
|
63
99
|
}
|
|
64
100
|
|
|
65
|
-
|
|
101
|
+
eprint!("Authenticating...");
|
|
102
|
+
io::stderr().flush().ok();
|
|
66
103
|
let mut client = AccountingClient::new();
|
|
67
|
-
client.authenticate(&api_key).await
|
|
104
|
+
match client.authenticate(&api_key).await {
|
|
105
|
+
Ok(_) => eprintln!(" {}", sym_ok()),
|
|
106
|
+
Err(e) => {
|
|
107
|
+
eprintln!(" {}", sym_fail());
|
|
108
|
+
return Err(e);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
68
111
|
|
|
69
|
-
|
|
70
|
-
|
|
112
|
+
eprint!("Fetching administrations...");
|
|
113
|
+
io::stderr().flush().ok();
|
|
114
|
+
let admins = match client.administrations().await {
|
|
115
|
+
Ok(admins) => {
|
|
116
|
+
eprintln!(" {}", sym_ok());
|
|
117
|
+
admins
|
|
118
|
+
}
|
|
119
|
+
Err(e) => {
|
|
120
|
+
eprintln!(" {}", sym_fail());
|
|
121
|
+
return Err(e);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
71
124
|
|
|
72
125
|
if admins.is_empty() {
|
|
73
126
|
return Err(YukiError::NotFound(
|
|
@@ -150,8 +203,18 @@ pub async fn run(api_key: Option<&str>, default_admin: Option<&str>) -> Result<(
|
|
|
150
203
|
|
|
151
204
|
config.save_to(&path)?;
|
|
152
205
|
|
|
153
|
-
eprintln!(
|
|
154
|
-
eprintln!("
|
|
206
|
+
eprintln!();
|
|
207
|
+
eprintln!("{} Configuration saved to {}", sym_ok(), path.display());
|
|
208
|
+
eprintln!();
|
|
209
|
+
eprintln!("{}:", bold("Next steps"));
|
|
210
|
+
eprintln!(
|
|
211
|
+
" yuki documents list {}",
|
|
212
|
+
dim("# list archived documents")
|
|
213
|
+
);
|
|
214
|
+
eprintln!(" yuki contacts list {}", dim("# list contacts"));
|
|
215
|
+
eprintln!(" yuki invoices list {}", dim("# list invoices"));
|
|
216
|
+
eprintln!(" yuki completions zsh {}", dim("# shell completions"));
|
|
217
|
+
eprintln!();
|
|
155
218
|
|
|
156
219
|
Ok(())
|
|
157
220
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|