luciq-cli 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE +21 -0
- data/README.md +36 -18
- data/lib/luciq/api/client.rb +12 -141
- data/lib/luciq/cli.rb +1 -1
- data/lib/luciq/commands/auth.rb +1 -1
- data/lib/luciq/commands/query_arguments.rb +15 -2
- data/lib/luciq/commands/upload.rb +16 -100
- data/lib/luciq/query_cli.rb +8 -2
- data/lib/luciq/upload_cli.rb +27 -26
- data/lib/luciq/version.rb +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8a0f4b1ed57b62e9807f17afddbd5e34b5fa411d504cd2fdabd5afc50521650c
|
|
4
|
+
data.tar.gz: b25294d1c535c880a7d8be44385bce9ccdc49bd8be7245ae8417d031177aad27
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cf5b2166bc9f2e6910feab38b73d90187d9a928d3207e703bcc97faa55fcd84b6398362150300207c850d49460d9c200e65957615be10c4309e0e61a7ec8e9af
|
|
7
|
+
data.tar.gz: f90266fa97e558b083630cda382d9febe7421a3e3f9c4e03935c93819e28ab26510ed6e2c1d154666b5aa634b44d74f667686155c5783c4b5e10510cf90a8999
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] - 2026-08-04
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Breaking:** `luciq upload` commands now take `--slug` and `--mode` instead of `--app-token`, matching the query commands. Uploads authenticate with your CLI login, so no application token is needed.
|
|
15
|
+
- `luciq whoami` and `luciq upload` now call the Luciq API gateway instead of the public backend endpoints.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `--tag-action` on `luciq bugs update` to control how `--tags` is applied: `append` (default), `replace`, or `remove`
|
|
20
|
+
- Homebrew installation: `brew install luciqai/tap/luciq-cli`
|
|
21
|
+
- MIT LICENSE
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- `luciq bugs update` now rejects `--clear-tags` combined with `--tag-action`, and no longer treats a tags-only change as an empty update
|
|
26
|
+
- Corrected the dashboard URL shown for creating a CLI token
|
|
27
|
+
|
|
10
28
|
## [0.2.0] - 2026-07-05
|
|
11
29
|
|
|
12
30
|
### Added
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Instabug, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -15,14 +15,13 @@ gem install luciq-cli
|
|
|
15
15
|
### Using Homebrew (macOS/Linux)
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
|
-
brew
|
|
19
|
-
brew install luciq-cli
|
|
18
|
+
brew install luciqai/tap/luciq-cli
|
|
20
19
|
```
|
|
21
20
|
|
|
22
21
|
### From Source
|
|
23
22
|
|
|
24
23
|
```bash
|
|
25
|
-
git clone https://github.com/
|
|
24
|
+
git clone https://github.com/luciqai/luciq-cli.git
|
|
26
25
|
cd luciq-cli
|
|
27
26
|
bundle install
|
|
28
27
|
bundle exec rake install
|
|
@@ -32,7 +31,7 @@ bundle exec rake install
|
|
|
32
31
|
|
|
33
32
|
### 1. Authenticate
|
|
34
33
|
|
|
35
|
-
Generate a CLI token from your [Luciq Dashboard](https://dashboard.luciq.ai/company/cli), then:
|
|
34
|
+
Generate a CLI token from your [Luciq Dashboard](https://dashboard.luciq.ai/company/luciq-cli), then:
|
|
36
35
|
|
|
37
36
|
> **Self-hosted clusters:** Replace `dashboard.luciq.ai` with your cluster URL.
|
|
38
37
|
|
|
@@ -52,14 +51,16 @@ Upload Android mapping files (`mapping.txt`):
|
|
|
52
51
|
|
|
53
52
|
```bash
|
|
54
53
|
luciq upload android-mapping mapping.txt \
|
|
55
|
-
--app
|
|
54
|
+
--slug my-app \
|
|
55
|
+
--mode production \
|
|
56
56
|
--version-name 1.0.0 \
|
|
57
57
|
--version-code 1
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
| Option | Description |
|
|
61
61
|
|--------|-------------|
|
|
62
|
-
| `--
|
|
62
|
+
| `--slug` | Application slug (required) |
|
|
63
|
+
| `--mode` | Application mode, e.g., `production` (required) |
|
|
63
64
|
| `--version-name` | App version name, e.g., `1.0.0` (required) |
|
|
64
65
|
| `--version-code` | App version code, e.g., `1` (required) |
|
|
65
66
|
|
|
@@ -125,11 +126,13 @@ Run `luciq upload help SUBCOMMAND` for the full options of any command.
|
|
|
125
126
|
| `luciq upload flutter-android-sourcemap FILE` | `.zip` | Android Dart symbol files |
|
|
126
127
|
| `luciq upload flutter-ndk FILE` | `.zip` | NDK `.so` shared object files (`--arch`) |
|
|
127
128
|
|
|
128
|
-
Common options: `--
|
|
129
|
-
(`*-ios-dsym`) need only
|
|
130
|
-
|
|
131
|
-
commands
|
|
132
|
-
|
|
129
|
+
Common options: `--slug` and `--mode` are required for every command — uploads use
|
|
130
|
+
your CLI login, the same as query commands. dSYM commands (`*-ios-dsym`) need only
|
|
131
|
+
`--slug` / `--mode`. Mapping, source-map, and
|
|
132
|
+
Flutter Dart-symbol commands also require `--version-name` / `--version-code`
|
|
133
|
+
(React Native source-map commands additionally accept `--codepush`). NDK commands
|
|
134
|
+
require `--version-name` and `--arch` (`armeabi-v7a`, `arm64-v8a`, `x86`, `x86_64`)
|
|
135
|
+
— not `--version-code`.
|
|
133
136
|
|
|
134
137
|
## Query & management commands
|
|
135
138
|
|
|
@@ -183,16 +186,20 @@ luciq crashes show --slug my-app --mode production --number 42
|
|
|
183
186
|
|------------|-------------|
|
|
184
187
|
| `list` | List bugs. Flags: `--status` (new/closed/in_progress), `--priority` (na/trivial/minor/major/blocker), `--app-version` |
|
|
185
188
|
| `show --number N` | Details for one bug |
|
|
186
|
-
| `update --number N` | Update a bug. Flags: `--status`, `--priority`, `--tags`, `--clear-tags`, `--duplicate-of`, `--action` |
|
|
189
|
+
| `update --number N` | Update a bug. Flags: `--status`, `--priority`, `--tags`, `--tag-action`, `--clear-tags`, `--duplicate-of`, `--action` |
|
|
187
190
|
|
|
188
191
|
```bash
|
|
189
192
|
luciq bugs update --slug my-app --mode production --number 7 --status closed --priority major
|
|
190
193
|
luciq bugs update --slug my-app --mode production --number 7 --duplicate-of 3
|
|
194
|
+
luciq bugs update --slug my-app --mode production --number 7 --tags urgent regression
|
|
195
|
+
luciq bugs update --slug my-app --mode production --number 7 --tags stale --tag-action remove
|
|
196
|
+
luciq bugs update --slug my-app --mode production --number 7 --tags only-this --tag-action replace
|
|
191
197
|
```
|
|
192
198
|
|
|
193
199
|
Provide at least one change. Duplicate marking (`--duplicate-of` / `--action`)
|
|
194
|
-
can't be combined with `--status`/`--priority
|
|
195
|
-
tags
|
|
200
|
+
can't be combined with `--status`/`--priority`. Tags: `--tags` appends to the existing
|
|
201
|
+
tags by default; `--tag-action replace` sets `--tags` as the full list (removing others),
|
|
202
|
+
`--tag-action remove` deletes `--tags` and keeps the rest; `--clear-tags` removes all.
|
|
196
203
|
|
|
197
204
|
### APM
|
|
198
205
|
|
|
@@ -320,14 +327,25 @@ url=https://api.your-cluster.luciq.ai
|
|
|
320
327
|
|
|
321
328
|
## Development
|
|
322
329
|
|
|
323
|
-
|
|
324
|
-
git clone https://github.com/Instabug/luciq-cli.git
|
|
325
|
-
cd luciq-cli
|
|
326
|
-
bundle install
|
|
330
|
+
Clone the repo and install dependencies as in [From Source](#from-source), then:
|
|
327
331
|
|
|
332
|
+
```bash
|
|
328
333
|
# Run tests
|
|
329
334
|
bundle exec rspec
|
|
330
335
|
|
|
331
336
|
# Test locally
|
|
332
337
|
bundle exec bin/luciq --help
|
|
333
338
|
```
|
|
339
|
+
|
|
340
|
+
## Releasing
|
|
341
|
+
|
|
342
|
+
After publishing a new gem version to RubyGems, sync the Homebrew formula in
|
|
343
|
+
the [homebrew-tap](https://github.com/luciqai/homebrew-tap) repo:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
bundle exec rake formula:bump # writes to ../homebrew-tap, override with TAP_DIR
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Open a pull request in the tap repo with the result: Homebrew users stay on
|
|
350
|
+
the previous version until the bumped formula lands on its `main` branch.
|
|
351
|
+
`brew livecheck luciq-cli` reports when the formula lags RubyGems.
|
data/lib/luciq/api/client.rb
CHANGED
|
@@ -9,18 +9,13 @@ require 'luciq/config'
|
|
|
9
9
|
module Luciq
|
|
10
10
|
module API
|
|
11
11
|
class Client
|
|
12
|
-
SYMBOLS_FILES_PATH = '/api/sdk/v3/symbols_files'
|
|
13
|
-
SO_FILES_PATH = '/api/web/public/so_files'
|
|
14
|
-
FLUTTER_IOS_SYMBOLS_PATH = '/api/web/public/flutter-symbol-files/ios'
|
|
15
|
-
FLUTTER_ANDROID_SYMBOLS_PATH = '/api/web/public/flutter-symbol-files/android'
|
|
16
|
-
|
|
17
12
|
def initialize
|
|
18
13
|
@token = Config.load_token
|
|
19
14
|
@base_url = Config.load_base_url
|
|
20
15
|
end
|
|
21
16
|
|
|
22
17
|
def whoami
|
|
23
|
-
uri = build_uri('/api/
|
|
18
|
+
uri = build_uri('/api/cli/whoami')
|
|
24
19
|
request = Net::HTTP::Get.new(uri)
|
|
25
20
|
apply_headers(request)
|
|
26
21
|
execute(uri, request)
|
|
@@ -37,145 +32,17 @@ module Luciq
|
|
|
37
32
|
execute(uri, request)
|
|
38
33
|
end
|
|
39
34
|
|
|
40
|
-
def
|
|
41
|
-
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def upload_android_mapping(file_path:, app_token:, version_code:, version_name:)
|
|
45
|
-
upload_mapping(
|
|
46
|
-
file_path: file_path, app_token: app_token,
|
|
47
|
-
version_code: version_code, version_name: version_name
|
|
48
|
-
)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def upload_android_ndk(file_path:, app_token:, app_version:, arch:)
|
|
52
|
-
upload_so_file(file_path: file_path, app_token: app_token, app_version: app_version, arch: arch)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def upload_react_native_ios_dsym(file_path:, app_token:)
|
|
56
|
-
upload_dsym(file_path: file_path, app_token: app_token)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def upload_react_native_ios_sourcemap(file_path:, app_token:, app_version:)
|
|
60
|
-
upload_react_native_sourcemap(
|
|
61
|
-
file_path: file_path, app_token: app_token, os: 'ios', app_version: app_version
|
|
62
|
-
)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def upload_react_native_android_mapping(file_path:, app_token:, version_code:, version_name:)
|
|
66
|
-
upload_mapping(
|
|
67
|
-
file_path: file_path, app_token: app_token,
|
|
68
|
-
version_code: version_code, version_name: version_name
|
|
69
|
-
)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def upload_react_native_android_sourcemap(file_path:, app_token:, app_version:)
|
|
73
|
-
upload_react_native_sourcemap(
|
|
74
|
-
file_path: file_path, app_token: app_token, os: 'android', app_version: app_version
|
|
75
|
-
)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def upload_react_native_ndk(file_path:, app_token:, app_version:, arch:)
|
|
79
|
-
upload_so_file(file_path: file_path, app_token: app_token, app_version: app_version, arch: arch)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def upload_flutter_ios_dsym(file_path:, app_token:)
|
|
83
|
-
upload_dsym(file_path: file_path, app_token: app_token)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def upload_flutter_ios_sourcemap(file_path:, app_token:, version_name:, version_code:)
|
|
87
|
-
upload_flutter_symbols(
|
|
88
|
-
FLUTTER_IOS_SYMBOLS_PATH,
|
|
89
|
-
file_path: file_path, app_token: app_token,
|
|
90
|
-
version_name: version_name, version_code: version_code
|
|
91
|
-
)
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def upload_flutter_android_mapping(file_path:, app_token:, version_code:, version_name:)
|
|
95
|
-
upload_mapping(
|
|
96
|
-
file_path: file_path, app_token: app_token,
|
|
97
|
-
version_code: version_code, version_name: version_name
|
|
98
|
-
)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def upload_flutter_android_sourcemap(file_path:, app_token:, version_name:, version_code:)
|
|
102
|
-
upload_flutter_symbols(
|
|
103
|
-
FLUTTER_ANDROID_SYMBOLS_PATH,
|
|
104
|
-
file_path: file_path, app_token: app_token,
|
|
105
|
-
version_name: version_name, version_code: version_code
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def upload_flutter_ndk(file_path:, app_token:, app_version:, arch:)
|
|
110
|
-
upload_so_file(file_path: file_path, app_token: app_token, app_version: app_version, arch: arch)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
private
|
|
114
|
-
|
|
115
|
-
def upload_dsym(file_path:, app_token:)
|
|
116
|
-
uri = build_uri(SYMBOLS_FILES_PATH)
|
|
117
|
-
File.open(file_path, 'rb') do |file|
|
|
118
|
-
params = {
|
|
119
|
-
'symbols_file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)),
|
|
120
|
-
'application_token' => app_token,
|
|
121
|
-
'os' => 'ios'
|
|
122
|
-
}
|
|
123
|
-
post_multipart(uri, params)
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def upload_mapping(file_path:, app_token:, version_code:, version_name:)
|
|
128
|
-
uri = build_uri(SYMBOLS_FILES_PATH)
|
|
129
|
-
File.open(file_path, 'rb') do |file|
|
|
130
|
-
params = {
|
|
131
|
-
'symbols_file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)),
|
|
132
|
-
'application_token' => app_token,
|
|
133
|
-
'os' => 'android',
|
|
134
|
-
'app_version' => { code: version_code, name: version_name }.to_json
|
|
135
|
-
}
|
|
136
|
-
post_multipart(uri, params)
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def upload_react_native_sourcemap(file_path:, app_token:, os:, app_version:)
|
|
141
|
-
uri = build_uri(SYMBOLS_FILES_PATH)
|
|
35
|
+
def upload(command, file_path, fields = {})
|
|
36
|
+
uri = build_uri("/api/cli/uploads/#{command}")
|
|
142
37
|
File.open(file_path, 'rb') do |file|
|
|
143
38
|
params = {
|
|
144
|
-
'
|
|
145
|
-
|
|
146
|
-
'platform' => 'react_native',
|
|
147
|
-
'os' => os,
|
|
148
|
-
'app_version' => app_version.to_json
|
|
149
|
-
}
|
|
39
|
+
'file' => UploadIO.new(file, content_type_for(file_path), File.basename(file_path))
|
|
40
|
+
}.merge(fields)
|
|
150
41
|
post_multipart(uri, params)
|
|
151
42
|
end
|
|
152
43
|
end
|
|
153
44
|
|
|
154
|
-
|
|
155
|
-
uri = build_uri(SO_FILES_PATH)
|
|
156
|
-
File.open(file_path, 'rb') do |file|
|
|
157
|
-
params = {
|
|
158
|
-
'so_file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)),
|
|
159
|
-
'application_token' => app_token,
|
|
160
|
-
'app_version' => app_version,
|
|
161
|
-
'arch' => arch
|
|
162
|
-
}
|
|
163
|
-
post_multipart(uri, params)
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def upload_flutter_symbols(path, file_path:, app_token:, version_name:, version_code:)
|
|
168
|
-
uri = build_uri(path)
|
|
169
|
-
File.open(file_path, 'rb') do |file|
|
|
170
|
-
params = {
|
|
171
|
-
'file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)),
|
|
172
|
-
'application_token' => app_token,
|
|
173
|
-
'app_version_name' => version_name,
|
|
174
|
-
'app_version_code' => version_code
|
|
175
|
-
}
|
|
176
|
-
post_multipart(uri, params)
|
|
177
|
-
end
|
|
178
|
-
end
|
|
45
|
+
private
|
|
179
46
|
|
|
180
47
|
def post_multipart(uri, params)
|
|
181
48
|
request = Net::HTTP::Post::Multipart.new(uri.path, params)
|
|
@@ -183,8 +50,12 @@ module Luciq
|
|
|
183
50
|
execute(uri, request)
|
|
184
51
|
end
|
|
185
52
|
|
|
186
|
-
def
|
|
187
|
-
file_path.downcase
|
|
53
|
+
def content_type_for(file_path)
|
|
54
|
+
case File.extname(file_path).downcase
|
|
55
|
+
when '.json' then 'application/json'
|
|
56
|
+
when '.txt' then 'text/plain'
|
|
57
|
+
else 'application/octet-stream'
|
|
58
|
+
end
|
|
188
59
|
end
|
|
189
60
|
|
|
190
61
|
def build_uri(path)
|
data/lib/luciq/cli.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Luciq
|
|
|
15
15
|
desc 'login', 'Authenticate with Luciq'
|
|
16
16
|
long_desc <<~DESC
|
|
17
17
|
Authenticate with Luciq using a CLI token.
|
|
18
|
-
Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/cli
|
|
18
|
+
Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/luciq-cli
|
|
19
19
|
The token will be saved in ~/.luciqrc
|
|
20
20
|
DESC
|
|
21
21
|
option :auth_token, type: :string, desc: 'CLI authentication token'
|
data/lib/luciq/commands/auth.rb
CHANGED
|
@@ -16,7 +16,7 @@ module Luciq
|
|
|
16
16
|
unless token
|
|
17
17
|
puts 'Login to Luciq'
|
|
18
18
|
puts '=' * 40
|
|
19
|
-
puts 'Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/cli'
|
|
19
|
+
puts 'Generate a CLI token from your Luciq dashboard: https://dashboard.luciq.ai/company/luciq-cli'
|
|
20
20
|
puts
|
|
21
21
|
puts "Note: For self-hosted clusters, replace 'dashboard' with your cluster name."
|
|
22
22
|
puts
|
|
@@ -101,6 +101,9 @@ module Luciq
|
|
|
101
101
|
if action && (@options[:status] || @options[:priority])
|
|
102
102
|
raise 'Duplicate marking cannot be combined with --status/--priority'
|
|
103
103
|
end
|
|
104
|
+
if @options[:clear_tags] && @options[:tag_action]
|
|
105
|
+
raise '--clear-tags cannot be combined with --tag-action (--clear-tags already replaces with an empty set)'
|
|
106
|
+
end
|
|
104
107
|
|
|
105
108
|
changes = {
|
|
106
109
|
status_id: map_one(BUG_STATUS_IDS, @options[:status]),
|
|
@@ -109,9 +112,19 @@ module Luciq
|
|
|
109
112
|
action: action,
|
|
110
113
|
original_bug_number: @options[:duplicate_of]
|
|
111
114
|
}.compact
|
|
112
|
-
return changes unless changes.empty?
|
|
113
115
|
|
|
114
|
-
|
|
116
|
+
if changes.empty?
|
|
117
|
+
raise 'Provide at least one change (--status/--priority/--tags/--clear-tags/--duplicate-of/--action)'
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# tag_action only modifies how --tags is applied; on its own it is not a change
|
|
121
|
+
if @options[:clear_tags]
|
|
122
|
+
changes[:tag_action] = 'replace'
|
|
123
|
+
elsif @options[:tag_action]
|
|
124
|
+
changes[:tag_action] = @options[:tag_action]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
changes
|
|
115
128
|
end
|
|
116
129
|
|
|
117
130
|
def bug_duplicate_action
|
|
@@ -13,144 +13,68 @@ module Luciq
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def ios_dsym(file_path)
|
|
16
|
-
run_upload(file_path, 'iOS dSYM file', format: :zip)
|
|
17
|
-
@client.upload_ios_dsym(file_path: file_path, app_token: @options[:app_token])
|
|
18
|
-
end
|
|
16
|
+
run_upload('ios-dsym', file_path, 'iOS dSYM file', format: :zip)
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def android_mapping(file_path)
|
|
22
|
-
run_upload(file_path, 'Android mapping file')
|
|
23
|
-
@client.upload_android_mapping(
|
|
24
|
-
file_path: file_path,
|
|
25
|
-
app_token: @options[:app_token],
|
|
26
|
-
version_code: @options[:version_code],
|
|
27
|
-
version_name: @options[:version_name]
|
|
28
|
-
)
|
|
29
|
-
end
|
|
20
|
+
run_upload('android-mapping', file_path, 'Android mapping file')
|
|
30
21
|
end
|
|
31
22
|
|
|
32
23
|
def android_ndk(file_path)
|
|
33
|
-
run_upload(file_path, 'Android NDK .so files', format: :zip)
|
|
34
|
-
validate_arch!
|
|
35
|
-
@client.upload_android_ndk(
|
|
36
|
-
file_path: file_path,
|
|
37
|
-
app_token: @options[:app_token],
|
|
38
|
-
app_version: @options[:version_name],
|
|
39
|
-
arch: @options[:arch]
|
|
40
|
-
)
|
|
41
|
-
end
|
|
24
|
+
run_upload('android-ndk', file_path, 'Android NDK .so files', format: :zip, arch: true)
|
|
42
25
|
end
|
|
43
26
|
|
|
44
27
|
def react_native_ios_dsym(file_path)
|
|
45
|
-
run_upload(file_path, 'React Native iOS dSYM', format: :zip)
|
|
46
|
-
@client.upload_react_native_ios_dsym(file_path: file_path, app_token: @options[:app_token])
|
|
47
|
-
end
|
|
28
|
+
run_upload('react-native-ios-dsym', file_path, 'React Native iOS dSYM', format: :zip)
|
|
48
29
|
end
|
|
49
30
|
|
|
50
31
|
def react_native_ios_sourcemap(file_path)
|
|
51
|
-
run_upload(file_path, 'React Native iOS source map', format: :sourcemap)
|
|
52
|
-
@client.upload_react_native_ios_sourcemap(
|
|
53
|
-
file_path: file_path,
|
|
54
|
-
app_token: @options[:app_token],
|
|
55
|
-
app_version: build_app_version
|
|
56
|
-
)
|
|
57
|
-
end
|
|
32
|
+
run_upload('react-native-ios-sourcemap', file_path, 'React Native iOS source map', format: :sourcemap)
|
|
58
33
|
end
|
|
59
34
|
|
|
60
35
|
def react_native_android_mapping(file_path)
|
|
61
|
-
run_upload(file_path, 'React Native Android mapping file')
|
|
62
|
-
@client.upload_react_native_android_mapping(
|
|
63
|
-
file_path: file_path,
|
|
64
|
-
app_token: @options[:app_token],
|
|
65
|
-
version_code: @options[:version_code],
|
|
66
|
-
version_name: @options[:version_name]
|
|
67
|
-
)
|
|
68
|
-
end
|
|
36
|
+
run_upload('react-native-android-mapping', file_path, 'React Native Android mapping file')
|
|
69
37
|
end
|
|
70
38
|
|
|
71
39
|
def react_native_android_sourcemap(file_path)
|
|
72
|
-
run_upload(file_path, 'React Native Android source map', format: :sourcemap)
|
|
73
|
-
@client.upload_react_native_android_sourcemap(
|
|
74
|
-
file_path: file_path,
|
|
75
|
-
app_token: @options[:app_token],
|
|
76
|
-
app_version: build_app_version
|
|
77
|
-
)
|
|
78
|
-
end
|
|
40
|
+
run_upload('react-native-android-sourcemap', file_path, 'React Native Android source map', format: :sourcemap)
|
|
79
41
|
end
|
|
80
42
|
|
|
81
43
|
def react_native_ndk(file_path)
|
|
82
|
-
run_upload(file_path, 'React Native NDK .so files', format: :zip)
|
|
83
|
-
validate_arch!
|
|
84
|
-
@client.upload_react_native_ndk(
|
|
85
|
-
file_path: file_path,
|
|
86
|
-
app_token: @options[:app_token],
|
|
87
|
-
app_version: @options[:version_name],
|
|
88
|
-
arch: @options[:arch]
|
|
89
|
-
)
|
|
90
|
-
end
|
|
44
|
+
run_upload('react-native-ndk', file_path, 'React Native NDK .so files', format: :zip, arch: true)
|
|
91
45
|
end
|
|
92
46
|
|
|
93
47
|
def flutter_ios_dsym(file_path)
|
|
94
|
-
run_upload(file_path, 'Flutter iOS dSYM', format: :zip)
|
|
95
|
-
@client.upload_flutter_ios_dsym(file_path: file_path, app_token: @options[:app_token])
|
|
96
|
-
end
|
|
48
|
+
run_upload('flutter-ios-dsym', file_path, 'Flutter iOS dSYM', format: :zip)
|
|
97
49
|
end
|
|
98
50
|
|
|
99
51
|
def flutter_ios_sourcemap(file_path)
|
|
100
|
-
run_upload(file_path, 'Flutter iOS Dart sourcemap', format: :zip)
|
|
101
|
-
@client.upload_flutter_ios_sourcemap(
|
|
102
|
-
file_path: file_path,
|
|
103
|
-
app_token: @options[:app_token],
|
|
104
|
-
version_name: @options[:version_name],
|
|
105
|
-
version_code: @options[:version_code]
|
|
106
|
-
)
|
|
107
|
-
end
|
|
52
|
+
run_upload('flutter-ios-sourcemap', file_path, 'Flutter iOS Dart sourcemap', format: :zip)
|
|
108
53
|
end
|
|
109
54
|
|
|
110
55
|
def flutter_android_mapping(file_path)
|
|
111
|
-
run_upload(file_path, 'Flutter Android mapping file')
|
|
112
|
-
@client.upload_flutter_android_mapping(
|
|
113
|
-
file_path: file_path,
|
|
114
|
-
app_token: @options[:app_token],
|
|
115
|
-
version_code: @options[:version_code],
|
|
116
|
-
version_name: @options[:version_name]
|
|
117
|
-
)
|
|
118
|
-
end
|
|
56
|
+
run_upload('flutter-android-mapping', file_path, 'Flutter Android mapping file')
|
|
119
57
|
end
|
|
120
58
|
|
|
121
59
|
def flutter_android_sourcemap(file_path)
|
|
122
|
-
run_upload(file_path, 'Flutter Android Dart sourcemap', format: :zip)
|
|
123
|
-
@client.upload_flutter_android_sourcemap(
|
|
124
|
-
file_path: file_path,
|
|
125
|
-
app_token: @options[:app_token],
|
|
126
|
-
version_name: @options[:version_name],
|
|
127
|
-
version_code: @options[:version_code]
|
|
128
|
-
)
|
|
129
|
-
end
|
|
60
|
+
run_upload('flutter-android-sourcemap', file_path, 'Flutter Android Dart sourcemap', format: :zip)
|
|
130
61
|
end
|
|
131
62
|
|
|
132
63
|
def flutter_ndk(file_path)
|
|
133
|
-
run_upload(file_path, 'Flutter NDK .so files', format: :zip)
|
|
134
|
-
validate_arch!
|
|
135
|
-
@client.upload_flutter_ndk(
|
|
136
|
-
file_path: file_path,
|
|
137
|
-
app_token: @options[:app_token],
|
|
138
|
-
app_version: @options[:version_name],
|
|
139
|
-
arch: @options[:arch]
|
|
140
|
-
)
|
|
141
|
-
end
|
|
64
|
+
run_upload('flutter-ndk', file_path, 'Flutter NDK .so files', format: :zip, arch: true)
|
|
142
65
|
end
|
|
143
66
|
|
|
144
67
|
private
|
|
145
68
|
|
|
146
|
-
def run_upload(file_path, label, format: nil)
|
|
69
|
+
def run_upload(command, file_path, label, format: nil, arch: false)
|
|
147
70
|
validate_file!(file_path)
|
|
148
71
|
validate_format!(file_path, format)
|
|
72
|
+
validate_arch! if arch
|
|
149
73
|
|
|
150
74
|
puts "Uploading #{label}: #{File.basename(file_path)}"
|
|
151
75
|
puts
|
|
152
76
|
|
|
153
|
-
|
|
77
|
+
@client.upload(command, file_path, @options)
|
|
154
78
|
|
|
155
79
|
puts "✓ #{label} uploaded successfully!"
|
|
156
80
|
rescue StandardError => e
|
|
@@ -198,14 +122,6 @@ module Luciq
|
|
|
198
122
|
puts " Allowed values: #{ALLOWED_ARCHITECTURES.join(', ')}"
|
|
199
123
|
exit 1
|
|
200
124
|
end
|
|
201
|
-
|
|
202
|
-
def build_app_version
|
|
203
|
-
{
|
|
204
|
-
code: @options[:version_code],
|
|
205
|
-
name: @options[:version_name],
|
|
206
|
-
codepush: @options[:codepush]
|
|
207
|
-
}.compact
|
|
208
|
-
end
|
|
209
125
|
end
|
|
210
126
|
end
|
|
211
127
|
end
|
data/lib/luciq/query_cli.rb
CHANGED
|
@@ -199,6 +199,10 @@ module Luciq
|
|
|
199
199
|
Update a bug. Provide at least one change: --status/--priority/--tags/--clear-tags
|
|
200
200
|
change the bug; duplicate marking is a separate action and can't be combined with them.
|
|
201
201
|
|
|
202
|
+
Tags: --tags appends to the existing tags by default. Use --tag-action to change
|
|
203
|
+
that: replace sets --tags as the full list (removing others); remove deletes --tags
|
|
204
|
+
and keeps the rest. --clear-tags removes all tags.
|
|
205
|
+
|
|
202
206
|
Mark a duplicate: --duplicate-of <master-number> (implies --action mark_as_duplicate).
|
|
203
207
|
Detach a duplicate: --action unmark_as_duplicate.
|
|
204
208
|
DESC
|
|
@@ -206,8 +210,10 @@ module Luciq
|
|
|
206
210
|
option :number, type: :numeric, required: true, desc: 'Bug number'
|
|
207
211
|
option :status, type: :string, enum: %w[new closed in_progress], desc: 'New status'
|
|
208
212
|
option :priority, type: :string, enum: %w[na trivial minor major blocker], desc: 'New priority'
|
|
209
|
-
option :tags, type: :array, desc: 'Tags to
|
|
210
|
-
option :
|
|
213
|
+
option :tags, type: :array, desc: 'Tags to apply (see --tag-action; appends to existing tags by default)'
|
|
214
|
+
option :tag_action, type: :string, enum: %w[replace append remove],
|
|
215
|
+
desc: 'How --tags is applied: append (default, keep existing), replace, remove'
|
|
216
|
+
option :clear_tags, type: :boolean, desc: 'Remove all tags (cannot be combined with --tag-action)'
|
|
211
217
|
option :duplicate_of, type: :numeric, desc: 'Master bug number (marks this a duplicate)'
|
|
212
218
|
option :action, type: :string, enum: %w[mark_as_duplicate unmark_as_duplicate],
|
|
213
219
|
desc: 'Duplicate action (defaults to mark_as_duplicate with --duplicate-of)'
|
data/lib/luciq/upload_cli.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'thor'
|
|
4
4
|
require 'luciq/commands/upload'
|
|
5
|
+
require 'luciq/query_cli'
|
|
5
6
|
|
|
6
7
|
module Luciq
|
|
7
8
|
class UploadCLI < Thor
|
|
@@ -12,9 +13,9 @@ module Luciq
|
|
|
12
13
|
Upload iOS dSYM files to Luciq for crash symbolication.
|
|
13
14
|
File format: .zip containing dSYM files
|
|
14
15
|
Example:
|
|
15
|
-
luciq upload ios-dsym MyApp.dSYM.zip --app
|
|
16
|
+
luciq upload ios-dsym MyApp.dSYM.zip --slug my-app --mode production
|
|
16
17
|
DESC
|
|
17
|
-
|
|
18
|
+
QueryOptions.app(self)
|
|
18
19
|
def ios_dsym(file)
|
|
19
20
|
Commands::Upload.new(options).ios_dsym(file)
|
|
20
21
|
end
|
|
@@ -24,9 +25,9 @@ module Luciq
|
|
|
24
25
|
Upload Android Proguard/R8 mapping files to Luciq for crash deobfuscation.
|
|
25
26
|
File format: mapping.txt
|
|
26
27
|
Example:
|
|
27
|
-
luciq upload android-mapping mapping.txt --app
|
|
28
|
+
luciq upload android-mapping mapping.txt --slug my-app --mode production --version-name 1.0.0 --version-code 1
|
|
28
29
|
DESC
|
|
29
|
-
|
|
30
|
+
QueryOptions.app(self)
|
|
30
31
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
31
32
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
32
33
|
def android_mapping(file)
|
|
@@ -38,9 +39,9 @@ module Luciq
|
|
|
38
39
|
Upload Android NDK shared object (.so) files to Luciq for native crash symbolication.
|
|
39
40
|
File format: .zip containing the .so files
|
|
40
41
|
Example:
|
|
41
|
-
luciq upload android-ndk so-files.zip --app
|
|
42
|
+
luciq upload android-ndk so-files.zip --slug my-app --mode production --version-name 1.0.0 --arch arm64-v8a
|
|
42
43
|
DESC
|
|
43
|
-
|
|
44
|
+
QueryOptions.app(self)
|
|
44
45
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
45
46
|
option :arch, type: :string, required: true, enum: ARCHITECTURES, desc: 'CPU architecture'
|
|
46
47
|
def android_ndk(file)
|
|
@@ -52,9 +53,9 @@ module Luciq
|
|
|
52
53
|
Upload React Native iOS dSYM files to Luciq for native crash symbolication.
|
|
53
54
|
File format: .zip containing dSYM files
|
|
54
55
|
Example:
|
|
55
|
-
luciq upload react-native-ios-dsym dsyms.zip --app
|
|
56
|
+
luciq upload react-native-ios-dsym dsyms.zip --slug my-app --mode production
|
|
56
57
|
DESC
|
|
57
|
-
|
|
58
|
+
QueryOptions.app(self)
|
|
58
59
|
def react_native_ios_dsym(file)
|
|
59
60
|
Commands::Upload.new(options).react_native_ios_dsym(file)
|
|
60
61
|
end
|
|
@@ -64,9 +65,9 @@ module Luciq
|
|
|
64
65
|
Upload React Native iOS JavaScript source maps to Luciq for crash symbolication.
|
|
65
66
|
File format: .json or .txt source map
|
|
66
67
|
Example:
|
|
67
|
-
luciq upload react-native-ios-sourcemap ios-sourcemap.json --app
|
|
68
|
+
luciq upload react-native-ios-sourcemap ios-sourcemap.json --slug my-app --mode production --version-code 1 --version-name 1.0.0
|
|
68
69
|
DESC
|
|
69
|
-
|
|
70
|
+
QueryOptions.app(self)
|
|
70
71
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
71
72
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
72
73
|
option :codepush, type: :string, desc: 'CodePush version label (e.g., v42)'
|
|
@@ -79,9 +80,9 @@ module Luciq
|
|
|
79
80
|
Upload React Native Android Proguard/R8 mapping files to Luciq for native crash deobfuscation.
|
|
80
81
|
File format: mapping.txt
|
|
81
82
|
Example:
|
|
82
|
-
luciq upload react-native-android-mapping mapping.txt --app
|
|
83
|
+
luciq upload react-native-android-mapping mapping.txt --slug my-app --mode production --version-code 1 --version-name 1.0.0
|
|
83
84
|
DESC
|
|
84
|
-
|
|
85
|
+
QueryOptions.app(self)
|
|
85
86
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
86
87
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
87
88
|
def react_native_android_mapping(file)
|
|
@@ -93,9 +94,9 @@ module Luciq
|
|
|
93
94
|
Upload React Native Android JavaScript source maps to Luciq for crash deobfuscation.
|
|
94
95
|
File format: .json or .txt source map
|
|
95
96
|
Example:
|
|
96
|
-
luciq upload react-native-android-sourcemap android-sourcemap.json --app
|
|
97
|
+
luciq upload react-native-android-sourcemap android-sourcemap.json --slug my-app --mode production --version-code 1 --version-name 1.0.0
|
|
97
98
|
DESC
|
|
98
|
-
|
|
99
|
+
QueryOptions.app(self)
|
|
99
100
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
100
101
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
101
102
|
option :codepush, type: :string, desc: 'CodePush version label (e.g., v42)'
|
|
@@ -108,9 +109,9 @@ module Luciq
|
|
|
108
109
|
Upload React Native NDK shared object (.so) files to Luciq for native crash symbolication.
|
|
109
110
|
File format: .zip containing the .so files
|
|
110
111
|
Example:
|
|
111
|
-
luciq upload react-native-ndk so-files.zip --app
|
|
112
|
+
luciq upload react-native-ndk so-files.zip --slug my-app --mode production --version-name 1.0.0 --arch arm64-v8a
|
|
112
113
|
DESC
|
|
113
|
-
|
|
114
|
+
QueryOptions.app(self)
|
|
114
115
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
115
116
|
option :arch, type: :string, required: true, enum: ARCHITECTURES, desc: 'CPU architecture'
|
|
116
117
|
def react_native_ndk(file)
|
|
@@ -122,9 +123,9 @@ module Luciq
|
|
|
122
123
|
Upload Flutter iOS dSYM files to Luciq for native crash symbolication.
|
|
123
124
|
File format: .zip containing dSYM files
|
|
124
125
|
Example:
|
|
125
|
-
luciq upload flutter-ios-dsym MyApp.dSYM.zip --app
|
|
126
|
+
luciq upload flutter-ios-dsym MyApp.dSYM.zip --slug my-app --mode production
|
|
126
127
|
DESC
|
|
127
|
-
|
|
128
|
+
QueryOptions.app(self)
|
|
128
129
|
def flutter_ios_dsym(file)
|
|
129
130
|
Commands::Upload.new(options).flutter_ios_dsym(file)
|
|
130
131
|
end
|
|
@@ -134,9 +135,9 @@ module Luciq
|
|
|
134
135
|
Upload Flutter iOS Dart sourcemap files to Luciq for crash symbolication.
|
|
135
136
|
File format: .zip containing Flutter debug symbols
|
|
136
137
|
Example:
|
|
137
|
-
luciq upload flutter-ios-sourcemap app.ios-arm64.symbols.zip --app
|
|
138
|
+
luciq upload flutter-ios-sourcemap app.ios-arm64.symbols.zip --slug my-app --mode production --version-name 1.0.0 --version-code 1
|
|
138
139
|
DESC
|
|
139
|
-
|
|
140
|
+
QueryOptions.app(self)
|
|
140
141
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
141
142
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
142
143
|
def flutter_ios_sourcemap(file)
|
|
@@ -148,9 +149,9 @@ module Luciq
|
|
|
148
149
|
Upload Flutter Android Proguard/R8 mapping files to Luciq for native crash deobfuscation.
|
|
149
150
|
File format: mapping.txt
|
|
150
151
|
Example:
|
|
151
|
-
luciq upload flutter-android-mapping mapping.txt --app
|
|
152
|
+
luciq upload flutter-android-mapping mapping.txt --slug my-app --mode production --version-code 1 --version-name 1.0.0
|
|
152
153
|
DESC
|
|
153
|
-
|
|
154
|
+
QueryOptions.app(self)
|
|
154
155
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
155
156
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
156
157
|
def flutter_android_mapping(file)
|
|
@@ -162,9 +163,9 @@ module Luciq
|
|
|
162
163
|
Upload Flutter Android Dart sourcemap files to Luciq for crash symbolication.
|
|
163
164
|
File format: .zip containing Flutter debug symbols
|
|
164
165
|
Example:
|
|
165
|
-
luciq upload flutter-android-sourcemap app.android-arm64.symbols.zip --app
|
|
166
|
+
luciq upload flutter-android-sourcemap app.android-arm64.symbols.zip --slug my-app --mode production --version-name 1.0.0 --version-code 1
|
|
166
167
|
DESC
|
|
167
|
-
|
|
168
|
+
QueryOptions.app(self)
|
|
168
169
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
169
170
|
option :version_code, type: :string, required: true, desc: 'App version code (e.g., 1)'
|
|
170
171
|
def flutter_android_sourcemap(file)
|
|
@@ -176,9 +177,9 @@ module Luciq
|
|
|
176
177
|
Upload Flutter NDK shared object (.so) files to Luciq for native crash symbolication.
|
|
177
178
|
File format: .zip containing the .so files
|
|
178
179
|
Example:
|
|
179
|
-
luciq upload flutter-ndk so-files.zip --app
|
|
180
|
+
luciq upload flutter-ndk so-files.zip --slug my-app --mode production --version-name 1.0.0 --arch arm64-v8a
|
|
180
181
|
DESC
|
|
181
|
-
|
|
182
|
+
QueryOptions.app(self)
|
|
182
183
|
option :version_name, type: :string, required: true, desc: 'App version name (e.g., 1.0.0)'
|
|
183
184
|
option :arch, type: :string, required: true, enum: ARCHITECTURES, desc: 'CPU architecture'
|
|
184
185
|
def flutter_ndk(file)
|
data/lib/luciq/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: luciq-cli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ahmed Hany
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-08-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: multipart-post
|
|
@@ -47,6 +47,7 @@ extensions: []
|
|
|
47
47
|
extra_rdoc_files: []
|
|
48
48
|
files:
|
|
49
49
|
- CHANGELOG.md
|
|
50
|
+
- LICENSE
|
|
50
51
|
- README.md
|
|
51
52
|
- bin/luciq
|
|
52
53
|
- lib/luciq/api/client.rb
|
|
@@ -59,13 +60,13 @@ files:
|
|
|
59
60
|
- lib/luciq/query_cli.rb
|
|
60
61
|
- lib/luciq/upload_cli.rb
|
|
61
62
|
- lib/luciq/version.rb
|
|
62
|
-
homepage: https://github.com/
|
|
63
|
+
homepage: https://github.com/luciqai/luciq-cli
|
|
63
64
|
licenses:
|
|
64
65
|
- MIT
|
|
65
66
|
metadata:
|
|
66
|
-
homepage_uri: https://github.com/
|
|
67
|
-
source_code_uri: https://github.com/
|
|
68
|
-
changelog_uri: https://github.com/
|
|
67
|
+
homepage_uri: https://github.com/luciqai/luciq-cli
|
|
68
|
+
source_code_uri: https://github.com/luciqai/luciq-cli
|
|
69
|
+
changelog_uri: https://github.com/luciqai/luciq-cli/blob/main/CHANGELOG.md
|
|
69
70
|
rubygems_mfa_required: 'true'
|
|
70
71
|
post_install_message:
|
|
71
72
|
rdoc_options: []
|