Skip to content

Commit

Permalink
devonfw#132: removed experimental zip extraction code, added tests
Browse files Browse the repository at this point in the history
- removed the code I experimented with regarding the Zip extraction, which will probably get addressed in a different PR.
- the tar extraction tests now test NONE, GZ, and BZIP2 compression
  • Loading branch information
MattesMrzik committed Jan 18, 2024
1 parent 5b01c5f commit 761ef61
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 32 deletions.
8 changes: 0 additions & 8 deletions cli/src/main/java/com/devonfw/tools/ide/io/FileAccess.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.devonfw.tools.ide.io;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import java.nio.file.Path;
import java.util.function.Predicate;

Expand Down Expand Up @@ -125,13 +124,6 @@ default void copy(Path source, Path target) {
*/
Path toRealPath(Path path);

/**
* @param permissionInt The integer as returned by {@link TarArchiveEntry#getMode()} that represents the file
* permissions of a file on a Unix file system.
* @return A String representing the file permissions. E.g. "rwxrwxr-x" or "rw-rw-r--"
*/
String generatePermissionString(int permissionInt);

/**
* Deletes the given {@link Path} idempotent and recursive.
*
Expand Down
25 changes: 11 additions & 14 deletions cli/src/main/java/com/devonfw/tools/ide/io/FileAccessImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

import com.devonfw.tools.ide.context.IdeContext;
Expand Down Expand Up @@ -499,7 +498,12 @@ public void untar(Path file, Path targetDir, TarCompression compression) {
unpack(file, targetDir, in -> new TarArchiveInputStream(compression.unpack(in)));
}

public String generatePermissionString(int permissions) {
/**
* @param permissions The integer as returned by {@link TarArchiveEntry#getMode()} that represents the file
* permissions of a file on a Unix file system.
* @return A String representing the file permissions. E.g. "rwxrwxr-x" or "rw-rw-r--"
*/
public static String generatePermissionString(int permissions) {

// Ensure that only the last 9 bits are considered
permissions &= 0b111111111;
Expand All @@ -521,18 +525,9 @@ private void unpack(Path file, Path targetDir, Function<InputStream, ArchiveInpu
try (InputStream is = Files.newInputStream(file); ArchiveInputStream ais = unpacker.apply(is)) {
ArchiveEntry entry = ais.getNextEntry();
boolean isTar = ais instanceof TarArchiveInputStream;
boolean isZip = ais instanceof ZipArchiveInputStream;
while (entry != null) {
String permissionStr = null;
if (isZip) {
// TODO ZipArchiveInputStream is unable to fill this field, you must use ZipFile if you want to read entries
// using this attribute (getExternalAttributes).
int unixMode = ((int) ((ZipArchiveEntry) entry).getExternalAttributes() >> 16) & 0xFFFF;
// unixMode always zero since ZipArchiveInputStream does not read getExternalAttributes()
System.out.println("File: " + ((ZipArchiveEntry) entry).getName());
System.out.println("Unix Mode: " + unixMode);
System.out.println("Unix Mode octal: " + Integer.toOctalString(unixMode));
} else if (isTar) {
if (isTar) {
int tarMode = ((TarArchiveEntry) entry).getMode();
permissionStr = generatePermissionString(tarMode);
}
Expand All @@ -549,8 +544,10 @@ private void unpack(Path file, Path targetDir, Function<InputStream, ArchiveInpu
mkdirs(entryPath.getParent());
Files.copy(ais, entryPath);
}
Set<PosixFilePermission> permissions = PosixFilePermissions.fromString(permissionStr);
Files.setPosixFilePermissions(entryPath, permissions);
if (isTar) {
Set<PosixFilePermission> permissions = PosixFilePermissions.fromString(permissionStr);
Files.setPosixFilePermissions(entryPath, permissions);
}
entry = ais.getNextEntry();
}
} catch (IOException e) {
Expand Down
75 changes: 65 additions & 10 deletions cli/src/test/java/com/devonfw/tools/ide/io/FileAccessImplTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.devonfw.tools.ide.io;

import static com.devonfw.tools.ide.io.FileAccessImpl.generatePermissionString;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;
Expand Down Expand Up @@ -475,20 +475,38 @@ private void assertSymlinkRead(Path link, Path trueTarget) {
}

/**
* Test of {@link FileAccessImpl#untar(Path, Path, TarCompression)} and checks if file permissions are preserved on
* Linux
* Test of {@link FileAccessImpl#untar(Path, Path, TarCompression)} with {@link TarCompression#NONE} and checks if
* file permissions are preserved on Unix.
*/
@Test
public void testUntarWithFilePermissions(@TempDir Path tempDir) {
// TODO test:
// NONE -> not yet checked
// GZ, -> checked
// BZIP2 -> not yet checked
public void testUntarWithNoneCompressionWithFilePermissions(@TempDir Path tempDir) {

// arrange
IdeContext context = IdeTestContextMock.get();
// TODO I think these are not relevant on Windows. But what about MacOS?
if (!context.getSystemInfo().isLinux()) {
if (context.getSystemInfo().isWindows()) {
return;
}

// act
context.getFileAccess().untar(
Path.of("src/test/resources/com/devonfw/tools/ide/io").resolve("executable_and_non_executable.tar"), tempDir,
TarCompression.NONE);

// assert
assertPosixFilePermissions(tempDir.resolve("executableFile.txt"), "rwxrwxr-x");
assertPosixFilePermissions(tempDir.resolve("nonExecutableFile.txt"), "rw-rw-r--");
}

/**
* Test of {@link FileAccessImpl#untar(Path, Path, TarCompression)} with {@link TarCompression#GZ} and checks if file
* permissions are preserved on Unix.
*/
@Test
public void testUntarWithGzCompressionWithFilePermissions(@TempDir Path tempDir) {

// arrange
IdeContext context = IdeTestContextMock.get();
if (context.getSystemInfo().isWindows()) {
return;
}

Expand All @@ -502,6 +520,29 @@ public void testUntarWithFilePermissions(@TempDir Path tempDir) {
assertPosixFilePermissions(tempDir.resolve("nonExecutableFile.txt"), "rw-rw-r--");
}

/**
* Test of {@link FileAccessImpl#untar(Path, Path, TarCompression)} with {@link TarCompression#BZIP2} and checks if
* file permissions are preserved on Unix.
*/
@Test
public void testUntarWithBzip2CompressionWithFilePermissions(@TempDir Path tempDir) {

// arrange
IdeContext context = IdeTestContextMock.get();
if (context.getSystemInfo().isWindows()) {
return;
}

// act
context.getFileAccess().untar(
Path.of("src/test/resources/com/devonfw/tools/ide/io").resolve("executable_and_non_executable.tar.bz2"),
tempDir, TarCompression.BZIP2);

// assert
assertPosixFilePermissions(tempDir.resolve("executableFile.txt"), "rwxrwxr-x");
assertPosixFilePermissions(tempDir.resolve("nonExecutableFile.txt"), "rw-rw-r--");
}

private void assertPosixFilePermissions(Path file, String permissions) {

try {
Expand All @@ -513,4 +554,18 @@ private void assertPosixFilePermissions(Path file, String permissions) {
}
}

/**
* Test of {@link FileAccessImpl#generatePermissionString(int)}.
*/
@Test
public void testGeneratePermissionString() {

assertThat(generatePermissionString(0)).isEqualTo("---------");
assertThat(generatePermissionString(436)).isEqualTo("rw-rw-r--");
assertThat(generatePermissionString(948)).isEqualTo("rw-rw-r--");
assertThat(generatePermissionString(509)).isEqualTo("rwxrwxr-x");
assertThat(generatePermissionString(511)).isEqualTo("rwxrwxrwx");

}

}
Binary file not shown.
Binary file not shown.

0 comments on commit 761ef61

Please sign in to comment.