Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,35 @@ synchronized File extractPackage() throws IOException {
}

File execDir = targetPath.resolve("dart-sass").toFile();
File result = findExecutable(execDir);

File[] execFile = execDir.listFiles(pathname -> pathname.isFile() && pathname.getName().startsWith("sass"));

File result;
if (result == null && !IOUtils.isEmpty(targetPath)) {
log.info("No unique dart-sass executable found in {}, extracting {} again", execDir, dist);
try {
IOUtils.extract(dist, targetPath);
} catch (IOException e) {
throw new IOException(String.format("Failed to extract %s into %s", dist, targetPath), e);
}
result = findExecutable(execDir);
}

if (execFile == null || execFile.length != 1) {
if (result == null) {
throw new IllegalStateException("No (unique) executable file found in " + execDir);
} else {
result = execFile[0];
}

result.setExecutable(true, true);
return result;
}

private File findExecutable(File execDir) {
File[] execFile = execDir.listFiles(pathname -> pathname.isFile() && pathname.getName().startsWith("sass"));
if (execFile == null || execFile.length != 1) {
return null;
}

return execFile[0];
}

Path getTargetPath() throws IOException {
String dartSassVersion = PropertyUtils.getDartSassVersion();
String hostVersion = PropertyUtils.getHostVersion();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,17 @@
import de.larsgrefer.sass.embedded.SassCompilerFactory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import javax.annotation.Nullable;
import java.io.File;
import java.io.OutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
Expand Down Expand Up @@ -33,4 +42,55 @@ void testConcurrentAccess() throws IOException {
}

}
}

@Test
void extractPackageRestoresMissingExecutable(@TempDir Path tempDir) throws IOException {
Path archive = tempDir.resolve("dart-sass.zip");
createDartSassZip(archive);

Path targetPath = tempDir.resolve("target");
DartSassPackageProvider provider = new TestPackageProvider(archive.toUri().toURL(), targetPath);

File executable = provider.extractPackage();
assertThat(executable).isFile();

Files.delete(executable.toPath());
Files.write(targetPath.resolve("dart-sass").resolve("kept-by-temp-cleaner"), new byte[0]);

File restoredExecutable = provider.extractPackage();
assertThat(restoredExecutable).isFile();
}

private void createDartSassZip(Path archive) throws IOException {
try (OutputStream outputStream = Files.newOutputStream(archive);
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
zipOutputStream.putNextEntry(new ZipEntry("dart-sass/"));
zipOutputStream.closeEntry();
zipOutputStream.putNextEntry(new ZipEntry("dart-sass/sass"));
zipOutputStream.write(new byte[]{1});
zipOutputStream.closeEntry();
}
}

private static class TestPackageProvider extends DartSassPackageProvider {

private final URL packageUrl;
private final Path targetPath;

TestPackageProvider(URL packageUrl, Path targetPath) {
this.packageUrl = packageUrl;
this.targetPath = targetPath;
}

@Override
Path getTargetPath() {
return targetPath;
}

@Nullable
@Override
protected URL getPackageUrl() {
return packageUrl;
}
}
}