diff --git a/.gitignore b/.gitignore
index ac7a7af1..bb2c3441 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,4 @@ asset-pipeline-site/src/assets/html/apidoc/
.jruby-container
.sass-cache
.sass-work
+.shelf/
diff --git a/asset-pipeline-core.ipr b/asset-pipeline-core.ipr
index 2775d189..ea652b92 100644
--- a/asset-pipeline-core.ipr
+++ b/asset-pipeline-core.ipr
@@ -360,9 +360,12 @@
+
-
+
+
+
@@ -1476,7 +1479,6 @@
-
@@ -1567,7 +1569,6 @@
-
@@ -1699,7 +1700,6 @@
-
@@ -1709,7 +1709,6 @@
-
@@ -2214,7 +2213,6 @@
-
@@ -2925,7 +2923,6 @@
-
diff --git a/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/NativeLibraryLoader.groovy b/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/NativeLibraryLoader.groovy
new file mode 100644
index 00000000..5f7f9e1e
--- /dev/null
+++ b/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/NativeLibraryLoader.groovy
@@ -0,0 +1,100 @@
+package asset.pipeline.dart
+
+import asset.pipeline.AssetPipelineConfigHolder
+import com.caoccao.javet.enums.JSRuntimeType
+import com.caoccao.javet.interop.loader.JavetLibLoader
+import groovy.transform.CompileStatic
+import groovy.util.logging.Slf4j
+
+import java.nio.channels.Channels
+import java.nio.channels.FileChannel
+import java.nio.channels.ReadableByteChannel
+import java.util.jar.JarEntry
+import java.util.jar.JarFile
+
+import static com.caoccao.javet.utils.JavetOSUtils.*
+
+@Slf4j
+@CompileStatic
+class NativeLibraryLoader {
+ static final String JAVET_VERSION = NativeLibraryLoader.class.classLoader.getResource("javet-version.txt").openStream().text
+ static final String BASE_URL = AssetPipelineConfigHolder.config?.javetBaseUrl ?: "https://repo1.maven.org/maven2/com/caoccao/javet"
+
+ final JavetLibLoader javetLibLoader
+
+ NativeLibraryLoader(JSRuntimeType jsRuntimeType) {
+ javetLibLoader = new JavetLibLoader(jsRuntimeType)
+ }
+
+ private URL getJavetJARUrl() {
+ new URL("${BASE_URL}/${javetPackageName}/${JAVET_VERSION}/${getJavetFileName()}")
+ }
+
+ private String getJavetPackageName() {
+ IS_MACOS ? "javet-macos" : "javet"
+ }
+
+ private String getJavetFileName() {
+ "${javetPackageName}-${JAVET_VERSION}.jar"
+ }
+
+ /**
+ * The native libraries are packed in the Javet platform specific jars. First we need to download the correct JAR
+ * for this platform and then we will extract the native library from it and into a temporary directory for loading.
+ *
+ * @return the downloaded Javet jar file for this platform
+ */
+ private File downloadJavetJar() {
+ File jarFile = new File(TEMP_DIRECTORY, javetFileName)
+ if (jarFile.exists()) {
+ log.debug("Jar file ${jarFile.path} exists, skipping download")
+ return jarFile
+ }
+
+ // Download the file
+ URL jarUrl = getJavetJARUrl()
+ log.info("Downloading sass-dart native library integration: ${jarUrl}")
+
+ copyToFile(jarUrl.openStream(), jarFile)
+
+ log.debug("Downloaded $jarUrl to $jarFile (${jarFile.size()} bytes)")
+ jarFile
+ }
+
+ private void copyToFile(InputStream inputStream, File targetFile) {
+ ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream)
+ FileOutputStream fileOutputStream = new FileOutputStream(targetFile)
+ FileChannel fileChannel = fileOutputStream.getChannel()
+ fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE)
+ }
+
+ /**
+ * A file reference to the platform and arch specific native library needed.
+ * @return the required native library for v8 integration
+ */
+ File extractNativeLibrary() {
+ File file = downloadJavetJar()
+ if (!file.exists()) {
+ throw new IllegalStateException("Javet jar file $file does not exist, perhaps the download failed")
+ }
+
+ String libraryName = javetLibLoader.libFileName
+ File jniLibrary = new File(TEMP_DIRECTORY, libraryName)
+ if (jniLibrary.exists()) {
+ log.debug("Native library $libraryName already exists, skipping extract")
+ return jniLibrary
+ }
+
+ // Extract from the JAR file, should be in the root
+ JarFile jarFile = new JarFile(file)
+ JarEntry jarEntry = jarFile.getJarEntry(libraryName)
+ if (!jarEntry) {
+ throw new IllegalStateException("Could not load native library: $libraryName")
+ }
+
+ copyToFile(jarFile.getInputStream(jarEntry), jniLibrary)
+
+ log.debug("Extracted native library $libraryName to ${jniLibrary.path}")
+ jniLibrary
+ }
+}
diff --git a/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/NativeLibraryUtil.groovy b/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/NativeLibraryUtil.groovy
deleted file mode 100644
index 2d762a31..00000000
--- a/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/NativeLibraryUtil.groovy
+++ /dev/null
@@ -1,106 +0,0 @@
-package asset.pipeline.dart
-
-import asset.pipeline.AssetPipelineConfigHolder
-import com.caoccao.javet.enums.JSRuntimeType
-import groovy.transform.CompileStatic
-import groovy.util.logging.Slf4j
-
-import java.nio.channels.Channels
-import java.nio.channels.FileChannel
-import java.nio.channels.ReadableByteChannel
-import java.nio.file.Files
-import java.nio.file.Paths
-import java.nio.file.StandardCopyOption
-import java.util.jar.JarEntry
-import java.util.jar.JarFile
-
-@Slf4j
-@CompileStatic
-class NativeLibraryUtil {
- static final String JAVET_VERSION = NativeLibraryUtil.class.classLoader.getResource("javet-version.txt").openStream().text
- static final String BASE_URL = AssetPipelineConfigHolder.config?.javetBaseUrl ?: "https://repo1.maven.org/maven2/com/caoccao/javet/javet-macos/${JAVET_VERSION}/"
-
- static final String TMP_DIR = System.getProperty("java.io.tmpdir")
- static final String OS_ARCH = System.getProperty("os.arch")
- static final String OS_NAME = System.getProperty("os.name")
-
- static final boolean IS_LINUX = OS_NAME.startsWith("Linux")
- static final boolean IS_MACOS = OS_NAME.startsWith("Mac OS")
- static final boolean IS_WINDOWS = OS_NAME.startsWith("Windows")
- static final boolean IS_ARM64 = OS_ARCH.startsWith("arm64") || OS_ARCH.startsWith("armv8") || OS_ARCH == "aarch64"
- static final boolean IS_X86_64 = OS_ARCH.matches(/^(x8664|amd64|ia32e|em64t|x64|x86_64)$/)
-
- static final String ARCH_NAME = IS_ARM64 ? 'arm64' : 'x86_64'
-
- static URL getJavetJARUrl() {
- new URL(BASE_URL + getJavetFileName())
- }
-
- static String getJavetFileName() {
- IS_MACOS ? "javet-macos-${JAVET_VERSION}.jar" : "javet-${JAVET_VERSION}.jar"
- }
-
- static String getLibraryName(JSRuntimeType runtimeType) {
- if (IS_MACOS) {
- return "libjavet-${runtimeType.name}-macos-${ARCH_NAME}.v.${JAVET_VERSION}.dylib"
- }
- if (IS_LINUX) {
- return "libjavet-${runtimeType.name}-linux-${ARCH_NAME}.v.${JAVET_VERSION}.so"
- }
- if (IS_WINDOWS) {
- return "libjavet-${runtimeType.name}-windows-${ARCH_NAME}.v.${JAVET_VERSION}.dll"
- }
-
- throw new IllegalStateException("Platform type not supported: ${OS_NAME} (${OS_ARCH}), expected Mac OS, Linux, or Windows")
- }
-
- static File downloadJavetJar(JSRuntimeType runtimeType) {
- File jarFile = new File(TMP_DIR, javetFileName)
- if (jarFile.exists()) {
- log.debug("Jar file ${jarFile.path} exists, skipping download")
- return jarFile
- }
-
- // Download the file
- URL jarUrl = getJavetJARUrl()
- log.info("Downloading sass-dart native library integration: ${jarUrl}")
-
- copyToFile(jarUrl.openStream(), jarFile)
-
- log.debug("Downloaded $jarUrl to $jarFile (${jarFile.size()} bytes)")
- jarFile
- }
-
- static File extractNativeLibrary(JSRuntimeType runtimeType) {
- File file = downloadJavetJar(runtimeType)
- if (!file.exists()) {
- throw new IllegalStateException("Javet jar file $file does not exist, perhaps the download failed")
- }
-
- String libraryName = getLibraryName(runtimeType)
- File jniLibrary = new File(TMP_DIR, libraryName)
- if (jniLibrary.exists()) {
- log.debug("Native library $libraryName already exists, skipping extract")
- return jniLibrary
- }
-
- // Extract from the JAR file, should be in the root
- JarFile jarFile = new JarFile(file)
- JarEntry jarEntry = jarFile.getJarEntry(libraryName)
- if (!jarEntry) {
- throw new IllegalStateException("Could not load native library: $libraryName")
- }
-
- copyToFile(jarFile.getInputStream(jarEntry), jniLibrary)
-
- log.debug("Extracted native library $libraryName to ${jniLibrary.path}")
- jniLibrary
- }
-
- static private void copyToFile(InputStream inputStream, File targetFile) {
- ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream)
- FileOutputStream fileOutputStream = new FileOutputStream(targetFile)
- FileChannel fileChannel = fileOutputStream.getChannel()
- fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE)
- }
-}
diff --git a/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/SassProcessor.groovy b/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/SassProcessor.groovy
index 68170e1d..dce63c5f 100644
--- a/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/SassProcessor.groovy
+++ b/sass-dart-asset-pipeline/src/main/groovy/asset/pipeline/dart/SassProcessor.groovy
@@ -33,7 +33,7 @@ class SassProcessor extends AbstractProcessor {
final String sassCompiler
static {
- File nativeLibrary = NativeLibraryUtil.extractNativeLibrary(JSRuntimeType.Node)
+ File nativeLibrary = new NativeLibraryLoader(JSRuntimeType.Node).extractNativeLibrary()
// Override Javet to use the library that we downloaded for this platform
JavetLibLoader.setLibLoadingListener(new IJavetLibLoadingListener() {
diff --git a/sass-dart-asset-pipeline/src/test/groovy/asset/pipeline/dart/SassProcessorSpec.groovy b/sass-dart-asset-pipeline/src/test/groovy/asset/pipeline/dart/SassProcessorSpec.groovy
index c4f9b4e2..b1aaf67c 100644
--- a/sass-dart-asset-pipeline/src/test/groovy/asset/pipeline/dart/SassProcessorSpec.groovy
+++ b/sass-dart-asset-pipeline/src/test/groovy/asset/pipeline/dart/SassProcessorSpec.groovy
@@ -26,10 +26,13 @@ import spock.lang.Specification
*/
class SassProcessorSpec extends Specification {
+ void setup() {
+ AssetPipelineConfigHolder.config = [:]
+ }
+
void "should compile sass into css"() {
given:
AssetPipelineConfigHolder.resolvers = []
- AssetPipelineConfigHolder.config = [:]
AssetPipelineConfigHolder.registerResolver(new FileSystemAssetResolver('test','assets'))
def assetFile = AssetHelper.fileForFullName('test.scss')
def processor = new SassProcessor()
@@ -42,7 +45,6 @@ class SassProcessorSpec extends Specification {
void "should compile nested sass into css"() {
given:
AssetPipelineConfigHolder.resolvers = []
- AssetPipelineConfigHolder.config = [:]
AssetPipelineConfigHolder.registerResolver(new FileSystemAssetResolver('test','assets'))
def assetFile = AssetHelper.fileForFullName('partials/forms.scss')
def processor = new SassProcessor()
@@ -55,7 +57,6 @@ class SassProcessorSpec extends Specification {
void "should compile nested foo into css"() {
given:
AssetPipelineConfigHolder.resolvers = []
- AssetPipelineConfigHolder.config = [:]
AssetPipelineConfigHolder.registerResolver(new FileSystemAssetResolver('test','assets'))
def assetFile = AssetHelper.fileForFullName('foo/foo.scss')
def processor = new SassProcessor()
@@ -68,7 +69,6 @@ class SassProcessorSpec extends Specification {
void "should compile Bourbon"() {
given:
AssetPipelineConfigHolder.resolvers = []
- AssetPipelineConfigHolder.config = [:]
AssetPipelineConfigHolder.registerResolver(new FileSystemAssetResolver('test', 'assets'))
def assetFile = AssetHelper.fileForFullName('bourbon-test.scss')
def processor = new SassProcessor()
@@ -81,7 +81,6 @@ class SassProcessorSpec extends Specification {
void "should compile Bootstrap v4"() {
given:
AssetPipelineConfigHolder.resolvers = []
- AssetPipelineConfigHolder.config = [:]
AssetPipelineConfigHolder.registerResolver(new FileSystemAssetResolver('test', 'assets'))
def assetFile = AssetHelper.fileForFullName('bootstrap/bootstrap.scss')
def processor = new SassProcessor()