Skip to content

Commit

Permalink
feat(stdlib): extract function (#587)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mte90 authored Nov 30, 2024
1 parent 05caef9 commit a837380
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 3 deletions.
31 changes: 30 additions & 1 deletion src/std/fs.ab
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { join, replace_regex, split } from "std/text"
import { match_regex, join, replace_regex, split } from "std/text"

/// Checks if a directory exists.
pub fun dir_exist(path) {
Expand Down Expand Up @@ -108,3 +108,32 @@ pub fun glob_multiple(paths: [Text]): [Text]? {
pub fun glob(path: Text): [Text]? {
return glob_multiple([path])?
}

/// Extract the file detecting from the filename the extension
/// Supports: bz2, gz, xz, bz2, deb, rar, rpm, tar(gz/xz/bz), zip(war/jar), 7z
/// Note: Not all the commands supports the output folder path
pub fun extract(path: Text, target: Text): Null? {
if file_exist(path) {
if {
match_regex(path, "\.\(tar\.bz2\|tbz\|tbz2\)$"): $ tar xvjf "{path}" -C "{target}" $?
match_regex(path, "\.\(tar\.gz\|tgz\)$"): $ tar xzf "{path}" -C "{target}" $?
match_regex(path, "\.\(tar\.xz\|txz$\)$"): $ tar xJf "{path}" -C "{target}" $?
match_regex(path, "\.bz2$"): $ bunzip2 "{path}" $?
match_regex(path, "\.deb$"): $ dpkg-deb -xv "{path}" "{target}" $?
match_regex(path, "\.gz$"): $ gunzip "{path}" $?
match_regex(path, "\.rar$"): $ unrar x "{path}" "{target}" $?
match_regex(path, "\.rpm$"): $ rpm2cpio "{path}" | cpio -idm $?
match_regex(path, "\.tar$"): $ tar xf "{path}" -C "{target}" $?
match_regex(path, "\.xz$"): $ xz --decompress "{path}" $?
match_regex(path, "\.7z$"): $ 7z -y "{path}" -o "{target}" $?
match_regex(path, "\.\(zip\|war\|jar\)$"): $ unzip "{path}" -d "{target}" $?
else {
echo "Error: Unsupported file type"
fail 3
}
}
} else {
echo "Error: File not found"
fail 2
}
}
61 changes: 59 additions & 2 deletions src/std/text.ab
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fun replace_regex(source: Text, search: Text, replace: Text, extended: Bool
// contains "GNU sed".
$ re='\bCopyright\b.+\bFree Software Foundation\b'; [[ \$(sed --version 2>/dev/null) =~ \$re ]] $
let flag = status == 0 then "-r" else "-E"
return $ echo "{source}" | sed {flag} -e "s/{search}/{replace}/g" $
return $ echo "{source}" | sed "{flag}" -e "s/{search}/{replace}/g" $
} else {
return $ echo "{source}" | sed -e "s/{search}/{replace}/g" $
}
Expand Down Expand Up @@ -91,7 +91,7 @@ pub fun chars(text: Text): [Text] {
return chars
}

/// Checks if some text contains a value/
/// Checks if some text contains a value.
pub fun contains(text: Text, phrase: Text): Bool {
let result = trust $ if [[ "{text}" == *"{phrase}"* ]]; then
echo 1
Expand All @@ -100,6 +100,63 @@ pub fun contains(text: Text, phrase: Text): Bool {
return result == "1"
}

/// Checks if an array value is in the text.
pub fun contains_any(text: Text, terms: [Text]): Bool {
for term in terms {
if contains(text, term) {
return true
}
}

return false
}

/// Checks if all the arrays values are in the string
pub fun contains_all(text: Text, terms: [Text]): Bool {
for term in terms {
if not contains(text, term) {
return false
}
}

return true
}

/// Match all occurences of a regex pattern.
///
/// Function uses `sed`
pub fun match_regex(source: Text, search: Text, extended: Bool = false): Bool {
trust {
search = replace(search, "/", "\/")
let output = ""
if extended {
// GNU sed versions 4.0 through 4.2 support extended regex syntax,
// but only via the "-r" option; use that if the version information
// contains "GNU sed".
$ re='\bCopyright\b.+\bFree Software Foundation\b'; [[ \$(sed --version 2>/dev/null) =~ \$re ]] $
let flag = status == 0 then "-r" else "-E"
output = $ echo "{source}" | sed "{flag}" -ne "/{search}/p" $
} else {
output = $ echo "{source}" | sed -ne "/{search}/p" $
}
if output != "" {
return true
}
}
return false
}

/// Checks if an array value (with regular expression) is in the text.
pub fun match_any_regex(text: Text, terms: [Text]): Bool {
for term in terms {
if match_regex(text, term, false) {
return true
}
}

return false
}

/// Reverses text using `rev`.
pub fun reverse(text: Text): Text {
return trust $ echo "{text}" | rev $
Expand Down
19 changes: 19 additions & 0 deletions src/tests/stdlib/contains_all.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { contains_all } from "std/text"

// Output
// None: 0
// One: 0
// Right: 1
// Both: 1

fun test_multiple(label, text, terms) {
let result = contains_all(text, terms)
echo "{label}: {result}"
}

main {
test_multiple("None", "Hello World", ["Other", "Other"])
test_multiple("One", "Hello World", ["World", "Something"])
test_multiple("Right", "Hello World", ["World", "Hello"])
test_multiple("Both", "Hello World", ["Hello", "World"])
}
21 changes: 21 additions & 0 deletions src/tests/stdlib/contains_any.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { contains_any } from "std/text"

// Output
// Empty: 0
// None: 0
// Left: 1
// Right: 1
// Both: 1

fun test_multiple(label, text, terms) {
let result = contains_any(text, terms)
echo "{label}: {result}"
}

main {
test_multiple("Empty", "Hello World", [Text])
test_multiple("None", "Hello World", ["Other", "Other"])
test_multiple("Left", "Hello World", ["Hello", "Other"])
test_multiple("Right", "Hello World", ["Other", "World"])
test_multiple("Both", "Hello World", ["Hello", "World"])
}
21 changes: 21 additions & 0 deletions src/tests/stdlib/extract.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * from "std/fs"
import { includes } from "std/array"

main {
let tmpdir = trust $ mktemp -d /tmp/amber-XXXX $
cd tmpdir
trust $ touch test.txt $
silent trust $tar -czf "filename.tar.gz" "{tmpdir}/test.txt"$
trust $ rm "test.txt" $
let package = tmpdir + "/" + "filename.tar.gz"

extract(package, tmpdir) failed {
echo "Error"
}

if dir_exist(tmpdir + "/" + tmpdir) {
echo "Succeeded"
}

trust $ rm -rf "{tmpdir}" $
}
21 changes: 21 additions & 0 deletions src/tests/stdlib/match_any_regex.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { match_any_regex } from "std/text"

// Output
// Empty: 0
// None: 0
// Right: 1
// Left: 1
// Both: 1

fun test_multiple(label, text, terms) {
let result = match_any_regex(text, terms)
echo "{label}: {result}"
}

main {
test_multiple("Empty", "Hello World", [Text])
test_multiple("None", "Hello World", ["Other", "Other$"])
test_multiple("Right", "Hello World", ["Other", "World$"])
test_multiple("Left", "Hello World", ["^Hello", "Other"])
test_multiple("Both", "Hello World", ["^Hello", "$World"])
}
7 changes: 7 additions & 0 deletions src/tests/stdlib/match_regex.ab
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { match_regex } from "std/text"

main {
if match_regex("Hello World", "World$") {
echo "Succeeded"
}
}

0 comments on commit a837380

Please sign in to comment.