Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add directory creator API for making files executable #392

Merged
merged 1 commit into from
Feb 28, 2025
Merged
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 @@ -4,8 +4,13 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.util.LinkedHashSet;
import java.util.Set;

import com.g2forge.alexandria.java.core.resource.IResource;
import com.g2forge.alexandria.java.function.IConsumer1;
Expand All @@ -26,17 +31,22 @@ public class DirectoryCreator {
protected static class FileCreator implements IFileCreator {
protected final Path path;

@Getter(lazy = true)
@ToString.Exclude
private final IFileModifier modifier = new FileModifier(getPath());

@Override
public void empty() {
public IFileModifier empty() {
try {
Files.createFile(getPath());
} catch (IOException e) {
throw new RuntimeIOException(e);
}
return getModifier();
}

@Override
public void from(InputStream source) {
public IFileModifier from(InputStream source) {
try {
try (final OutputStream output = Files.newOutputStream(getPath())) {
HBinaryIO.copy(source, output);
Expand All @@ -50,25 +60,57 @@ public void from(InputStream source) {
throw new RuntimeIOException(e);
}
}
return getModifier();
}

@Override
public void from(Path source) {
public IFileModifier from(Path source) {
HFile.copy(source, getPath());
return getModifier();
}
}

@Getter(AccessLevel.PROTECTED)
@ToString
@RequiredArgsConstructor
protected static class FileModifier implements IFileModifier {
protected final Path path;

@Override
public IFileModifier with(IConsumer1<? super Path> modifier) {
modifier.accept(getPath());
return this;
}
}

public interface IFileCreator {
public void empty();
public IFileModifier empty();

public IFileModifier from(InputStream source);

public void from(InputStream source);
public default IFileModifier from(IResource source) {
return from(source.getResourceAsStream(true));
}

public default void from(IResource source) {
from(source.getResourceAsStream(true));
public IFileModifier from(Path source);
}

public interface IFileModifier {
public default IFileModifier executable() {
return with(path -> {
try {
final PosixFileAttributeView view = Files.getFileAttributeView(path, PosixFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
if (view != null) {
final Set<PosixFilePermission> permissions = new LinkedHashSet<>(view.readAttributes().permissions());
if (permissions.add(PosixFilePermission.OWNER_EXECUTE)) view.setPermissions(permissions);
}
} catch (IOException exception) {
throw new RuntimeIOException(String.format("Failed to make %1$s executable by owner!", path), exception);
}
});
}

public void from(Path source);
public IFileModifier with(IConsumer1<? super Path> modifier);
}

public static void create(Path path, IConsumer1<DirectoryCreator> consumer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ public void empty() throws IOException {
Assert.assertEquals(0l, Files.size(file));
}

@Test
public void executable() throws IOException {
final Path root = temp.get().resolve("executable");
DirectoryCreator.create(root, d0 -> {
d0.file("file").empty().executable();
});
Assert.assertTrue(Files.isDirectory(root));
final Path file = root.resolve("file");
Assert.assertTrue(Files.isRegularFile(file));
Assert.assertEquals(0l, Files.size(file));
}

@Test
public void nop() {
final Path root = temp.get().resolve("nop");
Expand Down Expand Up @@ -91,7 +103,7 @@ public void pathErrorNotNested() {
});
Assert.fail();
} catch (IllegalArgumentException exception) {
//Assert.assertTrue(exception.getMessage().contains("outside"));
// Assert.assertTrue(exception.getMessage().contains("outside"));
}
}

Expand Down