youtrack-cli 0.3.3__tar.gz → 0.3.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.
Files changed (94) hide show
  1. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/PKG-INFO +1 -1
  2. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/admin.rst +9 -0
  3. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/pyproject.toml +1 -1
  4. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_admin.py +32 -0
  5. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/uv.lock +1 -1
  6. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/admin.py +61 -18
  7. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.claude/settings.local.json +0 -0
  8. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.github/dependabot.yml +0 -0
  9. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.github/workflows/ci.yml +0 -0
  10. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.github/workflows/release.yml +0 -0
  11. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.gitignore +0 -0
  12. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.pre-commit-config.yaml +0 -0
  13. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/.readthedocs.yaml +0 -0
  14. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/CLAUDE.md +0 -0
  15. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/PUBLISHING.md +0 -0
  16. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/README.md +0 -0
  17. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/Makefile +0 -0
  18. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/api/index.rst +0 -0
  19. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/changelog.rst +0 -0
  20. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/command-aliases.rst +0 -0
  21. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/articles.rst +0 -0
  22. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/auth.rst +0 -0
  23. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/boards.rst +0 -0
  24. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/config.rst +0 -0
  25. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/index.rst +0 -0
  26. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/issues.rst +0 -0
  27. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/projects.rst +0 -0
  28. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/reports.rst +0 -0
  29. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/time.rst +0 -0
  30. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/commands/users.rst +0 -0
  31. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/conf.py +0 -0
  32. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/configuration.rst +0 -0
  33. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/development.rst +0 -0
  34. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/index.rst +0 -0
  35. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/installation.rst +0 -0
  36. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/learning-path.rst +0 -0
  37. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/logging.rst +0 -0
  38. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/performance.md +0 -0
  39. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/progress-indicators.md +0 -0
  40. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/quickstart.rst +0 -0
  41. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/requirements.txt +0 -0
  42. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/security.rst +0 -0
  43. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/troubleshooting.rst +0 -0
  44. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/workflows.rst +0 -0
  45. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/docs/youtrack-concepts.rst +0 -0
  46. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/justfile +0 -0
  47. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/package-lock.json +0 -0
  48. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/package.json +0 -0
  49. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/__init__.py +0 -0
  50. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/conftest.py +0 -0
  51. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_articles.py +0 -0
  52. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_auth.py +0 -0
  53. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_boards.py +0 -0
  54. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_config.py +0 -0
  55. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_issues.py +0 -0
  56. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_logging.py +0 -0
  57. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_main.py +0 -0
  58. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_projects.py +0 -0
  59. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_reports.py +0 -0
  60. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_security.py +0 -0
  61. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_time.py +0 -0
  62. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tests/test_users.py +0 -0
  63. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/tox.ini +0 -0
  64. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/__init__.py +0 -0
  65. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/articles.py +0 -0
  66. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/auth.py +0 -0
  67. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/boards.py +0 -0
  68. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/cache.py +0 -0
  69. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/cli_utils/__init__.py +0 -0
  70. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/cli_utils/aliases.py +0 -0
  71. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/client.py +0 -0
  72. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/__init__.py +0 -0
  73. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/articles.py +0 -0
  74. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/boards.py +0 -0
  75. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/common.py +0 -0
  76. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/issues.py +0 -0
  77. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/projects.py +0 -0
  78. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/time_tracking.py +0 -0
  79. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/commands/users.py +0 -0
  80. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/common.py +0 -0
  81. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/config.py +0 -0
  82. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/exceptions.py +0 -0
  83. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/issues.py +0 -0
  84. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/logging.py +0 -0
  85. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/main.py +0 -0
  86. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/performance.py +0 -0
  87. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/progress.py +0 -0
  88. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/projects.py +0 -0
  89. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/py.typed +0 -0
  90. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/reports.py +0 -0
  91. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/security.py +0 -0
  92. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/time.py +0 -0
  93. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/users.py +0 -0
  94. {youtrack_cli-0.3.3 → youtrack_cli-0.3.4}/youtrack_cli/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: youtrack-cli
3
- Version: 0.3.3
3
+ Version: 0.3.4
4
4
  Summary: YouTrack CLI - Command line interface for JetBrains YouTrack issue tracking system
5
5
  Project-URL: Homepage, https://github.com/ryan-murphy/yt-cli
6
6
  Project-URL: Documentation, https://yt-cli.readthedocs.io/
@@ -552,6 +552,15 @@ Common Issues and Solutions
552
552
  **Health Check Issues**
553
553
  Review system logs and resource availability.
554
554
 
555
+ **Health Check 404 Errors**
556
+ If the health check command returns a 404 error, this may indicate:
557
+
558
+ * Your YouTrack version doesn't support the system settings endpoint
559
+ * The API endpoint has changed in your YouTrack version
560
+ * Your YouTrack instance has a different API configuration
561
+
562
+ The command will automatically try fallback endpoints and provide specific guidance based on the error type.
563
+
555
564
  System Diagnostics
556
565
  ~~~~~~~~~~~~~~~~~
557
566
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "youtrack-cli"
3
- version = "0.3.3"
3
+ version = "0.3.4"
4
4
  description = "YouTrack CLI - Command line interface for JetBrains YouTrack issue tracking system"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9, <3.14"
@@ -175,6 +175,38 @@ class TestAdminManager:
175
175
  assert result["status"] == "success"
176
176
  assert result["data"] == mock_health
177
177
 
178
+ @pytest.mark.asyncio
179
+ async def test_get_system_health_404_error(self, admin_manager, auth_manager):
180
+ """Test system health check with 404 error on all endpoints."""
181
+ with patch("httpx.AsyncClient") as mock_client:
182
+ mock_response = Mock()
183
+ mock_response.status_code = 404
184
+ mock_request = Mock()
185
+ http_error = httpx.HTTPStatusError("Not Found", request=mock_request, response=mock_response)
186
+ mock_client.return_value.__aenter__.return_value.get.side_effect = http_error
187
+
188
+ result = await admin_manager.get_system_health()
189
+
190
+ assert result["status"] == "error"
191
+ assert "System health endpoint not found (404)" in result["message"]
192
+ assert "YouTrack version doesn't support this endpoint" in result["message"]
193
+
194
+ @pytest.mark.asyncio
195
+ async def test_get_system_health_403_error(self, admin_manager, auth_manager):
196
+ """Test system health check with 403 permission error."""
197
+ with patch("httpx.AsyncClient") as mock_client:
198
+ mock_response = Mock()
199
+ mock_response.status_code = 403
200
+ mock_request = Mock()
201
+ http_error = httpx.HTTPStatusError("Forbidden", request=mock_request, response=mock_response)
202
+ mock_client.return_value.__aenter__.return_value.get.side_effect = http_error
203
+
204
+ result = await admin_manager.get_system_health()
205
+
206
+ assert result["status"] == "error"
207
+ assert "Insufficient permissions for health check" in result["message"]
208
+ assert "Low-level Admin Read" in result["message"]
209
+
178
210
  @pytest.mark.asyncio
179
211
  async def test_clear_caches_success(self, admin_manager, auth_manager):
180
212
  """Test successful cache clearing."""
@@ -1751,7 +1751,7 @@ wheels = [
1751
1751
 
1752
1752
  [[package]]
1753
1753
  name = "youtrack-cli"
1754
- version = "0.3.3"
1754
+ version = "0.3.4"
1755
1755
  source = { editable = "." }
1756
1756
  dependencies = [
1757
1757
  { name = "click" },
@@ -153,6 +153,7 @@ class AdminManager:
153
153
  response = await client.get(
154
154
  f"{credentials.base_url.rstrip('/')}/api/admin/globalSettings/license",
155
155
  headers=headers,
156
+ params={"fields": "id,username,license,error"},
156
157
  timeout=10.0,
157
158
  )
158
159
  response.raise_for_status()
@@ -167,6 +168,14 @@ class AdminManager:
167
168
  "status": "error",
168
169
  "message": "Insufficient permissions to view license.",
169
170
  }
171
+ elif e.response.status_code == 404:
172
+ return {
173
+ "status": "error",
174
+ "message": (
175
+ "License endpoint not found. This may indicate an "
176
+ "incompatible YouTrack version or configuration."
177
+ ),
178
+ }
170
179
  return {"status": "error", "message": f"HTTP error: {e}"}
171
180
  except Exception as e:
172
181
  return {"status": "error", "message": f"Unexpected error: {e}"}
@@ -231,28 +240,62 @@ class AdminManager:
231
240
  "Accept": "application/json",
232
241
  }
233
242
 
234
- async with httpx.AsyncClient() as client:
235
- try:
236
- response = await client.get(
237
- f"{credentials.base_url.rstrip('/')}/api/admin/globalSettings/systemSettings",
238
- headers=headers,
239
- timeout=10.0,
240
- )
241
- response.raise_for_status()
242
-
243
- health_info = response.json()
244
- return {"status": "success", "data": health_info}
243
+ # List of endpoints to try, in order of preference
244
+ endpoints = [
245
+ "/api/admin/globalSettings/systemSettings",
246
+ "/api/admin/globalSettings/systemSettings?fields=baseUrl,isApplicationReadOnly,maxUploadFileSize,maxExportItems",
247
+ ]
245
248
 
246
- except httpx.HTTPError as e:
247
- if hasattr(e, "response") and e.response is not None:
248
- if e.response.status_code == 403:
249
+ async with httpx.AsyncClient() as client:
250
+ for endpoint in endpoints:
251
+ try:
252
+ response = await client.get(
253
+ f"{credentials.base_url.rstrip('/')}{endpoint}",
254
+ headers=headers,
255
+ timeout=10.0,
256
+ )
257
+ response.raise_for_status()
258
+
259
+ health_info = response.json()
260
+ return {"status": "success", "data": health_info}
261
+
262
+ except httpx.HTTPStatusError as e:
263
+ if e.response.status_code == 404:
264
+ continue # Try next endpoint
265
+ elif e.response.status_code == 403:
249
266
  return {
250
267
  "status": "error",
251
- "message": "Insufficient permissions for health check.",
268
+ "message": "Insufficient permissions for health check. "
269
+ "Requires 'Low-level Admin Read' permission.",
252
270
  }
253
- return {"status": "error", "message": f"HTTP error: {e}"}
254
- except Exception as e:
255
- return {"status": "error", "message": f"Unexpected error: {e}"}
271
+ elif e.response.status_code == 401:
272
+ return {
273
+ "status": "error",
274
+ "message": "Authentication failed. Your token may have expired. Run 'yt auth login' again.",
275
+ }
276
+ else:
277
+ response_text = e.response.text if hasattr(e.response, "text") else str(e)
278
+ return {
279
+ "status": "error",
280
+ "message": f"HTTP {e.response.status_code}: {response_text}",
281
+ }
282
+ except httpx.RequestError as e:
283
+ return {
284
+ "status": "error",
285
+ "message": f"Network error: {e}. Check your YouTrack URL and network connection.",
286
+ }
287
+ except Exception as e:
288
+ return {"status": "error", "message": f"Unexpected error: {e}"}
289
+
290
+ # If all endpoints failed with 404
291
+ return {
292
+ "status": "error",
293
+ "message": "System health endpoint not found (404). This may indicate:\n"
294
+ "1. Your YouTrack version doesn't support this endpoint\n"
295
+ "2. The endpoint URL may have changed\n"
296
+ "3. Your YouTrack instance has a different API configuration\n"
297
+ "Please verify your YouTrack version and API access.",
298
+ }
256
299
 
257
300
  async def clear_caches(self) -> dict[str, Any]:
258
301
  """Clear system caches.
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