Daniele Scasciafratte

Amber Lang

Easily write Bash with a transpiler

Daniele Scasciafratte / @Mte90Net

Daniele Scasciafratte

  • Co Founder/CTO Codeat
  • Open Source Addicted
  • Mozillian & Mozilla TechSpeaker/Reps (former)
  • WordPress Core Contributor (former)
  • Podcast 🇮🇹 Daniele.tech - Opinioni in open source
  • Italian Linux Society council member
  • Amber Lang Co-Maintainer
  • Book Author: "Contribute to Open Source: the right way"

Bash

Bash, short for Bourne-Again SHell, is a shell program and command language supported by the Free Software Foundation and first developed for the GNU Project by Brian Fox. Designed as a 100% free software alternative for the Bourne shell, it was initially released in 1989.
https://en.wikipedia.org/wiki/Bash_(Unix_shell)

Bash

Since then, Bash has become by far the most popular shell among users of Linux, becoming the default interactive shell on that operating system's various distributions and on Apple's macOS releases before Catalina in October 2019. Bash has also been ported to Microsoft Windows and distributed with Cygwin and MinGW, to DOS by the DJGPP project and to Android via various terminal emulation applications.
https://en.wikipedia.org/wiki/Bash_(Unix_shell)

Bash Pro/Cons

✔️ It is everywhere

✔️ Already installed (except for the commands)

✔️ Standard for Linux scripts

❌ Unique (and strange) syntax

❌ It is easy to follow wrong practices

✔️/❌ Linux commands knowledge required

❌ Time consuming to write a (complex) script

Amber Lang


https://amber-lang.com/

Bash


example() {
  local value=$1
  if [ 1 -gt 0 ]; then
    __array_0=(${value} ${value})
    local numbers=("${__array_0[@]}")
    local sum=0
    for i in "${numbers[@]}"; do
      sum=$(${sum} + ${numbers[${i}]})
    done
    echo "it's ""me"
    returnvalue=${sum}
    return 0
  fi
  return 1
}
example 1
if [ $? != 0 ]; then
    echo "What???"
else
    echo $returnvalue
fi
					

Amber


fun example(value:Num = 1) {
    if 1 > 0 {
        let numbers = [value, value]
        let sum = 0
        loop i in numbers {
            sum += numbers[i]
        }
        echo "it's " + "me"
        return sum
    }
    fail 1
}
echo example(1) failed {
    echo "What???"
}
					

Real Amber Script (example)


#!/usr/bin/env amber
import { split, contains } from "std/text"
import { * } from "std/fs"
let path = "/tmp/amber-sc-tests"
if (not dir_exist(path)) {
    create_dir(path)
}
let report = "{path}/report.txt"
trust file_write(report, "Report for Shellcheck")
let output = ""
let stdtests = trust $/usr/bin/ls "src/tests/stdlib/"$
let stdlib = split(stdtests, "\n")
loop v in stdlib {
    if (not contains(v, ".txt") and file_exist("src/tests/stdlib/{v}")) {
        echo "Generating Bash script for test {v}"
        trust {
            trust $amber "src/tests/stdlib/{v}" "{path}/{v}.sh"$
            output = trust $shellcheck "{path}/{v}.sh"$
        }
        if (status != 0) {
            echo "Shellcheck found something!"
            trust file_append(report, output)
        }
    }
}
					

Real Amber Script


import { make_executable } from "std/fs"
import { download } from "std/http"
import { is_root } from "std/env"
import { contains } from "std/text"

if not is_root() {
    echo "This script requires root permissions!"
    exit(1)
}

[..]

fun download_to_bin(download_url, binary, packed_file) {
    if silent download(download_url, packed_file) {
        trust {
            if contains("tar.gz", packed_file) {
                $tar -zxvf "./{packed_file}" -C ./ > /dev/null 2>&1$
                trust mv "./{binary}" "/usr/local/bin"
            } else {
                $gunzip -c - > "/usr/local/bin/{binary}"$
            }
            $rm "./{packed_file}"$
        }
        make_executable("/usr/local/bin/{binary}")
    } else {
        echo "Download for {binary} at {download_url} failed"
        exit(1)
    }
}
					
https://docs.amber-lang.com/by_example/lsp_installer

Features

  • Integrates (if found): shfmt (shell code formatter), bshchk (runtime Bash dependency checker)
  • Bash (generated) more readable
  • Syntax easier to remember
  • Type: Integer, Float, Text, Array, Boolean etc
  • Standard Library + Builtins (with internal automated tests)
  • ShellCheck code valid (in progress)
  • Written in Rust (with standard library in pure Amber)
  • Editor support for VS Code, Zed and Vim (initial)

Next version (already in dev)

  • Bugfixes
  • unsafe keyword to trust
  • Windows support
  • Glob function
  • New functions in standard library and builtins

Roadmap

  • More standard library & Builtins
  • More readable and optimized Bash code
  • Improve the syntax for more features
  • ShellCheck code valid (in progress)
  • OOP support?
  • Define the Bash version to support in the generated code
  • LSP server (WIP)

THE END

- docs.amber-lang.com