Skip to content

Support Android projects using build.gradle.kts#307

Merged
woocheol-lge merged 1 commit intomainfrom
k_test
Apr 17, 2026
Merged

Support Android projects using build.gradle.kts#307
woocheol-lge merged 1 commit intomainfrom
k_test

Conversation

@woocheol-lge
Copy link
Copy Markdown
Contributor

@woocheol-lge woocheol-lge commented Apr 13, 2026

Description

Support Android projects using build.gradle.kts

@woocheol-lge woocheol-lge requested a review from dd-jy April 13, 2026 07:57
@woocheol-lge woocheol-lge self-assigned this Apr 13, 2026
@woocheol-lge woocheol-lge added the chore [PR/Issue] Refactoring, maintenance the code label Apr 13, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

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

Walkthrough

Renamed a misspelled constant and expanded Android manifest detection to Kotlin DSL; refactored Gradle plugin/task injection and subprocess handling; added Android package-manager preexistence tracking and Gradle cache cleanup; and added many Android/Kotlin test project assets and REUSE mappings for test directories.

Changes

Cohort / File(s) Summary
Constants
src/fosslight_dependency/constant.py
Renamed SUPPORT_PACKAESUPPORT_PACKAGE; changed ANDROID mapping to ['build.gradle', 'build.gradle.kts'].
Core package manager / Gradle flow
src/fosslight_dependency/_package_manager.py
Refactored Gradle task runner to use argv-style subprocess calls, cwd context switching, returncode-based error handling, generalized Android plugin injection for Groovy/Kotlin DSL, and adjusted plugin/task helpers and signatures (add_android_plugin_in_gradle(..., gradle_file), add_allDeps_in_gradle(gradle_file)).
Android package manager state & cleanup
src/fosslight_dependency/package_manager/Android.py
Added input_file_preexisted and gradle_cache_preexisted flags; destructor now conditionally preserves preexisting input files and removes created Gradle cache only when appropriate.
Mass constant-reference fixes
src/fosslight_dependency/package_manager/*, src/fosslight_dependency/run_dependency_scanner.py
Replaced all uses of const.SUPPORT_PACKAE with const.SUPPORT_PACKAGE across many package managers (Cargo, Carthage, Cocoapods, Helm, Maven, Npm, Nuget, Pub, Pypi, Swift, Unity) and the runner. Reviewers should verify each package manager still resolves expected manifest filenames.
REUSE metadata
.reuse/dep5
Added Files: entries for tests/test_android2/*, tests/test_kotlin/*, and tests/test_kotlin2/* with Copyright/License mappings.
Test assets — Android (Groovy)
tests/test_android2/sunflower/...
Added full Android Groovy project (root & app build.gradle, gradle.properties, wrapper scripts, settings) containing fosslight plugin usage and build config key handling.
Test assets — Kotlin DSL (v1)
tests/test_kotlin/sunflower/...
Added Kotlin DSL app (build.gradle.kts) and a large android_dependency_output.txt (149 entries) used as expected dependency-license output.
Test assets — Kotlin DSL (v2)
tests/test_kotlin2/sunflower/...
Added Kotlin DSL project with version catalog (gradle/libs.versions.toml), build.gradle.kts, gradle.properties, wrapper scripts, and settings.gradle.kts.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant PM as PackageManager
  participant FS as FileSystem
  participant Gradle as GradleWrapper
  participant Parser as DependencyParser

  User->>PM: run_plugin()
  PM->>FS: chdir(input_dir) / backup gradle files
  PM->>Gradle: exec ['gradlew', 'allDeps'] (capture_output)
  Gradle-->>PM: stdout / stderr / returncode
  alt returncode == 0 and stdout non-empty
    PM->>Parser: parse_dependency_tree(stdout)
    Parser-->>PM: dependency data
  else failure
    PM->>PM: log stderr, mark failure
  end
  PM->>FS: restore backed-up files, cleanup .gradle (if created)
  PM-->>User: results / status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • dd-jy
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main change: adding support for Android projects using build.gradle.kts files. This is consistent with the primary code changes showing ANDROID constant expansion from 'build.gradle' to ['build.gradle', 'build.gradle.kts'].

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch k_test

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 and usage tips.

@woocheol-lge woocheol-lge changed the title support Android projects using build.gradle.kts ㄴupport Android projects using build.gradle.kts Apr 13, 2026
@woocheol-lge woocheol-lge changed the title ㄴupport Android projects using build.gradle.kts Support Android projects using build.gradle.kts Apr 13, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
src/fosslight_dependency/package_manager/Android.py (1)

49-50: Narrow exception handling for cache deletion.

Catching Exception here can mask unrelated bugs; prefer OSError for filesystem failures.

Proposed change
-            except Exception as e:
+            except OSError as e:
                 logger.warning(f'Failed to remove gradle cache directory: {e}')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/package_manager/Android.py` around lines 49 - 50,
Change the broad except Exception to catch filesystem-related errors only:
replace the "except Exception as e" block that logs "Failed to remove gradle
cache directory" with "except OSError as e" (or a more specific subclass like
FileNotFoundError if appropriate) so only filesystem failures are caught; keep
the existing logger.warning call and message but now log the OSError details.
Ensure this change is applied in the Android.py block that removes the gradle
cache directory and uses logger.warning to report failures.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 193-206: The current logic inspects data for 'dependencies {'
before 'buildscript {' and may inject plugin_classpath into a project
dependencies block; change the order so you check for 'buildscript {' first and
only inject plugin_classpath into a dependencies block that is inside
buildscript, using the same data string variable and plugin_classpath symbol; if
'buildscript {' exists but has no nested 'dependencies {' insert a dependencies
block inside that buildscript, and if no buildscript exists prepend a complete
buildscript block that includes a repositories section plus the dependencies
block containing plugin_classpath so the classpath can be resolved properly.
- Around line 242-267: The code currently emits a Kotlin DSL template in the
else branch regardless of whether the project is Groovy (const.GRADLE) or Kotlin
(const.KOTLIN); update the branch logic in the method that builds allDeps (the
block referencing self.package_manager_name and variables configuration/allDeps)
so that both const.ANDROID and const.GRADLE use the Groovy template (the task
allDeps(type: DependencyReportTask) { ... } string) while only const.KOTLIN uses
the Kotlin DSL template (tasks.register(...::class) { ... }); adjust the
conditional (or add an explicit check for const.KOTLIN) to select the correct
template and ensure configuration building lines match the chosen DSL.

In `@src/fosslight_dependency/package_manager/Kotlin.py`:
- Around line 10-14: The Kotlin subclass sets self.package_manager_name after
calling Android.__init__, but Android.__init__ reads package_manager_name during
setup and may pick the wrong manifest; move the assignment of
package_manager_name = const.KOTLIN to before the super().__init__ call in the
Kotlin.__init__ so Android.__init__ sees the correct package manager value
(refer to class Kotlin, method __init__, and Android.__init__).

---

Nitpick comments:
In `@src/fosslight_dependency/package_manager/Android.py`:
- Around line 49-50: Change the broad except Exception to catch
filesystem-related errors only: replace the "except Exception as e" block that
logs "Failed to remove gradle cache directory" with "except OSError as e" (or a
more specific subclass like FileNotFoundError if appropriate) so only filesystem
failures are caught; keep the existing logger.warning call and message but now
log the OSError details. Ensure this change is applied in the Android.py block
that removes the gradle cache directory and uses logger.warning to report
failures.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 01d24367-b061-4281-8f65-c0d242ad7b06

📥 Commits

Reviewing files that changed from the base of the PR and between 203acab and 6164f49.

⛔ Files ignored due to path filters (2)
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (36)
  • .reuse/dep5
  • src/fosslight_dependency/_analyze_dependency.py
  • src/fosslight_dependency/_package_manager.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Android.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/package_manager/Kotlin.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Swift.py
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_android2/sunflower/build.gradle
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/gradlew
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin/sunflower/app/android_dependency_output.txt
  • tests/test_kotlin/sunflower/app/build.gradle.kts
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/app/build.gradle.kts
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/settings.gradle.kts

Comment thread src/fosslight_dependency/_package_manager.py Outdated
Comment thread src/fosslight_dependency/_package_manager.py Outdated
Comment thread src/fosslight_dependency/package_manager/Kotlin.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/fosslight_dependency/_package_manager.py (2)

259-285: ⚠️ Potential issue | 🟠 Major

const.GRADLE should use Groovy task syntax, not Kotlin DSL syntax.

The else branch currently applies Kotlin DSL (tasks.register(...::class)) to const.GRADLE (build.gradle), which is Groovy DSL.

In Groovy build.gradle, is tasks.register("allDeps", org.gradle.api.tasks.diagnostics.DependencyReportTask::class) valid, or should it be tasks.register('allDeps', org.gradle.api.tasks.diagnostics.DependencyReportTask) / task allDeps(type: DependencyReportTask)?
♻️ Proposed fix
-        if self.package_manager_name == const.ANDROID:
+        if self.package_manager_name in (const.ANDROID, const.GRADLE):
             configuration = ','.join([f'project.configurations.{c}' for c in config])
             allDeps = f'''allprojects {{
                     task allDeps(type: DependencyReportTask) {{
                             doFirst{{
                                 try {{
                                     configurations = [{configuration}] as Set }}
                                 catch(UnknownConfigurationException) {{}}
                             }}
                         }}
                         }}'''
-        else:
+        elif self.package_manager_name == const.KOTLIN:
             configuration = '\n'.join([
                 f'                try {{ cfgs.add(project.configurations.getByName("{c}")) }} catch (e: Exception) {{}}'
                 for c in config
             ])
             allDeps = f'''
                     allprojects {{
                         tasks.register("allDeps", org.gradle.api.tasks.diagnostics.DependencyReportTask::class) {{
                             doFirst {{
                                 val cfgs = mutableSetOf<org.gradle.api.artifacts.Configuration>()
                     {configuration}
                                 setConfigurations(cfgs)
                             }}
                         }}
                     }}'''
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 259 - 285, The
else-branch that builds the allDeps Gradle snippet uses Kotlin DSL syntax
(tasks.register(...::class)) which is incorrect for const.GRADLE (Groovy
build.gradle); update the logic in _package_manager.py that builds allDeps when
self.package_manager_name == const.GRADLE (the else branch producing the
tasks.register(...) block) to emit Groovy DSL syntax instead (e.g., use
tasks.register('allDeps', org.gradle.api.tasks.diagnostics.DependencyReportTask)
or the Groovy-style task allDeps(type: DependencyReportTask) and keep the same
configuration collection code), ensuring the string templates and variable names
(configuration, allDeps) are adjusted to generate valid Groovy rather than
Kotlin DSL.

210-223: ⚠️ Potential issue | 🟠 Major

Inject Kotlin classpath(...) only inside buildscript { dependencies { ... } } and include repositories.

The current branch checks 'dependencies {' before 'buildscript {', so it can inject into the project dependency block (invalid for script classpath). The fallback block also omits repositories, so classpath resolution can fail.

In Gradle Kotlin DSL (build.gradle.kts), can classpath("group:artifact:version") be used in the regular project dependencies block, or only inside buildscript { dependencies { ... } }, and does buildscript classpath require repositories { ... }?
♻️ Proposed fix
-            if 'dependencies {' in data:
+            if 'buildscript {' in data and 'buildscript {' in data:
+                # Insert classpath into buildscript dependencies block, not project dependencies.
+                # Also ensure repositories are available for classpath resolution.
+                if 'buildscript {' in data and 'dependencies {' in data.split('buildscript {', 1)[1]:
+                    data = data.replace(
+                        'buildscript {\n    dependencies {',
+                        f'buildscript {{\n    repositories {{\n        mavenCentral()\n        google()\n    }}\n    dependencies {{\n{plugin_classpath}',
+                        1
+                    )
+                else:
+                    data = data.replace(
+                        'buildscript {',
+                        f'buildscript {{\n    repositories {{\n        mavenCentral()\n        google()\n    }}\n    dependencies {{\n{plugin_classpath}\n    }}',
+                        1
+                    )
-            elif 'buildscript {' in data:
-                data = data.replace(
-                    'buildscript {',
-                    f'buildscript {{\n    dependencies {{\n{plugin_classpath}\n    }}',
-                    1
-                )
             else:
-                data = f'buildscript {{\n    dependencies {{\n{plugin_classpath}\n    }}\n}}\n' + data
+                data = (
+                    'buildscript {\n'
+                    '    repositories {\n'
+                    '        mavenCentral()\n'
+                    '        google()\n'
+                    '    }\n'
+                    '    dependencies {\n'
+                    f'{plugin_classpath}\n'
+                    '    }\n'
+                    '}\n'
+                ) + data
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 210 - 223, The
code currently tests for 'dependencies {' before 'buildscript {' and may insert
plugin_classpath into the wrong block; change the conditional order so you
detect and inject into 'buildscript {' (and its inner 'dependencies {') first,
only fall back to creating a buildscript block when no buildscript exists, and
when creating that fallback include a repositories block alongside dependencies
(e.g., add a repositories { ... } section above or beside the injected
dependencies) so classpath resolution works; locate the string-manipulation
using variables data and plugin_classpath in _package_manager.py and modify
those branches accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 98-168: Wrap the block that modifies and executes Gradle files in
a try/finally so gradle_file and module_build_gradle are always restored: move
the creation of gradle_backup/module_gradle_backup and the calls to
add_allDeps_in_gradle()/add_android_kotlin_plugin_in_gradle() and all subprocess
invocations (the section that uses cmd_gradle, ret_task, ret_alldeps,
ret_plugin, change_file_mode, subprocess.check_output/subprocess.run, and
plugin_auto_run) into a try, and in the finally ensure you revert file mode
(using change_file_mode with saved current_mode if set) and always restore
gradle_backup -> gradle_file and module_gradle_backup -> module_build_gradle
(removing any temp files first); also ensure current_mode is only used if
initialized and that ret_task defaulting logic remains correct so cleanup always
runs on exceptions.

---

Duplicate comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 259-285: The else-branch that builds the allDeps Gradle snippet
uses Kotlin DSL syntax (tasks.register(...::class)) which is incorrect for
const.GRADLE (Groovy build.gradle); update the logic in _package_manager.py that
builds allDeps when self.package_manager_name == const.GRADLE (the else branch
producing the tasks.register(...) block) to emit Groovy DSL syntax instead
(e.g., use tasks.register('allDeps',
org.gradle.api.tasks.diagnostics.DependencyReportTask) or the Groovy-style task
allDeps(type: DependencyReportTask) and keep the same configuration collection
code), ensuring the string templates and variable names (configuration, allDeps)
are adjusted to generate valid Groovy rather than Kotlin DSL.
- Around line 210-223: The code currently tests for 'dependencies {' before
'buildscript {' and may insert plugin_classpath into the wrong block; change the
conditional order so you detect and inject into 'buildscript {' (and its inner
'dependencies {') first, only fall back to creating a buildscript block when no
buildscript exists, and when creating that fallback include a repositories block
alongside dependencies (e.g., add a repositories { ... } section above or beside
the injected dependencies) so classpath resolution works; locate the
string-manipulation using variables data and plugin_classpath in
_package_manager.py and modify those branches accordingly.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 864cb888-86ef-4d70-a83d-367fc1e3599c

📥 Commits

Reviewing files that changed from the base of the PR and between 6164f49 and 7a6a994.

⛔ Files ignored due to path filters (2)
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (36)
  • .reuse/dep5
  • src/fosslight_dependency/_analyze_dependency.py
  • src/fosslight_dependency/_package_manager.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Android.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/package_manager/Kotlin.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Swift.py
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_android2/sunflower/build.gradle
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/gradlew
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin/sunflower/app/android_dependency_output.txt
  • tests/test_kotlin/sunflower/app/build.gradle.kts
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/app/build.gradle.kts
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/settings.gradle.kts
✅ Files skipped from review due to trivial changes (21)
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • .reuse/dep5
  • tests/test_kotlin2/sunflower/gradle.properties
  • src/fosslight_dependency/run_dependency_scanner.py
  • src/fosslight_dependency/package_manager/Kotlin.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Pub.py
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin2/sunflower/settings.gradle.kts
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/build.gradle
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/build.gradle.kts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/_analyze_dependency.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Helm.py
  • tests/test_kotlin/sunflower/build.gradle.kts

Comment thread src/fosslight_dependency/_package_manager.py Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
src/fosslight_dependency/_package_manager.py (2)

259-284: ⚠️ Potential issue | 🟠 Major

const.GRADLE incorrectly receives Kotlin DSL template.

The condition at line 259 only checks for const.ANDROID to use the Groovy template. The else branch (line 270) uses Kotlin DSL syntax (tasks.register(...::class)), which is invalid for const.GRADLE projects that use build.gradle (Groovy DSL).

Both const.ANDROID and const.GRADLE should use the Groovy template; only const.KOTLIN should use the Kotlin DSL template.

♻️ Proposed fix
-        if self.package_manager_name == const.ANDROID:
+        if self.package_manager_name in (const.ANDROID, const.GRADLE):
             configuration = ','.join([f'project.configurations.{c}' for c in config])
             allDeps = f'''allprojects {{
                     task allDeps(type: DependencyReportTask) {{
                             doFirst{{
                                 try {{
                                     configurations = [{configuration}] as Set }}
                                 catch(UnknownConfigurationException) {{}}
                             }}
                         }}
                         }}'''
-        else:
+        elif self.package_manager_name == const.KOTLIN:
             configuration = '\n'.join([
                 f'                try {{ cfgs.add(project.configurations.getByName("{c}")) }} catch (e: Exception) {{}}'
                 for c in config
             ])
             allDeps = f'''
                     allprojects {{
                         tasks.register("allDeps", org.gradle.api.tasks.diagnostics.DependencyReportTask::class) {{
                             doFirst {{
                                 val cfgs = mutableSetOf<org.gradle.api.artifacts.Configuration>()
                     {configuration}
                                 setConfigurations(cfgs)
                             }}
                         }}
                     }}'''
+        else:
+            logger.warning(f"Unsupported package manager for allDeps: {self.package_manager_name}")
+            return False
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 259 - 284, The
code currently emits the Kotlin DSL template for any non-ANDROID package
manager; change the branching so only const.KOTLIN produces the Kotlin DSL
snippet and both const.ANDROID and const.GRADLE use the Groovy template. Locate
the block that sets allDeps (use references package_manager_name, const.ANDROID,
const.GRADLE, const.KOTLIN, and the allDeps variable) and update the conditional
to either check explicitly for const.KOTLIN for the Kotlin template or use an if
self.package_manager_name in (const.ANDROID, const.GRADLE): Groovy-template else
if self.package_manager_name == const.KOTLIN: Kotlin-template, ensuring the
Groovy string (the current ANDROID branch) is reused for GRADLE.

204-229: ⚠️ Potential issue | 🟠 Major

_add_kotlin_buildscript() may inject classpath into project dependencies block.

The logic checks for 'dependencies {' (line 210) before 'buildscript {' (line 216). In a build.gradle.kts with both a project dependencies {} block and a buildscript {} block, this will incorrectly inject classpath(...) into the project dependencies, which is invalid Kotlin DSL syntax.

Additionally, the fallback (line 223) creates a buildscript block without a repositories {} section, which will prevent classpath resolution.

♻️ Proposed fix: check buildscript first
     def _add_kotlin_buildscript(self):
         plugin_classpath = '    classpath("org.fosslight:android-dependency-scanning:+")'
         gradle_file = const.SUPPORT_PACKAGE.get(self.package_manager_name)
         try:
             with open(gradle_file, 'r', encoding='utf-8') as f:
                 data = f.read()
-            if 'dependencies {' in data:
-                data = data.replace(
-                    'dependencies {',
-                    f'dependencies {{\n{plugin_classpath}',
-                    1
-                )
-            elif 'buildscript {' in data:
+            if 'buildscript {' in data:
+                # Find buildscript block and inject into its dependencies
+                if 'buildscript {' in data and 'dependencies {' in data[data.find('buildscript {'):]:
+                    # buildscript has dependencies block
+                    bs_start = data.find('buildscript {')
+                    deps_start = data.find('dependencies {', bs_start)
+                    data = data[:deps_start] + 'dependencies {\n' + plugin_classpath + '\n' + data[deps_start + len('dependencies {'):]
+                else:
+                    data = data.replace(
+                        'buildscript {',
+                        f'buildscript {{\n    repositories {{ mavenCentral() }}\n    dependencies {{\n{plugin_classpath}\n    }}',
+                        1
+                    )
-                data = data.replace(
-                    'buildscript {',
-                    f'buildscript {{\n    dependencies {{\n{plugin_classpath}\n    }}',
-                    1
-                )
             else:
-                data = f'buildscript {{\n    dependencies {{\n{plugin_classpath}\n    }}\n}}\n' + data
+                data = f'buildscript {{\n    repositories {{ mavenCentral() }}\n    dependencies {{\n{plugin_classpath}\n    }}\n}}\n' + data
             with open(gradle_file, 'w', encoding='utf-8') as f:
                 f.write(data)
             return True
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 204 - 229, In
_add_kotlin_buildscript(), avoid injecting plugin_classpath into a project-level
'dependencies {' by checking for 'buildscript {' before 'dependencies {'; update
the control flow so you first look for an existing 'buildscript {' and insert
the classpath (and add a 'repositories {' section if missing) inside that
buildscript's dependencies block, then fall back to adding a new buildscript
that includes both 'repositories {' and 'dependencies {' when neither block
exists; use gradle_file and const.SUPPORT_PACKAGE to locate the file and ensure
all modifications write back to the same file and return the existing boolean
behavior on success/failure.
🧹 Nitpick comments (1)
tests/test_kotlin/sunflower/app/build.gradle.kts (1)

65-67: Outdated comment references Java 8 while targeting Java 17.

The comment on line 66 says "work-runtime-ktx 2.1.0 and above now requires Java 8" but jvmTarget is set to Java 17. Consider updating the comment to reflect the actual Java version requirement for this configuration.

📝 Suggested comment update
   kotlinOptions {
-    // work-runtime-ktx 2.1.0 and above now requires Java 8
+    // Targeting Java 17 for modern Android development
     jvmTarget = JavaVersion.VERSION_17.toString()
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/test_kotlin/sunflower/app/build.gradle.kts` around lines 65 - 67,
Update the misleading inline comment in the kotlinOptions block: change the
comment that references Java 8 to accurately reflect the actual target Java
version (Java 17) used by jvmTarget (JavaVersion.VERSION_17.toString()). Locate
the kotlinOptions section and replace or reword the comment so it references the
correct Java requirement (e.g., "work-runtime-ktx requires Java 8+, project
targets Java 17") or otherwise clarifies that the project is targeting Java 17.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 158-177: Move the backup-restoration logic out of the try block
into the finally block so backups are always restored on error: initialize
gradle_file, gradle_backup, module_build_gradle, module_gradle_backup before the
try to avoid NameError, then in finally check those variables and use
os.path.isfile to remove/restore (shutil.move) the backups for
gradle_backup->gradle_file and module_gradle_backup->module_build_gradle when
self.package_manager_name is in (const.ANDROID, const.KOTLIN); keep the existing
logger/error handling and ensure os.chdir(prev_dir) remains in finally as well.
- Around line 181-202: The _add_android_buildscript function currently always
prepends a new buildscript block (variable build_script) which can create
duplicates; change it to read gradle_file, detect if a buildscript { ... } block
already exists and if so insert the classpath
'org.fosslight:android-dependency-scanning:+' line into that block's
dependencies section (and avoid adding it if the exact classpath already
exists), otherwise prepend the full build_script as before; perform file
read/write on gradle_file as currently done and preserve existing
content/formatting, and keep the existing logging behavior on exceptions.

In `@tests/test_kotlin/sunflower/app/android_dependency_output.txt`:
- Line 37: The test fixture entry for dependency
com.google.guava:listenablefuture:1.0 (ID 35) has an empty License field; update
the expected output to "Apache License 2.0" for that entry (or alternatively fix
the license scanner so it correctly detects Apache License 2.0 for
com.google.guava:listenablefuture:1.0) and ensure the test record for ID 35
reflects the corrected license text.

---

Duplicate comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 259-284: The code currently emits the Kotlin DSL template for any
non-ANDROID package manager; change the branching so only const.KOTLIN produces
the Kotlin DSL snippet and both const.ANDROID and const.GRADLE use the Groovy
template. Locate the block that sets allDeps (use references
package_manager_name, const.ANDROID, const.GRADLE, const.KOTLIN, and the allDeps
variable) and update the conditional to either check explicitly for const.KOTLIN
for the Kotlin template or use an if self.package_manager_name in
(const.ANDROID, const.GRADLE): Groovy-template else if self.package_manager_name
== const.KOTLIN: Kotlin-template, ensuring the Groovy string (the current
ANDROID branch) is reused for GRADLE.
- Around line 204-229: In _add_kotlin_buildscript(), avoid injecting
plugin_classpath into a project-level 'dependencies {' by checking for
'buildscript {' before 'dependencies {'; update the control flow so you first
look for an existing 'buildscript {' and insert the classpath (and add a
'repositories {' section if missing) inside that buildscript's dependencies
block, then fall back to adding a new buildscript that includes both
'repositories {' and 'dependencies {' when neither block exists; use gradle_file
and const.SUPPORT_PACKAGE to locate the file and ensure all modifications write
back to the same file and return the existing boolean behavior on
success/failure.

---

Nitpick comments:
In `@tests/test_kotlin/sunflower/app/build.gradle.kts`:
- Around line 65-67: Update the misleading inline comment in the kotlinOptions
block: change the comment that references Java 8 to accurately reflect the
actual target Java version (Java 17) used by jvmTarget
(JavaVersion.VERSION_17.toString()). Locate the kotlinOptions section and
replace or reword the comment so it references the correct Java requirement
(e.g., "work-runtime-ktx requires Java 8+, project targets Java 17") or
otherwise clarifies that the project is targeting Java 17.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 02651b00-753a-42b6-8f87-c064cc4da601

📥 Commits

Reviewing files that changed from the base of the PR and between 7a6a994 and c08e9f7.

⛔ Files ignored due to path filters (2)
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (36)
  • .reuse/dep5
  • src/fosslight_dependency/_analyze_dependency.py
  • src/fosslight_dependency/_package_manager.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Android.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/package_manager/Kotlin.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Swift.py
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_android2/sunflower/build.gradle
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/gradlew
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin/sunflower/app/android_dependency_output.txt
  • tests/test_kotlin/sunflower/app/build.gradle.kts
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/app/build.gradle.kts
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/settings.gradle.kts
✅ Files skipped from review due to trivial changes (21)
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Unity.py
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • src/fosslight_dependency/package_manager/Cargo.py
  • tests/test_kotlin2/sunflower/gradle.properties
  • .reuse/dep5
  • src/fosslight_dependency/run_dependency_scanner.py
  • src/fosslight_dependency/package_manager/Kotlin.py
  • tests/test_kotlin2/sunflower/settings.gradle.kts
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/app/build.gradle.kts
🚧 Files skipped from review as they are similar to previous changes (8)
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/_analyze_dependency.py
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/package_manager/Swift.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/constant.py
  • tests/test_android2/sunflower/gradlew

Comment thread src/fosslight_dependency/_package_manager.py Outdated
Comment thread src/fosslight_dependency/_package_manager.py Outdated
Comment thread tests/test_kotlin/sunflower/app/android_dependency_output.txt
Copy link
Copy Markdown
Contributor

@dd-jy dd-jy left a comment

Choose a reason for hiding this comment

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

@woocheol-lge
현재 Package manager 단위로 class가 생성되어 있는데, Android에 대해서만 Gradle과 별도 플러그인 실행을 위해 분리해 두었습니다.
kotlin은 사실 언어이고 Android이기 때문에 별도 Class로 생성하는 것보다 Android로 처리되도록 수정되어야 할 것 같습니다.

@woocheol-lge woocheol-lge force-pushed the k_test branch 2 times, most recently from 036f405 to efab40f Compare April 16, 2026 05:07
@woocheol-lge woocheol-lge requested a review from dd-jy April 16, 2026 05:09
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (1)
src/fosslight_dependency/_package_manager.py (1)

199-210: ⚠️ Potential issue | 🟠 Major

Keep the dependencies {} search scoped to the actual buildscript {} block.

bs_block = data[bs_start:] scans the entire rest of the file. If the script has buildscript { ... } without its own dependencies {} and a regular project dependencies {} later, Lines 204-205 / 244-245 inject the plugin classpath into the project dependency block instead of the buildscript block.

Please bound the search to the matching closing brace of buildscript {} before looking for or inserting dependencies {}. This is the same invalid-injection class of bug that was called out earlier, just in the new helper path.

Also applies to: 238-250

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 199 - 210, The
current logic uses bs_block = data[bs_start:] which scans to EOF and can match a
later project-level "dependencies {"; instead compute the exact end of the
buildscript block by walking characters from bs_start (counting '{' and '}' to
find the matching closing brace), set bs_block = data[bs_start:bs_end], then
search for 'dependencies {' inside that bounded bs_block and insert
plugin_classpath at dep_pos computed from bs_start + bs_block.index(...); if no
dependencies exist insert the dependencies block right after the opening
buildscript brace inside that same bs_block (not via a global replace). Apply
this same bounded-search fix for the other analogous insertion path that also
uses bs_block and plugin_classpath.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 109-114: The code wrongly reuses the root gradle filename/DSL for
the module; change the logic that handles Android modules (where
self.package_manager_name == const.ANDROID) to resolve the module's actual
Gradle script independently: look inside the module directory (self.app_name)
for candidate files (e.g., build.gradle and build.gradle.kts), pick the existing
one (prefer explicit existence over using the root gradle_file), set
module_build_gradle to that path and compute module_gradle_backup and the DSL
flag (Kotlin vs Groovy) from the module filename or its contents, then call
add_android_plugin_in_gradle(module_build_gradle, module_file_name_or_dsl_flag)
so injection uses the module's true filename/DSL; apply the same independent
resolution approach where the code later references the root flag/filename (the
block around add_android_plugin_in_gradle and the apply-syntax branch formerly
at lines ~263-270).
- Around line 132-147: The Gradle subprocess calls build shell strings with
cmd_gradle and user-controlled self.app_name and pass them to
subprocess.check_output/run with shell=True; remove shell=True and construct
argv lists instead (e.g. [cmd_gradle, 'allDeps'] and [cmd_gradle,
f':{self.app_name}:generateLicenseTxt']) so arguments are not interpreted by a
shell, update the calls where cmd_gradle and self.app_name are used (the
branches that set cmd, the subprocess.check_output usage and the subprocess.run
usage around ret and ret_plugin), and apply the same fix in
collect_gradle_download_urls() where app_name is included; ensure
encoding/capture_output behavior is preserved when switching to list-form
subprocess calls.

In `@tests/test_android2/sunflower/app/build.gradle`:
- Around line 38-39: The build generates a Java literal that can become the
string "null" or break if the UNSPLASH key contains quotes/backslashes; update
the code that calls buildConfigField("String", "UNSPLASH_ACCESS_KEY", "\"" +
getUnsplashAccess() + "\"") so that getUnsplashAccess() is checked for
null/empty and replaced with a safe default (e.g., empty string) instead of the
string "null", and escape quotes/backslashes in the returned value before
wrapping it in the Java string literal; apply the same fix to the other
occurrences referenced (lines 117-119) and ensure the unique symbols touched are
buildConfigField, UNSPLASH_ACCESS_KEY and getUnsplashAccess.

In `@tests/test_kotlin2/sunflower/app/build.gradle.kts`:
- Around line 38-39: The BuildConfig generation is writing the raw return of
getUnsplashAccess() which becomes the literal "null" when missing and doesn't
escape Java string characters; update the callsite that uses
buildConfigField("String", "UNSPLASH_ACCESS_KEY", "\"" + getUnsplashAccess() +
"\"") to first normalize the value (treat null/blank as empty string) and escape
special Java string characters (backslashes, quotes, newlines, etc.) before
wrapping with quotes; use the same fix for the other buildConfigField
occurrences that set UNSPLASH_ACCESS_KEY so all generated Java BuildConfig
values are safe and never the literal "null".

---

Duplicate comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 199-210: The current logic uses bs_block = data[bs_start:] which
scans to EOF and can match a later project-level "dependencies {"; instead
compute the exact end of the buildscript block by walking characters from
bs_start (counting '{' and '}' to find the matching closing brace), set bs_block
= data[bs_start:bs_end], then search for 'dependencies {' inside that bounded
bs_block and insert plugin_classpath at dep_pos computed from bs_start +
bs_block.index(...); if no dependencies exist insert the dependencies block
right after the opening buildscript brace inside that same bs_block (not via a
global replace). Apply this same bounded-search fix for the other analogous
insertion path that also uses bs_block and plugin_classpath.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2e765dd8-09ae-44c4-8daf-c59625a497a4

📥 Commits

Reviewing files that changed from the base of the PR and between c08e9f7 and 036f405.

⛔ Files ignored due to path filters (2)
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (34)
  • .reuse/dep5
  • src/fosslight_dependency/_package_manager.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Android.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Swift.py
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_android2/sunflower/build.gradle
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/gradlew
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin/sunflower/app/android_dependency_output.txt
  • tests/test_kotlin/sunflower/app/build.gradle.kts
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/app/build.gradle.kts
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/settings.gradle.kts
✅ Files skipped from review due to trivial changes (16)
  • .reuse/dep5
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle.properties
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/build.gradle
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin/sunflower/build.gradle.kts
  • src/fosslight_dependency/package_manager/Cargo.py
  • tests/test_kotlin2/sunflower/settings.gradle.kts
  • tests/test_kotlin/sunflower/app/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/build.gradle.kts
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Swift.py

Comment thread src/fosslight_dependency/_package_manager.py
Comment thread src/fosslight_dependency/_package_manager.py Outdated
Comment thread tests/test_android2/sunflower/app/build.gradle
Comment thread tests/test_kotlin2/sunflower/app/build.gradle.kts
Comment thread src/fosslight_dependency/_package_manager.py Outdated
Signed-off-by: woocheol <jayden6659@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/fosslight_dependency/_package_manager.py (1)

109-114: ⚠️ Potential issue | 🟡 Minor

Module Gradle file should be resolved independently of root file DSL.

The code assumes the module uses the same Gradle filename as the root (gradle_file), but valid Gradle builds can mix DSLs (e.g., build.gradle.kts at root with app/build.gradle in module). This causes incorrect syntax injection: KTS syntax is determined from the root file but injected into the module file, resulting in parse errors if DSLs differ.

♻️ Proposed fix to resolve module DSL independently
                 if self.package_manager_name == const.ANDROID:
-                    module_build_gradle = os.path.join(self.app_name, gradle_file)
+                    module_candidates = [
+                        os.path.join(self.app_name, 'build.gradle'),
+                        os.path.join(self.app_name, 'build.gradle.kts'),
+                    ]
+                    module_build_gradle = next((f for f in module_candidates if os.path.isfile(f)), '')
+                    module_gradle_dsl = os.path.basename(module_build_gradle) if module_build_gradle else ''
                     module_gradle_backup = f'{module_build_gradle}_bk'
-                    if os.path.isfile(module_build_gradle) and (not os.path.isfile(self.input_file_name)):
+                    if module_build_gradle and os.path.isfile(module_build_gradle) and (not os.path.isfile(self.input_file_name)):
                         shutil.copy(module_build_gradle, module_gradle_backup)
-                        ret_plugin = self.add_android_plugin_in_gradle(module_build_gradle, gradle_file)
+                        ret_plugin = self.add_android_plugin_in_gradle(module_build_gradle, module_gradle_dsl)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 109 - 114, The
code currently assumes the module gradle filename equals the root gradle_file,
which can mix DSLs and produce incorrect injections; update the ANDROID branch
(where package_manager_name == const.ANDROID) to detect the module's actual
gradle filename independently by checking for common module filenames (e.g.,
check os.path.join(self.app_name, 'build.gradle.kts') first, then
'build.gradle', and fall back to gradle_file if neither exists), set
module_build_gradle and module_gradle_backup using the detected filename, and
pass that detected filename/path into add_android_plugin_in_gradle instead of
blindly using gradle_file (refer to symbols: package_manager_name,
const.ANDROID, module_build_gradle, gradle_file, input_file_name,
add_android_plugin_in_gradle).
🧹 Nitpick comments (1)
src/fosslight_dependency/_package_manager.py (1)

163-166: Verify early skip path behavior when input file pre-exists.

When self.input_file_name already exists, the code skips plugin execution and sets direct_dep to False. However, this check happens after the Gradle commands may have already run. Consider moving this check earlier (before line 102) to avoid unnecessary Gradle invocations when the output file already exists.

♻️ Proposed fix to check early
         try:
             candidates = const.SUPPORT_PACKAGE.get(self.package_manager_name, '')
             if isinstance(candidates, list):
                 gradle_file = next((f for f in candidates if os.path.isfile(f)), '')
             else:
                 gradle_file = candidates
+
+            # Early exit if input file already exists
+            if os.path.isfile(self.input_file_name):
+                logger.info(f'Found {self.input_file_name}, skip to run plugin.')
+                self.set_direct_dependencies(False)
+                return True
+
             if os.path.isfile(gradle_file):
                 gradle_backup = f'{gradle_file}_bk'
                 ...
-
-            if os.path.isfile(self.input_file_name):
-                logger.info(f'Found {self.input_file_name}, skip to run plugin.')
-                self.set_direct_dependencies(False)
-                ret_task = True
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fosslight_dependency/_package_manager.py` around lines 163 - 166, The
early-skip check that tests os.path.isfile(self.input_file_name) and sets
self.set_direct_dependencies(False)/ret_task = True must run before any Gradle
invocations; move this check to the start of the method (before the block that
constructs or executes Gradle commands) so the plugin never launches Gradle when
the output file already exists. Keep the existing behavior of calling
self.set_direct_dependencies(False) and returning the same ret_task value when
the file exists, and ensure the check remains using self.input_file_name to
locate the pre-existing output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 109-114: The code currently assumes the module gradle filename
equals the root gradle_file, which can mix DSLs and produce incorrect
injections; update the ANDROID branch (where package_manager_name ==
const.ANDROID) to detect the module's actual gradle filename independently by
checking for common module filenames (e.g., check os.path.join(self.app_name,
'build.gradle.kts') first, then 'build.gradle', and fall back to gradle_file if
neither exists), set module_build_gradle and module_gradle_backup using the
detected filename, and pass that detected filename/path into
add_android_plugin_in_gradle instead of blindly using gradle_file (refer to
symbols: package_manager_name, const.ANDROID, module_build_gradle, gradle_file,
input_file_name, add_android_plugin_in_gradle).

---

Nitpick comments:
In `@src/fosslight_dependency/_package_manager.py`:
- Around line 163-166: The early-skip check that tests
os.path.isfile(self.input_file_name) and sets
self.set_direct_dependencies(False)/ret_task = True must run before any Gradle
invocations; move this check to the start of the method (before the block that
constructs or executes Gradle commands) so the plugin never launches Gradle when
the output file already exists. Keep the existing behavior of calling
self.set_direct_dependencies(False) and returning the same ret_task value when
the file exists, and ensure the check remains using self.input_file_name to
locate the pre-existing output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 58483be9-8cda-42b1-9416-2a92acab9b84

📥 Commits

Reviewing files that changed from the base of the PR and between 036f405 and 8d70ca5.

⛔ Files ignored due to path filters (2)
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
📒 Files selected for processing (34)
  • .reuse/dep5
  • src/fosslight_dependency/_package_manager.py
  • src/fosslight_dependency/constant.py
  • src/fosslight_dependency/package_manager/Android.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • src/fosslight_dependency/package_manager/Cocoapods.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/package_manager/Maven.py
  • src/fosslight_dependency/package_manager/Npm.py
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Pypi.py
  • src/fosslight_dependency/package_manager/Swift.py
  • src/fosslight_dependency/package_manager/Unity.py
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_android2/sunflower/build.gradle
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_android2/sunflower/gradlew
  • tests/test_android2/sunflower/gradlew.bat
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_kotlin/sunflower/app/android_dependency_output.txt
  • tests/test_kotlin/sunflower/app/build.gradle.kts
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/app/build.gradle.kts
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_kotlin2/sunflower/gradlew.bat
  • tests/test_kotlin2/sunflower/settings.gradle.kts
✅ Files skipped from review due to trivial changes (15)
  • src/fosslight_dependency/package_manager/Pypi.py
  • tests/test_android2/sunflower/settings.gradle
  • tests/test_android2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • tests/test_kotlin2/sunflower/gradle.properties
  • tests/test_android2/sunflower/gradle.properties
  • tests/test_kotlin2/sunflower/gradle/wrapper/gradle-wrapper.properties
  • src/fosslight_dependency/package_manager/Pub.py
  • src/fosslight_dependency/package_manager/Carthage.py
  • tests/test_kotlin2/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/settings.gradle.kts
  • src/fosslight_dependency/run_dependency_scanner.py
  • tests/test_android2/sunflower/build.gradle
  • .reuse/dep5
  • tests/test_kotlin/sunflower/build.gradle.kts
  • tests/test_kotlin2/sunflower/gradle/libs.versions.toml
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/fosslight_dependency/package_manager/Nuget.py
  • src/fosslight_dependency/package_manager/Cargo.py
  • src/fosslight_dependency/package_manager/Helm.py
  • src/fosslight_dependency/constant.py
  • tests/test_kotlin2/sunflower/gradlew
  • tests/test_android2/sunflower/app/build.gradle
  • tests/test_kotlin2/sunflower/app/build.gradle.kts

@woocheol-lge woocheol-lge merged commit 9c2695a into main Apr 17, 2026
15 checks passed
@woocheol-lge woocheol-lge deleted the k_test branch April 17, 2026 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore [PR/Issue] Refactoring, maintenance the code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants