Current section
Files
Jump to
Current section
Files
src/cli_project/project.gleam
//// A set of utilities to work within a Gleam project. I TOOK MOST OF THIS FROM THE SQUIRREL REPO. TYSM!
////
import funsies/orm_gen
import filepath
import gleam/dict
import gleam/erlang
import gleam/io
import gleam/list
import gleam/result
import gleam/string
import globlin
import globlin_fs
import shellout
import simplifile
import tom
/// Returns the project's name, read from the `gleam.toml` file.
///
pub fn name() -> Result(String, Nil) {
let configuration_path = filepath.join(root(), "gleam.toml")
use configuration <- try_nil(simplifile.read(configuration_path))
use toml <- try_nil(tom.parse(configuration))
use name <- try_nil(tom.get_string(toml, ["name"]))
Ok(name)
}
fn try_nil(
result: Result(a, b),
then do: fn(a) -> Result(c, Nil),
) -> Result(c, Nil) {
result.try(result.replace_error(result, Nil), do)
}
/// Finds the path of the project's `src` directory.
/// This recursively walks up from the current directory until it finds a
/// `gleam.toml` and builds it from there.
///
pub fn src() -> String {
filepath.join(root(), "src")
}
/// Finds the path leading to the project's root folder. This recursively walks
/// up from the current directory until it finds a `gleam.toml`.
///
fn root() -> String {
find_root(".")
}
fn find_root(path: String) -> String {
let toml = filepath.join(path, "gleam.toml")
case simplifile.is_file(toml) {
Ok(False) | Error(_) -> find_root(filepath.join("..", path))
Ok(True) -> path
}
}
pub fn find_schema_files() -> Result(dict.Dict(String, String), Nil) {
let current_root = root()
io.println("Current root: " <> current_root)
let assert Ok(cwd) = simplifile.current_directory()
let assert Ok(pattern) =
globlin.new_pattern(filepath.join(cwd, "/src/schema/*.gleam"))
case globlin_fs.glob(pattern, returning: globlin_fs.RegularFiles) {
Ok(files) -> {
io.println("Files found: " <> files |> string.join(", "))
files
|> list.map(fn(file) {
let file_names = file |> filepath.base_name()
let file_paths = "schema/" <> file_names
#(
file_paths,
file |> filepath.base_name() |> filepath.strip_extension(),
)
})
|> dict.from_list()
|> Ok()
}
Error(err) -> {
io.debug(err)
Error(Nil)
}
}
}
pub fn create_files(input: dict.Dict(String, String)) {
let values = dict.values(input)
simplifile.create_directory(src() <> "/funs/")
let code =
"// code to be run to generate the types and decoders"
<> "\n// DO NOT MODIFY"
<> "\n // generated by `funsies`"
<> "\n\nimport funsies/decoder"
<> "\nimport funsies/orm_gen"
<> "\n\n"
<> string.concat(
list.map(values, fn(val) { "import schema/" <> val <> "\n" }),
)
<> "\n"
<> "\n"
<> "pub fn main() {"
<> string.concat(
list.map(values, fn(val) {
"decoder.generate_row_type("
<> val
<> "."
<> val
<> "()"
<> ")"
<> "\n"
<> "decoder.generate_decoder_code("
<> val
<> "."
<> val
<> "()"
<> ")"
<> "\n"
<> "orm_gen.create_insert("
<> "\""
<> "src/funs/insert.gleam"
<> "\", "
<> val
<> "."
<> val
<> "())"
<> "\n"
}),
)
<> "}"
simplifile.write(src() <> "/funs/generate.gleam", code)
}
pub fn work() {
let assert Ok(cwd) = simplifile.current_directory()
case
shellout.command(
"gleam",
["run", "-m", "funs/generate"],
in: cwd <> "/",
opt: [],
)
{
Ok(res) -> {
io.println("Successfully generated types and decoders.")
Ok(Nil)
}
Error(e) -> {
io.debug("Error generating types and decoders")
Error(Nil)
}
}
}