diff --git a/src/std/fs.ab b/src/std/fs.ab index abddddc0..f4b0749a 100644 --- a/src/std/fs.ab +++ b/src/std/fs.ab @@ -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) { @@ -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 + } +} diff --git a/src/std/text.ab b/src/std/text.ab index 5529293f..19cdc981 100644 --- a/src/std/text.ab +++ b/src/std/text.ab @@ -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" $ } @@ -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 @@ -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 $ diff --git a/src/tests/stdlib/contains_all.ab b/src/tests/stdlib/contains_all.ab new file mode 100644 index 00000000..491f447b --- /dev/null +++ b/src/tests/stdlib/contains_all.ab @@ -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"]) +} diff --git a/src/tests/stdlib/contains_any.ab b/src/tests/stdlib/contains_any.ab new file mode 100644 index 00000000..47992e38 --- /dev/null +++ b/src/tests/stdlib/contains_any.ab @@ -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"]) +} diff --git a/src/tests/stdlib/extract.ab b/src/tests/stdlib/extract.ab new file mode 100644 index 00000000..b3ac1361 --- /dev/null +++ b/src/tests/stdlib/extract.ab @@ -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}" $ +} diff --git a/src/tests/stdlib/match_any_regex.ab b/src/tests/stdlib/match_any_regex.ab new file mode 100644 index 00000000..cefa20a8 --- /dev/null +++ b/src/tests/stdlib/match_any_regex.ab @@ -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"]) +} diff --git a/src/tests/stdlib/match_regex.ab b/src/tests/stdlib/match_regex.ab new file mode 100644 index 00000000..0b4788db --- /dev/null +++ b/src/tests/stdlib/match_regex.ab @@ -0,0 +1,7 @@ +import { match_regex } from "std/text" + +main { + if match_regex("Hello World", "World$") { + echo "Succeeded" + } +}