fizzy-cli 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +8 -3
- data/lib/fizzy/auth.rb +2 -2
- data/lib/fizzy/cli/auth.rb +4 -4
- data/lib/fizzy/client.rb +14 -6
- data/lib/fizzy/formatter.rb +25 -3
- data/lib/fizzy/version.rb +1 -1
- data/lib/fizzy.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8dff080f62b6b259b77127650d8be4044a35ecd86959efb4aeef2145c1446f54
|
|
4
|
+
data.tar.gz: c91fc7730a30946f973afed8f3e88599b4f1e6133f4985c012b26c323112f3aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 920efebccdd3501bf2337d2ba494fc7d8a83ec975494069a973dffa20537f8cf6fd3e9aff8f67f509f4cd011e24b1787ff8370fb909591fbf3b820d55c03c096
|
|
7
|
+
data.tar.gz: 05d674ae7f2cd41978a6e4ef18a108812e54314fb6a8a0f0a1c5c1dacb096119aebf6b69561b376ee4f6559f9b1b9051121a5d7ba9067aeb383a501ab31e69da
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
+
## [0.2.0] - 2026-02-21
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- Token storage migrated from JSON (`tokens.json`) to YAML (`tokens.yml`)
|
|
12
|
+
- Auth file parsing uses `YAML.safe_load_file` instead of `JSON.parse`
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- Formatter table column alignment with CJK characters, emoji, and other wide Unicode
|
|
16
|
+
- Formatter handles nil cell values without error
|
|
17
|
+
- ValidationError now shows human-readable output (`- field: message`) instead of raw JSON
|
|
18
|
+
- `identity` command documented as `fizzy auth identity` in README
|
|
19
|
+
- HTTP connection auto-closes on process exit via `at_exit` hook
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- `--account SLUG` usage example in README
|
|
23
|
+
- CLI integration tests for boards, cards, auth, and error handling (10 tests)
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
- Unused `patch` HTTP method from Client
|
|
27
|
+
|
|
8
28
|
## [0.1.0] - 2025-02-21
|
|
9
29
|
|
|
10
30
|
### Added
|
data/README.md
CHANGED
|
@@ -31,7 +31,7 @@ gem install fizzy
|
|
|
31
31
|
fizzy auth login --token YOUR_TOKEN
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
Tokens are stored at `~/.config/fizzy-cli/tokens.
|
|
34
|
+
Tokens are stored at `~/.config/fizzy-cli/tokens.yml`. You can also set `FIZZY_TOKEN` as an environment variable with `--account` to skip the file.
|
|
35
35
|
|
|
36
36
|
```sh
|
|
37
37
|
fizzy auth status # Show current auth
|
|
@@ -43,6 +43,11 @@ fizzy auth switch SLUG # Change default account
|
|
|
43
43
|
|
|
44
44
|
All commands support `--json` for JSON output and `--account SLUG` to override the default account.
|
|
45
45
|
|
|
46
|
+
```sh
|
|
47
|
+
# Use a different account
|
|
48
|
+
fizzy cards list --board BOARD_ID --account my-other-team
|
|
49
|
+
```
|
|
50
|
+
|
|
46
51
|
### Boards
|
|
47
52
|
|
|
48
53
|
```sh
|
|
@@ -142,7 +147,7 @@ fizzy pins unpin 42
|
|
|
142
147
|
### Other
|
|
143
148
|
|
|
144
149
|
```sh
|
|
145
|
-
fizzy identity # Show
|
|
150
|
+
fizzy auth identity # Show current user info
|
|
146
151
|
fizzy version # Print version
|
|
147
152
|
fizzy help # List all commands
|
|
148
153
|
```
|
|
@@ -173,7 +178,7 @@ end
|
|
|
173
178
|
|
|
174
179
|
| Source | Purpose |
|
|
175
180
|
|--------|---------|
|
|
176
|
-
| `~/.config/fizzy-cli/tokens.
|
|
181
|
+
| `~/.config/fizzy-cli/tokens.yml` | Stored auth tokens and default account |
|
|
177
182
|
| `FIZZY_TOKEN` env var | Token override (requires `--account`) |
|
|
178
183
|
|
|
179
184
|
## Development
|
data/lib/fizzy/auth.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Fizzy
|
|
4
4
|
class Auth
|
|
5
5
|
CONFIG_DIR = File.expand_path("~/.config/fizzy-cli")
|
|
6
|
-
TOKEN_FILE = File.join(CONFIG_DIR, "tokens.
|
|
6
|
+
TOKEN_FILE = File.join(CONFIG_DIR, "tokens.yml")
|
|
7
7
|
|
|
8
8
|
def self.resolve(account_slug = nil)
|
|
9
9
|
if ENV["FIZZY_TOKEN"]
|
|
@@ -25,7 +25,7 @@ module Fizzy
|
|
|
25
25
|
"No tokens file at #{TOKEN_FILE}. Run: fizzy auth login --token TOKEN"
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
data =
|
|
28
|
+
data = YAML.safe_load_file(TOKEN_FILE, permitted_classes: [Time])
|
|
29
29
|
slug = normalize_slug(account_slug || data["default_account"])
|
|
30
30
|
account = data["accounts"]&.find { |a| normalize_slug(a["account_slug"]) == slug }
|
|
31
31
|
raise AuthError, "No account found for #{slug}" unless account
|
data/lib/fizzy/cli/auth.rb
CHANGED
|
@@ -57,7 +57,7 @@ module Fizzy
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
FileUtils.mkdir_p(Auth::CONFIG_DIR)
|
|
60
|
-
File.write(Auth::TOKEN_FILE,
|
|
60
|
+
File.write(Auth::TOKEN_FILE, YAML.dump(data))
|
|
61
61
|
File.chmod(0o600, Auth::TOKEN_FILE)
|
|
62
62
|
|
|
63
63
|
puts "Authenticated as #{accounts.first.dig("user", "name")}"
|
|
@@ -85,7 +85,7 @@ module Fizzy
|
|
|
85
85
|
|
|
86
86
|
desc "accounts", "List available accounts"
|
|
87
87
|
def accounts
|
|
88
|
-
data =
|
|
88
|
+
data = YAML.safe_load_file(Auth::TOKEN_FILE, permitted_classes: [Time])
|
|
89
89
|
data["accounts"].each do |a|
|
|
90
90
|
marker = a["account_slug"] == data["default_account"] ? " *" : ""
|
|
91
91
|
puts "#{a["account_name"]} (#{a["account_slug"]})#{marker}"
|
|
@@ -95,13 +95,13 @@ module Fizzy
|
|
|
95
95
|
|
|
96
96
|
desc "switch ACCOUNT_SLUG", "Set default account"
|
|
97
97
|
def switch(account_slug)
|
|
98
|
-
data =
|
|
98
|
+
data = YAML.safe_load_file(Auth::TOKEN_FILE, permitted_classes: [Time])
|
|
99
99
|
normalized = Auth.normalize_slug(account_slug)
|
|
100
100
|
account = data["accounts"].find { |a| Auth.normalize_slug(a["account_slug"]) == normalized }
|
|
101
101
|
raise AuthError, "No account found for #{account_slug}" unless account
|
|
102
102
|
|
|
103
103
|
data["default_account"] = normalized
|
|
104
|
-
File.write(Auth::TOKEN_FILE,
|
|
104
|
+
File.write(Auth::TOKEN_FILE, YAML.dump(data))
|
|
105
105
|
|
|
106
106
|
puts "Switched to #{account["account_name"]} (#{normalized})"
|
|
107
107
|
end
|
data/lib/fizzy/client.rb
CHANGED
|
@@ -25,10 +25,6 @@ module Fizzy
|
|
|
25
25
|
request(:put, path, body: body)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
def patch(path, body: nil)
|
|
29
|
-
request(:patch, path, body: body)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
28
|
def delete(path)
|
|
33
29
|
request(:delete, path)
|
|
34
30
|
end
|
|
@@ -43,6 +39,11 @@ module Fizzy
|
|
|
43
39
|
http.open_timeout = 5
|
|
44
40
|
http.read_timeout = 30
|
|
45
41
|
http.start
|
|
42
|
+
at_exit do
|
|
43
|
+
http.finish
|
|
44
|
+
rescue StandardError
|
|
45
|
+
nil
|
|
46
|
+
end
|
|
46
47
|
http
|
|
47
48
|
end
|
|
48
49
|
end
|
|
@@ -71,7 +72,6 @@ module Fizzy
|
|
|
71
72
|
when :get then Net::HTTP::Get.new(uri)
|
|
72
73
|
when :post then Net::HTTP::Post.new(uri)
|
|
73
74
|
when :put then Net::HTTP::Put.new(uri)
|
|
74
|
-
when :patch then Net::HTTP::Patch.new(uri)
|
|
75
75
|
when :delete then Net::HTTP::Delete.new(uri)
|
|
76
76
|
end
|
|
77
77
|
end
|
|
@@ -116,7 +116,15 @@ module Fizzy
|
|
|
116
116
|
|
|
117
117
|
def parse_error(response)
|
|
118
118
|
data = JSON.parse(response.body)
|
|
119
|
-
|
|
119
|
+
|
|
120
|
+
if data["errors"].is_a?(Array) && data["errors"].any?
|
|
121
|
+
items = data["errors"].map do |e|
|
|
122
|
+
e.is_a?(Hash) ? "#{e["field"]}: #{e["message"]}" : e.to_s
|
|
123
|
+
end
|
|
124
|
+
"Validation failed\n - #{items.join("\n - ")}"
|
|
125
|
+
else
|
|
126
|
+
data["error"] || response.body
|
|
127
|
+
end
|
|
120
128
|
rescue JSON::ParserError
|
|
121
129
|
response.body
|
|
122
130
|
end
|
data/lib/fizzy/formatter.rb
CHANGED
|
@@ -7,13 +7,13 @@ module Fizzy
|
|
|
7
7
|
|
|
8
8
|
all_rows = [headers] + rows
|
|
9
9
|
widths = headers.each_index.map do |i|
|
|
10
|
-
all_rows.map { |r| r[i].to_s
|
|
10
|
+
all_rows.map { |r| display_width(r[i].to_s) }.max
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
io.puts headers.each_with_index.map { |h, i| h.to_s
|
|
13
|
+
io.puts headers.each_with_index.map { |h, i| display_ljust(h.to_s, widths[i]) }.join(" ")
|
|
14
14
|
io.puts widths.map { |w| "-" * w }.join(" ")
|
|
15
15
|
rows.each do |row|
|
|
16
|
-
io.puts row.each_with_index.map { |c, i| c.to_s
|
|
16
|
+
io.puts row.each_with_index.map { |c, i| display_ljust(c.to_s, widths[i]) }.join(" ")
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
@@ -33,5 +33,27 @@ module Fizzy
|
|
|
33
33
|
|
|
34
34
|
str.length > max ? "#{str[0...(max - 1)]}…" : str
|
|
35
35
|
end
|
|
36
|
+
|
|
37
|
+
def self.display_width(str)
|
|
38
|
+
str = str.to_s
|
|
39
|
+
str.each_char.sum { |c| wide_char?(c) ? 2 : 1 }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.display_ljust(str, width)
|
|
43
|
+
str = str.to_s
|
|
44
|
+
padding = width - display_width(str)
|
|
45
|
+
padding.positive? ? "#{str}#{" " * padding}" : str
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
WIDE_RANGES = [
|
|
49
|
+
0x1100..0x115F, 0x2E80..0xA4CF, 0xAC00..0xD7AF, 0xF900..0xFAFF,
|
|
50
|
+
0xFE10..0xFE6F, 0xFF00..0xFF60, 0x1F000..0x1FFFF, 0x20000..0x2FA1F
|
|
51
|
+
].freeze
|
|
52
|
+
|
|
53
|
+
def self.wide_char?(char)
|
|
54
|
+
WIDE_RANGES.any? { |r| r.cover?(char.ord) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private_class_method :display_width, :display_ljust, :wide_char?
|
|
36
58
|
end
|
|
37
59
|
end
|
data/lib/fizzy/version.rb
CHANGED
data/lib/fizzy.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fizzy-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Paluy
|
|
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
83
|
version: '0'
|
|
84
84
|
requirements: []
|
|
85
|
-
rubygems_version:
|
|
85
|
+
rubygems_version: 3.6.9
|
|
86
86
|
specification_version: 4
|
|
87
87
|
summary: CLI for Fizzy project management
|
|
88
88
|
test_files: []
|