Skip to content

feat(downloader): report release download progress via listener#76

Merged
nixel2007 merged 14 commits into
masterfrom
claude/github-issue-31-review-g8hz79
Jul 8, 2026
Merged

feat(downloader): report release download progress via listener#76
nixel2007 merged 14 commits into
masterfrom
claude/github-issue-31-review-g8hz79

Conversation

@nixel2007

Copy link
Copy Markdown
Member

Что и зачем

Часть решения 1c-syntax/intellij-language-1c-bsl#31: при скачивании релиза BSL Language Server клиент (плагин IntelliJ) мог показать только бесконечный «крутящийся» индикатор, потому что загрузчик качал ассет через HttpResponse.BodyHandlers.ofFile(...) — без какой-либо обратной связи о ходе загрузки.

Изменения

  • Добавлен DownloadProgressListener — функциональный интерфейс с методом onProgress(bytesRead, totalBytes) (totalBytes == -1, если сервер не прислал Content-Length) и константой NONE.
  • download(...) теперь читает тело ответа потоком (BodyHandlers.ofInputStream) и копирует его в файл по блокам, вызывая слушателя после каждого блока; размер берётся из заголовка Content-Length.
  • Добавлена перегрузка downloadIfNeeded(channel, progressListener). Прежний downloadIfNeeded(channel) сохранён и делегирует новой версии с no-op слушателем — обратная совместимость полная.

Проверки

  • compileJava, test (включая два новых теста на copyToFile) и проверка лицензионных заголовков (license) проходят локально.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV


Generated by Claude Code

Stream the release asset in chunks and notify a DownloadProgressListener
with bytes read and total size, so clients can render a real progress bar
instead of an indefinite spinner. The existing downloadIfNeeded overload
keeps working via a no-op listener.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Добавлены клиент релизов GitHub, интерфейс прогресса скачивания и новый потоковый путь загрузки ассетов с таймаутом. Тесты обновлены под новый API и сценарии прогресса.

Changes

Прогресс скачивания BSL Language Server

Layer / File(s) Summary
Клиент релизов и конструктор
src/main/java/com/github/_1c_syntax/utils/downloader/GitHubReleaseClient.java, src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java, build.gradle.kts
Добавлен GitHubReleaseClient, обновлён конструктор BslLanguageServerDownloader, зафиксирован интервал проверки и добавлена тестовая зависимость Mockito.
Прогресс и выбор загрузки
src/main/java/com/github/_1c_syntax/utils/downloader/DownloadProgressListener.java, src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java
Введён DownloadProgressListener; downloadIfNeeded(channel) делегирует новой перегрузке с слушателем, а ветка обновления и проверка интервала используют DEFAULT_CHECK_INTERVAL.
Потоковая загрузка и копирование
src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java
downloadAndExtract(...) передаёт слушатель в download(...); загрузка выполняется через HttpClient и InputStream, а copyToFile(...) сообщает прогресс и закрывает поток безопасно.
Тесты загрузчика
src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java
Обновлены конструкторные вызовы и добавлены тесты для copyToFile(...), прогресса, скачивания, fallback-сценариев и хелперов для HTTP/архивов.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • 1c-syntax/utils#72: Базовая реализация BslLanguageServerDownloader, которую этот PR расширяет новым клиентом релизов, прогрессом и потоковой загрузкой.

Poem

Я скачиваю байт за байтом — шур-шур-шур,
Прогресс идёт, и файл растёт в тиши.
Релизы в путь зовёт GitHub-клиент,
А заяц слушает: «ещё, ещё, пиши!»
🐰

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Название точно отражает главное изменение: добавлен listener для прогресса скачивания релизов.
Description check ✅ Passed Описание соответствует изменениям и верно перечисляет listener, потоковое скачивание и перегрузку метода.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/github-issue-31-review-g8hz79

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java (1)

278-302: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Добавить отдельный таймаут на чтение тела ответа
request.timeout(DOWNLOAD_TIMEOUT) в JDK 21 ограничивает только ожидание до получения заголовков. С BodyHandlers.ofInputStream() тело читается уже в copyToFile, и input.read(...) может зависнуть без дедлайна при медленном/оборванном соединении. Нужен отдельный read-timeout или асинхронная загрузка с отменой.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java`
around lines 278 - 302, The download(String, Path, DownloadProgressListener)
flow only applies DOWNLOAD_TIMEOUT to waiting for response headers, so body
reads in copyToFile can still hang indefinitely. Add a separate read timeout for
the response body or switch the download path to an async/cancellable approach,
and update the download/copyToFile handling in BslLanguageServerDownloader so
the body transfer is also bounded by a deadline.
🧹 Nitpick comments (1)
src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java (1)

89-121: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Тесты не проверяют копирование по нескольким чанкам.

Оба payload'а (20 и 3 байта) меньше размера буфера copyToFile (16 КБ), поэтому цикл чтения выполняется только один раз, и onProgress вызывается лишь дважды (старт/финиш). Основная цель фичи — потоковое копирование по чанкам с промежуточными уведомлениями о прогрессе — этим тестом не покрыта.

Стоит добавить тест с payload больше 16 КБ, чтобы проверить, что onProgress вызывается несколько раз с монотонно возрастающим bytesRead.

♻️ Пример дополнительного теста
`@Test`
void copyToFileReportsProgressAcrossMultipleChunks(`@TempDir` Path installDir) throws IOException {
  var payload = new byte[20 * 1024]; // больше буфера 16 КБ
  new Random(42).nextBytes(payload);
  var destination = installDir.resolve("asset.bin");
  var progress = new ArrayList<long[]>();

  BslLanguageServerDownloader.copyToFile(
    new ByteArrayInputStream(payload),
    destination,
    payload.length,
    (bytesRead, totalBytes) -> progress.add(new long[]{bytesRead, totalBytes}));

  assertThat(Files.readAllBytes(destination)).isEqualTo(payload);
  assertThat(progress.size()).isGreaterThan(2);
  assertThat(progress.get(progress.size() - 1)).containsExactly(payload.length, payload.length);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java`
around lines 89 - 121, The current tests for
BslLanguageServerDownloader.copyToFile only use payloads smaller than the 16 KB
buffer, so they never exercise multi-chunk streaming or intermediate progress
updates. Add a new test alongside copyToFileWritesContentAndReportsProgress and
copyToFilePropagatesUnknownTotalSize that uses a payload larger than the buffer
and asserts onProgress is invoked more than twice with monotonically increasing
bytesRead, while still verifying the file contents and final progress callback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java`:
- Around line 304-317: In copyToFile, the initial progress callback is invoked
before the try-with-resources block, so a RuntimeException from
DownloadProgressListener.onProgress can leave the InputStream unclosed. Move the
first onProgress(0, totalBytes) call inside the try block (after opening source
as input) or otherwise ensure source is included in resource management before
any callback can throw. Keep the cleanup behavior consistent with the contract
of DownloadProgressListener and the copyToFile method.

---

Outside diff comments:
In
`@src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java`:
- Around line 278-302: The download(String, Path, DownloadProgressListener) flow
only applies DOWNLOAD_TIMEOUT to waiting for response headers, so body reads in
copyToFile can still hang indefinitely. Add a separate read timeout for the
response body or switch the download path to an async/cancellable approach, and
update the download/copyToFile handling in BslLanguageServerDownloader so the
body transfer is also bounded by a deadline.

---

Nitpick comments:
In
`@src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java`:
- Around line 89-121: The current tests for
BslLanguageServerDownloader.copyToFile only use payloads smaller than the 16 KB
buffer, so they never exercise multi-chunk streaming or intermediate progress
updates. Add a new test alongside copyToFileWritesContentAndReportsProgress and
copyToFilePropagatesUnknownTotalSize that uses a payload larger than the buffer
and asserts onProgress is invoked more than twice with monotonically increasing
bytesRead, while still verifying the file contents and final progress callback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c5ef0bf9-22ed-4366-9a01-0f0c6ced0884

📥 Commits

Reviewing files that changed from the base of the PR and between 68d88ce and 5846d20.

📒 Files selected for processing (3)
  • src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java
  • src/main/java/com/github/_1c_syntax/utils/downloader/DownloadProgressListener.java
  • src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java

claude added 9 commits July 7, 2026 17:42
Address review feedback on the streaming download:
- move the initial onProgress call inside the try-with-resources so a
  throwing listener (e.g. cancellation) cannot leak the response body stream
- bound the lazily-read body with DOWNLOAD_TIMEOUT via a watchdog that closes
  the stream on deadline, restoring the timeout coverage lost when switching
  from ofFile to ofInputStream
- add a test covering multi-chunk copying with monotonically increasing progress

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
Addresses SonarCloud java:S5838 on the multi-chunk progress test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
The server archives are tens to hundreds of MB; the JDK-default 16 KiB buffer
means thousands of read/write syscalls and progress callbacks per download.
Enlarge the copy buffer to cut syscalls and callback frequency proportionally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
copyToFile no longer closes the stream it is handed; copyBodyWithDeadline owns
it via try-with-resources. The timeout watchdog stays a close-to-interrupt only
and is cancelled on the normal path, so the stream is closed exactly once unless
the deadline fires (where the second, idempotent close is the interrupt itself).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
Move stream ownership to download(), where response.body() is obtained: it opens
the stream in a try-with-resources and hosts the timeout watchdog, so nothing
closes a stream received as a parameter. copyToFile only reads.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
…ability

The HttpClient and GitHub client were built inside methods, so the downloadIfNeeded
flow could not be exercised without hitting the network. Extract release lookup
behind a ReleaseCatalog interface (GitHubReleaseCatalog is the default impl) and
inject the HttpClient via constructor. Public constructors keep their signatures
and wire the GitHub-backed defaults.

Add end-to-end tests for the full flow using a fake catalog and a loopback HTTP
server serving a real zip: download+extract+record version, progress reporting,
interval skip, offline fallback to installed, failure with nothing installed, and
channel pass-through.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
Replace the loopback HTTP server in the download tests with a mocked HttpClient
(Mockito), so the full downloadIfNeeded flow runs with no real network at all.

Collapse the telescoping constructors: keep one public GitHub convenience ctor
(installDir, token) and one public dependency-injecting ctor (installDir,
checkInterval, ReleaseCatalog, HttpClient); ReleaseCatalog is now public.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
…t ctor

Remove the premature ReleaseCatalog/GitHubReleaseCatalog abstraction: release
lookup moves back into the downloader as an overridable latestRelease(channel)
returning a small Release record, mirroring the existing subclass-override test
seam. Collapse to a single constructor that injects the HttpClient
(installDir, httpClient, token); the old (installDir, token) ctor is gone.

Tests mock the HttpClient and override latestRelease to run the whole
downloadIfNeeded flow with no network and no local server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
…f an override

Release lookup moves to a concrete GitHubReleaseClient (no interface) injected via
the constructor, so tests mock it with Mockito rather than subclassing the
downloader to override a method. The downloader now takes
(installDir, GitHubReleaseClient, HttpClient); both collaborators are mocked in
the download-flow tests, which run with no network.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java (2)

147-161: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Используйте импорт вместо полного имени класса.

java.util.concurrent.atomic.AtomicInteger указан полным именем вместо импорта, хотя остальной файл использует обычные импорты (см. блок строк 30-44).

♻️ Предлагаемое исправление
+import java.util.concurrent.atomic.AtomicInteger;
...
-    var closed = new java.util.concurrent.atomic.AtomicInteger();
+    var closed = new AtomicInteger();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java`
around lines 147 - 161, The test in copyToFileLeavesSourceOpenForCaller uses the
fully qualified java.util.concurrent.atomic.AtomicInteger inline instead of the
file’s standard import style. Add an import for AtomicInteger alongside the
other imports in BslLanguageServerDownloaderTest and update the local variable
declaration to use the simple class name, keeping the test logic unchanged.

260-280: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Мок HttpClient.send всегда возвращает один и тот же экземпляр ByteArrayInputStream.

response.body() заранее настроен возвращать один и тот же ByteArrayInputStream(body) для всех вызовов send(...). Если код загрузчика когда-либо вызовет send() более одного раза для одного и того же клиента (повторные попытки, редиректы, ретраи после watchdog-таймаута, упомянутого в описании PR), второй вызов получит уже исчерпанный поток, что приведёт к скрытому, трудно диагностируемому провалу теста вместо явной ошибки. В текущих тестах send() вызывается один раз на клиент, поэтому проблема не проявляется, но стоит держать это в уме при добавлении тестов ретраев/таймаутов.

Использование doReturn(...).when(...) вместо when(...).thenReturn(...) — оправданный приём для обхода конфликта дженериков в сигнатуре send(HttpRequest, BodyHandler<T>), это нормально.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java`
around lines 260 - 280, The HttpClient mock in httpClientReturning() reuses the
same ByteArrayInputStream for every send() call, which will break any
retry/redirect path that reads the body more than once. Update the
response.body() stubbing so each send() gets a fresh ByteArrayInputStream over
the same byte[] body, while keeping the existing
doReturn(...).when(client).send(...) setup unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java`:
- Around line 147-161: The test in copyToFileLeavesSourceOpenForCaller uses the
fully qualified java.util.concurrent.atomic.AtomicInteger inline instead of the
file’s standard import style. Add an import for AtomicInteger alongside the
other imports in BslLanguageServerDownloaderTest and update the local variable
declaration to use the simple class name, keeping the test logic unchanged.
- Around line 260-280: The HttpClient mock in httpClientReturning() reuses the
same ByteArrayInputStream for every send() call, which will break any
retry/redirect path that reads the body more than once. Update the
response.body() stubbing so each send() gets a fresh ByteArrayInputStream over
the same byte[] body, while keeping the existing
doReturn(...).when(client).send(...) setup unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 05054093-3fae-4d06-93a9-9c27ed003633

📥 Commits

Reviewing files that changed from the base of the PR and between e9e955c and 87d7d59.

📒 Files selected for processing (4)
  • build.gradle.kts
  • src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java
  • src/main/java/com/github/_1c_syntax/utils/downloader/GitHubReleaseClient.java
  • src/test/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloaderTest.java

claude added 3 commits July 7, 2026 21:38
Address review nitpicks: import AtomicInteger instead of using its FQN, and have
the mocked HttpClient hand out a fresh ByteArrayInputStream on each send() so the
mock stays correct if the body is ever read more than once.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
…lookup

GitHubReleaseClient no longer takes an HttpClient: the no-arg
HttpClientGitHubConnector lets github-api build and manage its own client for
the API calls. The injected HttpClient stays only in the downloader, solely for
the asset download — which github-api does not provide (GHAsset exposes just the
browser download URL) and which needs per-byte progress anyway.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/java/com/github/_1c_syntax/utils/downloader/GitHubReleaseClient.java (1)

76-79: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Не материализуйте listReleases() перед поиском

PagedIterable.toList() обходит все страницы заранее, хотя здесь нужен только первый не-draft релиз. Это лишние запросы и задержка. Итерируйтесь напрямую и остановитесь на первом совпадении:

♻️ Предлагаемый рефакторинг
GHRelease release = null;
for (GHRelease it : repository.listReleases()) {
  if (!it.isDraft()) {
    release = it;
    break;
  }
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/github/_1c_syntax/utils/downloader/GitHubReleaseClient.java`
around lines 76 - 79, The GitHub release lookup in GitHubReleaseClient currently
materializes repository.listReleases() via toList() before filtering, which
eagerly loads every page; update the release selection logic to iterate directly
over repository.listReleases(), stop at the first non-draft GHRelease, and keep
the existing release assignment behavior without collecting the full list first.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/main/java/com/github/_1c_syntax/utils/downloader/GitHubReleaseClient.java`:
- Around line 76-79: The GitHub release lookup in GitHubReleaseClient currently
materializes repository.listReleases() via toList() before filtering, which
eagerly loads every page; update the release selection logic to iterate directly
over repository.listReleases(), stop at the first non-draft GHRelease, and keep
the existing release assignment behavior without collecting the full list first.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6edf9c5e-0a36-46f9-99c3-e3bb22c15d04

📥 Commits

Reviewing files that changed from the base of the PR and between 290e284 and 3651a4e.

📒 Files selected for processing (2)
  • src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java
  • src/main/java/com/github/_1c_syntax/utils/downloader/GitHubReleaseClient.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/github/_1c_syntax/utils/downloader/BslLanguageServerDownloader.java

Iterate repository.listReleases() lazily and break on the first non-draft
prerelease instead of materializing every page via toList(), avoiding needless
GitHub API requests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CXTAaR4opi34idMG7ZZ8BV
@sonarqubecloud

sonarqubecloud Bot commented Jul 8, 2026

Copy link
Copy Markdown

@nixel2007 nixel2007 merged commit 7abc027 into master Jul 8, 2026
15 checks passed
@nixel2007 nixel2007 deleted the claude/github-issue-31-review-g8hz79 branch July 8, 2026 04:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants