-
Notifications
You must be signed in to change notification settings - Fork 125
Comparing changes
Open a pull request
base repository: kscripting/kscript
base: master
head repository: jnorthrup/k2script
compare: master
- 20 commits
- 47 files changed
- 2 contributors
Commits on Jun 5, 2025
-
fix: Resolve ClassNotFoundException for .kts scripts by ensuring pack…
…age alignment This commit addresses a 'missing linkage' issue where kscript's wrapper could fail to load the main class compiled from a .kts script, resulting in a ClassNotFoundException. **Problem Analysis:** 1. For `.kts` scripts without an explicit `package` declaration, kscript internally assigns a default package (e.g., `kscript.scriplet`). 2. A wrapper class (e.g., `Main_ScriptName.kt`) is generated to provide a standard `main` method entry point. This wrapper attempts to load the compiled `.kts` script's class using reflection, qualified with the assigned package name (e.g., `kscript.scriplet.ScriptName`). 3. However, the original `.kts` file content (without an explicit package statement) was written to a temporary file and compiled by `kotlinc`. `kotlinc` would place such a class in the default (unnamed) package. 4. This mismatch (wrapper expecting `kscript.scriplet.ScriptName`, but class actually being `ScriptName` in the default package) caused the `ClassNotFoundException`. **Solution Implemented:** The `JarArtifactCreator.create()` method has been modified. Before a `.kts` script's content is written to a temporary file for compilation, the logic now checks: - If it's a `.kts` file. - If kscript has determined a package name for it (either parsed or defaulted). - If the script content itself does not already start with a `package` declaration. If these conditions are met, the determined package declaration (e.g., `package kscript.scriplet;`) is prepended to the script content. This ensures that `kotlinc` compiles the `.kts` script's class into the same package that the wrapper expects, resolving the ClassNotFoundException. **Further Considerations for Full Robustness (Future Work):** While this commit fixes a critical classloading issue for `.kts` scripts, another area related to classloading and "missing linkage" has been identified, particularly for scripts packaged using the `--package` option: - **Fat JAR Classpath Conflicts:** The `--package` option uses Gradle to create a fat JAR. The current Gradle template uses `DuplicatesStrategy.INCLUDE`. This can lead to runtime issues (e.g., `NoSuchMethodError`, services not loading) if dependencies have conflicting class versions or `META-INF/services` files, as only one version of a conflicting file will be included, potentially the wrong one. - **Recommendation:** For more robust packaged scripts, the Gradle template should be updated to use a dedicated fat JAR plugin like `com.github.johnrengelman.shadow`, which offers better strategies for dependency conflict resolution and resource merging. This fix provides a significant improvement in the reliable execution of .kts files. Further work on the packaging mechanism can enhance robustness for distributed scripts.Configuration menu - View commit details
-
Copy full SHA for 48c185a - Browse repository at this point
Copy the full SHA 48c185aView commit details -
Merge pull request #3 from jnorthrup/fix/kts-classloader-linkage
fix: Resolve ClassNotFoundException for .kts scripts by ensuring pack…
Configuration menu - View commit details
-
Copy full SHA for 1507273 - Browse repository at this point
Copy the full SHA 1507273View commit details -
Fix: Resolve ClassNotFoundException for KTS scripts
This commit fixes a ClassNotFoundException that occurred when running KTS scripts. The issue was caused by your script class not being packaged into the scriplet.jar during compilation. The fix involves combining your script code and the wrapper code into a single string before compilation. This ensures that kotlinc treats them as a single compilation unit and packages all necessary classes into the resulting JAR. Specifically, the changes are: - In `JarArtifactCreator.kt`: - For KTS scripts, your script content and the generated wrapper content are now concatenated into a single string. - This combined string is written to a single temporary .kt file, which is then passed to the Kotlin compiler. - In `Templates.kt`: - `createWrapperForScript` now ensures the wrapper code has the correct package declaration, consistent with your script. This approach should resolve the ClassNotFoundException and allow KTS scripts to be compiled and executed correctly.
Configuration menu - View commit details
-
Copy full SHA for ebe1989 - Browse repository at this point
Copy the full SHA ebe1989View commit details -
Merge pull request #4 from jnorthrup/fix/classnotfound-exception
Fix: Resolve ClassNotFoundException for KTS scripts
Configuration menu - View commit details
-
Copy full SHA for b0b417f - Browse repository at this point
Copy the full SHA b0b417fView commit details -
feat: Update internal Kotlin version to 2.1.21-embedded
This commit updates the primary Kotlin version used by kscript for its own build and for the Gradle scripts it generates (e.g., for --idea and --package) from 1.7.21 to 2.1.21-embedded. Changes include: 1. **`build.gradle.kts`:** * The `kotlinVersion` property has been changed to "2.1.21-embedded". * The `kotlin("jvm")` plugin version has been updated to "2.1.21-embedded". * Dependencies on `org.jetbrains.kotlin:*` artifacts were already parameterized to use `kotlinVersion`, so they will automatically adopt the new version. 2. **`GradleTemplates.kt`:** * Verified that generated Gradle scripts for `--idea` and `--package` already use `KotlinVersion.CURRENT` to dynamically set their Kotlin plugin and `kotlin-script-runtime` versions. This ensures they will use the new "2.1.21-embedded" version. * Updated `kotlin-stdlib` declarations within these templates to also explicitly use the dynamic `kotlinVersion` for consistency and clarity. No other hardcoded references to the old Kotlin version were found in kscript's core operational code that required changes for this update. Runtime version information displayed to you (e.g., via `kscript --version`) should dynamically reflect this new version through `BuildConfig.KOTLIN_VERSION`.Configuration menu - View commit details
-
Copy full SHA for 0eb291c - Browse repository at this point
Copy the full SHA 0eb291cView commit details -
Merge pull request #5 from jnorthrup/fix/kts-classloader-linkage
feat: Update internal Kotlin version to 2.1.21-embedded
Configuration menu - View commit details
-
Copy full SHA for ad84dc2 - Browse repository at this point
Copy the full SHA ad84dc2View commit details -
feat: Add initial support for Python and NPM packaging
This change introduces the necessary files and build modifications to enable you to package kscript for Python (pip) and JavaScript (npm) environments. Key changes include: - Added Python wrapper script (`wrappers/kscript_py_wrapper.py`) to execute kscript.jar. - Added `setup.py` to define the Python package, making `kscript` available as a console script. - Added Node.js wrapper script (`wrappers/kscript_js_wrapper.js`) to execute kscript.jar. - Added `package.json` to define the NPM package, making `kscript` available via the bin field. - Modified `build.gradle.kts`: - To copy `kscript.jar` into the `wrappers/` directory. - To include `setup.py`, `package.json`, and the `wrappers/` directory (containing the JAR and wrapper scripts) in the main kscript distribution zip. - Added basic test scripts (`test/test_python_wrapper.py`, `test/test_js_wrapper.js`) to verify the functionality of the wrapper scripts with a sample kscript (`examples/test_wrapper.kts`). - Updated `README.adoc` with a new section detailing how you can build and install the Python and NPM packages from the distributed files. This provides a foundation for you if you wish to integrate kscript into Python or Node.js workflows by building the packages themselves from the kscript release distribution.Configuration menu - View commit details
-
Copy full SHA for 35a39db - Browse repository at this point
Copy the full SHA 35a39dbView commit details -
chore: Update Gradle wrapper to version 8.14.1
I've upgraded the Gradle wrapper to use Gradle version 8.14.1. This updates the `distributionUrl` in `gradle/wrapper/gradle-wrapper.properties` and ensures associated wrapper scripts are consistent. Using a more recent Gradle version helps with performance, compatibility with modern JDKs and Kotlin, and access to new Gradle features.
Configuration menu - View commit details
-
Copy full SHA for 5d78351 - Browse repository at this point
Copy the full SHA 5d78351View commit details -
Merge pull request #7 from jnorthrup/feat/python-npm-packaging
Feat/python npm packaging
Configuration menu - View commit details
-
Copy full SHA for 2af3bab - Browse repository at this point
Copy the full SHA 2af3babView commit details
Commits on Jun 6, 2025
-
Configuration menu - View commit details
-
Copy full SHA for 0e81106 - Browse repository at this point
Copy the full SHA 0e81106View commit details -
docs: Modernize and simplify README.adoc
Updated README.adoc to provide more current information and accurately reflect the project's state in 2024. Key changes include: - Introduction: Replaced outdated "Good News about Kotlin 1.4 scripting" section with a more timeless description of kscript's value. Removed a very dated (2017) conference link. - Installation: - Added a note clarifying that package manager versions (SDKMAN, Homebrew, Scoop) may not be the absolute latest, and recommending the "Build it yourself" section for cutting-edge use. - Updated the "Build it yourself" section to encourage its use for modern Kotlin/Java versions (e.g., Kotlin 2.2.0+, Java 21+), and to note JDK requirements. - Script Configuration / Annotations: - Added a cautionary note regarding the age of the `kscript-annotations:1.5` artifact and potential compatibility considerations with modern Kotlin 2.x. - Clarified that kscript historically used v1.5 internally. - Feature Descriptions: - Verified that no unmerged/non-existent features like Proguard were mentioned (none were, so no changes needed on this point). - How to contribute?: - Removed outdated, specific YouTrack issue links from 2017-2019. - Replaced with general guidance to use the kscript GitHub issue tracker and the official JetBrains YouTrack for IDE/Kotlin issues. - FAQ: - Updated the answer comparing Kotlin and Python scripting performance to be more nuanced and cover JVM startup/compilation overhead vs. peak performance. These changes aim to improve clarity, set realistic expectations for you, and ensure the documentation is more helpful and up-to-date.Configuration menu - View commit details
-
Copy full SHA for 8f5f461 - Browse repository at this point
Copy the full SHA 8f5f461View commit details -
feat: Implement --export-to-gradle-project feature
This commit introduces the new command-line option `--export-to-gradle-project <script> <output_dir>`, which allows you to generate a complete, standalone Gradle project from an existing kscript file. This "last mile toolkit" feature facilitates graduating a kscript into a more formal project structure, ready for further development, testing, and packaging using standard Gradle workflows. Key functionalities implemented in `ProjectGenerator.kt`: - Parses the input kscript for dependencies, Maven repositories, package name, and entry point using kscript's internal resolvers. - Creates the specified output directory. - Determines project properties (group, name, version), intelligently deriving the group and main class from script annotations or defaults. - Generates `settings.gradle.kts` with the project name. - Generates a comprehensive `build.gradle.kts` including: - Kotlin JVM and Application plugins (using kscript's own Kotlin version, e.g., 2.2.0-RC2, and targeting Java 21). - Project group and version. - Maven Central and any custom repositories from the script. - Kotlin standard library and all dependencies from the script. - Application main class configuration. - Standard Kotlin compiler options and Java toolchain settings. - Creates the standard Maven/Gradle directory structure: - `src/main/kotlin/[package_path]` - `src/main/resources` - `src/test/kotlin/[package_path]` - `src/test/resources` - Transforms the original kscript content by: - Removing the shebang and kscript-specific file-level annotations. - Adding an appropriate package declaration. - Saves the result as a `.kt` file within `src/main/kotlin/[package_path]`. - Generates a `.gitignore` file with common Kotlin/Gradle patterns. - Copies and configures the Gradle Wrapper (`gradlew`, `gradlew.bat`, `gradle/wrapper/*`) from kscript's own project, ensuring the generated project uses a consistent and recent Gradle version (e.g., 8.14.1). The command-line interface in `Kscript.kt` and option parsing in `OptionsUtils.kt` have been updated to support this new feature.Configuration menu - View commit details
-
Copy full SHA for 2b7c5db - Browse repository at this point
Copy the full SHA 2b7c5dbView commit details -
feat: Use
@file:ProjectCoordinatesin--export-to-gradle-projectThis commit enhances the `--export-to-gradle-project` feature by allowing kscripts to define their own target Maven coordinates (groupId, artifactId, version) via a new `@file:ProjectCoordinates` annotation. Key changes: 1. **Annotation Parsing (`Script.kt`, `Parser.kt`, `model/ProjectCoordinates.kt`):** - I introduced a new data class `model.ProjectCoordinates` to hold `group`, `artifact`, and `version`. - The `Script` model now includes an optional `projectCoordinates` field. - I updated `LineParser.kt` and `Parser.kt` to recognize and parse `@file:ProjectCoordinates(group="...", artifact="...", version="...")` annotations from script files. - The parsed coordinates are stored in the `Script` object via `ResolutionContext` and `SectionResolver`. 2. **Project Generation (`generator/ProjectGenerator.kt`):** - The `exportToGradleProject` function now retrieves any `ProjectCoordinates` defined in the script. - These script-defined coordinates are prioritized when setting: - `group` in `build.gradle.kts`. - `version` in `build.gradle.kts`. - `rootProject.name` in `settings.gradle.kts` (derived from the artifactId). - Fallback logic (using script package name, output directory name, or defaults) is retained if the annotation or specific attributes are missing. - The package path for source files (`src/main/kotlin/...`, `src/test/kotlin/...`) and the `package` declaration in the generated `.kt` file are now based on the `effectiveProjectGroup` (derived from the annotation or fallbacks). - Default `mainClassName` derivation also uses `effectiveProjectGroup`. This makes the project generation feature more declarative, allowing the script itself to be the source of truth for its intended Maven identity when being "graduated" into a full Gradle project.Configuration menu - View commit details
-
Copy full SHA for 528edfa - Browse repository at this point
Copy the full SHA 528edfaView commit details -
Merge pull request #8 from jnorthrup/feat/python-npm-packaging
Feat/python npm packaging
Configuration menu - View commit details
-
Copy full SHA for 9f945de - Browse repository at this point
Copy the full SHA 9f945deView commit details -
Configuration menu - View commit details
-
Copy full SHA for 64f1315 - Browse repository at this point
Copy the full SHA 64f1315View commit details -
Configuration menu - View commit details
-
Copy full SHA for 92d5da6 - Browse repository at this point
Copy the full SHA 92d5da6View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1840f7c - Browse repository at this point
Copy the full SHA 1840f7cView commit details
Commits on Jun 7, 2025
-
Add support for profiling and instrumentation
This change introduces a basic framework for bytecode transformation using ASM. As a proof-of-concept, it adds a simple profiling transformation that prints a message at the beginning of every function call. The transformation is implemented by: 1. Modifying `JarArtifactCreator.kt` to unpack the JAR created by `kotlinc`, apply the transformation to the .class files, and then re-pack the JAR. 2. Adding a `ProfilingClassVisitor` and `ProfilingMethodVisitor` to insert the necessary bytecode instructions. An integration test is included to verify that the profiling messages are printed correctly.
Configuration menu - View commit details
-
Copy full SHA for bb99eab - Browse repository at this point
Copy the full SHA bb99eabView commit details -
Add support for profiling and instrumentation
This change introduces a basic framework for bytecode transformation using ASM. As a proof-of-concept, it adds a simple profiling transformation that prints a message at the beginning of every function call. The transformation is implemented by: 1. Modifying `JarArtifactCreator.kt` to unpack the JAR created by `kotlinc`, apply the transformation to the .class files, and then re-pack the JAR. 2. Adding a `ProfilingClassVisitor` and `ProfilingMethodVisitor` to insert the necessary bytecode instructions. An integration test is included to verify that the profiling messages are printed correctly.
Configuration menu - View commit details
-
Copy full SHA for dd7e294 - Browse repository at this point
Copy the full SHA dd7e294View commit details -
Merge pull request #10 from jnorthrup/profiling-instrumentation
Profiling instrumentation
Configuration menu - View commit details
-
Copy full SHA for b8fd47f - Browse repository at this point
Copy the full SHA b8fd47fView commit details
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff master...master