fix new extract logic#996
Conversation
|
I love that non-archives are flattened by default, so, I'll investigate further into landlock to see if it's possible to workaround this, if not we are merging. I'd like a workaround like:
That'd be slightly more complex since our Landlock implementation would need to be aware of whether or not we are about to decompress a single-file format (non-archive), and also, know that path. But if we achieve that we don't have to tweak this behavior. |
|
I think you are right that this can be avoided. I will need to check again if its worth it but it also depends on the archive format; Can you tell me what use case you would like to see supported? |
Yeah, when I mentioned a workaround, I was strictly thinking about this scenario. But,
This ⬆️ is usually not the case anymore. Please correct me if I'm wrong, but in the latest Decompression will happen inside a new directory unless one of these scenarios happen:
In summary, when decompression in $CWD happens:
And, I believe this PR doesn't tackle these 3 because it was based on an assumption for something that changed recently, can you confirm if that's right? |
|
Here's a Nushell script I used to confirm that the latest version already keeps single-file archives under a new directory: Detailslet work = ($env.PWD | path join "ouch-pr-996-behavior")
rm -rf $work
mkdir $work
cd $work
git clone https://github.com/ouch-org/ouch.git repo
cd repo
git fetch origin main "+pull/996/head:refs/heads/pr-996"
let exe = if $nu.os-info.name == "windows" { "ouch.exe" } else { "ouch" }
mkdir ../bin
git switch --detach origin/main
cargo build --locked
cp (["target", "debug", $exe] | path join) (["..", "bin", $"ouch-main-($exe)"] | path join)
git switch --detach pr-996
cargo build --locked
cp (["target", "debug", $exe] | path join) (["..", "bin", $"ouch-pr996-($exe)"] | path join)
cd ..
let main_bin = ([$work, "bin", $"ouch-main-($exe)"] | path join)
let pr_bin = ([$work, "bin", $"ouch-pr996-($exe)"] | path join)
mkdir fixtures/src
"single contents" | save -f fixtures/src/single.txt
"same basename contents" | save -f fixtures/src/same
"plain gzip contents" | save -f fixtures/src/plain.txt
mkdir fixtures/src/wrapped
"wrapped contents" | save -f fixtures/src/wrapped/file.txt
^$main_bin --yes c fixtures/src/single.txt fixtures/single.zip
^$main_bin --yes c fixtures/src/same fixtures/same.zip
^$main_bin --yes c fixtures/src/wrapped fixtures/wrapped.zip
^$main_bin --yes c fixtures/src/plain.txt fixtures/plain.txt.gz
def snapshot [dir] {
let prev = $env.PWD
cd $dir
let rows = (
ls -a **/*
| each { |it|
let name = ($it.name | str replace -a "\\" "/")
if $it.type == dir { $"($name)/" } else { $name }
}
| sort
)
cd $prev
$rows
}
def run-one [bin branch case] {
let dir = (["runs", $branch, $case.name] | path join)
rm -rf $dir
mkdir $dir
cp $case.archive $dir
if $case.name == "merge-existing-output-dir" {
mkdir ($dir | path join "single")
"pre-existing" | save -f (($dir | path join "single" | path join "marker.txt"))
}
let prev = $env.PWD
cd $dir
^$bin --yes d ($case.archive | path basename) ...$case.args
rm -f ($case.archive | path basename)
cd $prev
{ branch: $branch, case: $case.name, tree: (snapshot $dir | str join ", ") }
}
def run-all [bin branch] {
let cases = [
{ name: "default-single-file-archive", archive: "fixtures/single.zip", args: [] }
{ name: "default-same-basename-file", archive: "fixtures/same.zip", args: [] }
{ name: "default-duplicate-root-dir", archive: "fixtures/wrapped.zip", args: [] }
{ name: "merge-existing-output-dir", archive: "fixtures/single.zip", args: [] }
{ name: "explicit-dir-dot", archive: "fixtures/single.zip", args: ["--dir", "."] }
{ name: "explicit-here", archive: "fixtures/single.zip", args: ["--here"] }
{ name: "non-archive-gzip", archive: "fixtures/plain.txt.gz", args: [] }
]
$cases | each { |case| run-one $bin $branch $case }
}
(run-all $main_bin "main") ++ (run-all $pr_bin "pr-996") | table -eThe output: |
This PR ensures that extraction always happens inside the new dir that is created before the archive is parsed. This is a requirement for future sandbox implementations and it fixes the behavior that is intended to always produce a directory with the archive name. Previously archives with single files would be flatten and end up with files in the $CWD.