From efb3aae55908cb88f5a9c900d6563603ab792d6a Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 20 May 2025 15:22:41 -0400 Subject: Add more advanced configuration options to modules.ini and support automatically downloading and installing from it. --- examples/README.md | 2 - examples/colorful/README.md | 8 +- examples/colorful/colorful.tm | 2 +- examples/colorful/modules.ini | 2 + examples/coroutines/README.md | 8 +- examples/http-server/connection-queue.tm | 2 +- examples/http-server/http-server.tm | 8 +- examples/http-server/modules.ini | 8 ++ examples/http-server/sample-site/random.tm | 2 +- examples/ini/ini.tm | 2 +- examples/ini/modules.ini | 2 + examples/tomo-install/CHANGES.md | 5 -- examples/tomo-install/tomo-install.tm | 84 --------------------- examples/tomodeps/CHANGES.md | 5 -- examples/tomodeps/tomodeps.tm | 117 ----------------------------- 15 files changed, 34 insertions(+), 223 deletions(-) create mode 100644 examples/colorful/modules.ini create mode 100644 examples/http-server/modules.ini create mode 100644 examples/ini/modules.ini delete mode 100644 examples/tomo-install/CHANGES.md delete mode 100644 examples/tomo-install/tomo-install.tm delete mode 100644 examples/tomodeps/CHANGES.md delete mode 100644 examples/tomodeps/tomodeps.tm (limited to 'examples') diff --git a/examples/README.md b/examples/README.md index 2b5f81fa..9e9291e5 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,8 +8,6 @@ This folder contains some example programs and libraries. style of [learnxinyminutes.com](https://learnxinyminutes.com/). - [game](game/): An example game using raylib. - [http-server](http-server/): A multithreaded HTTP server. -- [tomodeps](tomodeps/): A library for finding Tomo dependencies. -- [tomo-install](tomo-install/): A library for installing Tomo dependencies. - [wrap](wrap/): A command-line program to wrap text. ## Example Libraries diff --git a/examples/colorful/README.md b/examples/colorful/README.md index 04a221e3..faded9b1 100644 --- a/examples/colorful/README.md +++ b/examples/colorful/README.md @@ -54,8 +54,14 @@ colorful [--help] [texts...] [--by-line] [--files ...] `colorful` can also be used as a Tomo library: +```ini +# modules.ini +[colorful] +version=v1.0 +``` + ```tomo -use colorful_v1.0 +use colorful $Colorful" @(blue:Welcome to the @(bold:party)!) diff --git a/examples/colorful/colorful.tm b/examples/colorful/colorful.tm index 270efe8c..9a8bbbba 100644 --- a/examples/colorful/colorful.tm +++ b/examples/colorful/colorful.tm @@ -7,7 +7,7 @@ HELP := " CSI := "\033[" -use patterns_v1.0 +use patterns lang Colorful convert(text:Text -> Colorful) diff --git a/examples/colorful/modules.ini b/examples/colorful/modules.ini new file mode 100644 index 00000000..fb52a859 --- /dev/null +++ b/examples/colorful/modules.ini @@ -0,0 +1,2 @@ +[patterns] +version=v1.0 diff --git a/examples/coroutines/README.md b/examples/coroutines/README.md index 86b5dd00..644c0e07 100644 --- a/examples/coroutines/README.md +++ b/examples/coroutines/README.md @@ -5,8 +5,14 @@ This is a coroutine library built on top of a modified version of ## Example Usage +```ini +# modules.ini +[coroutines] +version=v1.0 +``` + ```tomo -use coroutines_v1.0 +use coroutines func main() co := Coroutine(func() diff --git a/examples/http-server/connection-queue.tm b/examples/http-server/connection-queue.tm index 5cf8bb91..c56069e1 100644 --- a/examples/http-server/connection-queue.tm +++ b/examples/http-server/connection-queue.tm @@ -1,4 +1,4 @@ -use pthreads_v1.0 +use pthreads func _assert_success(name:Text, val:Int32; inline) fail("$name() failed!") if val < 0 diff --git a/examples/http-server/http-server.tm b/examples/http-server/http-server.tm index 717aa733..89141c32 100644 --- a/examples/http-server/http-server.tm +++ b/examples/http-server/http-server.tm @@ -9,9 +9,9 @@ use use use -use commands_v1.0 -use pthreads_v1.0 -use patterns_v1.0 +use commands +use pthreads +use patterns use ./connection-queue.tm @@ -138,7 +138,7 @@ func load_routes(directory:Path -> {Text=RouteEntry}) func main(directory:Path, port=Int32(8080)) say("Serving on port $port") routes := load_routes(directory) - say(" Hosting: $routes") + say("Hosting: $routes") serve(port, func(request:HTTPRequest) if handler := routes[request.path] diff --git a/examples/http-server/modules.ini b/examples/http-server/modules.ini new file mode 100644 index 00000000..171e11d2 --- /dev/null +++ b/examples/http-server/modules.ini @@ -0,0 +1,8 @@ +[pthreads] +version=v1.0 + +[patterns] +version=v1.0 + +[commands] +version=v1.0 diff --git a/examples/http-server/sample-site/random.tm b/examples/http-server/sample-site/random.tm index 75e185b3..153ac2af 100755 --- a/examples/http-server/sample-site/random.tm +++ b/examples/http-server/sample-site/random.tm @@ -1,5 +1,5 @@ #!/bin/env tomo -use random_v1.0 +use random func main() say(" diff --git a/examples/ini/ini.tm b/examples/ini/ini.tm index 9bcfb3a4..4dc27725 100644 --- a/examples/ini/ini.tm +++ b/examples/ini/ini.tm @@ -1,5 +1,5 @@ -use patterns_v1.0 +use patterns _USAGE := " Usage: ini "[section[/key]]" diff --git a/examples/ini/modules.ini b/examples/ini/modules.ini new file mode 100644 index 00000000..fb52a859 --- /dev/null +++ b/examples/ini/modules.ini @@ -0,0 +1,2 @@ +[patterns] +version=v1.0 diff --git a/examples/tomo-install/CHANGES.md b/examples/tomo-install/CHANGES.md deleted file mode 100644 index 42ae752c..00000000 --- a/examples/tomo-install/CHANGES.md +++ /dev/null @@ -1,5 +0,0 @@ -# Version History - -## v1.0 - -Initial version diff --git a/examples/tomo-install/tomo-install.tm b/examples/tomo-install/tomo-install.tm deleted file mode 100644 index e9838859..00000000 --- a/examples/tomo-install/tomo-install.tm +++ /dev/null @@ -1,84 +0,0 @@ -use shell_v1.0 -use patterns_v1.0 - -_USAGE := " - tomo-install file.tm... -" - -_HELP := " - tomo-install: a tool for installing libraries for the Tomo language - Usage: $_USAGE -" - -func find_urls(path:Path -> [Text]) - urls : @[Text] - if path.is_directory() - for f in path.children() - urls.insert_all(find_urls(f)) - else if path.is_file() and path.extension() == ".tm" - for line in path.by_line()! - if captures := line.pattern_captures($Pat/use{space}{url}/) or line.pattern_captures($Pat/{id}{space}:={space}use{space}{url}/) - urls.insert(captures[-1]) - return urls - -func main(paths:[Path]) - if paths.length == 0 - paths = [(./)] - - urls := (++: find_urls(p) for p in paths) or [] - - github_token := (~/.config/tomo/github-token).read() - - (~/.local/share/tomo/installed).create_directory() - (~/.local/share/tomo/lib).create_directory() - - for url in urls - original_url := url - url_without_protocol := url.trim_pattern($Pat"http{0-1 s}://", right=no) - hash := $Shell@(echo -n @url_without_protocol | sha256sum).get_output()!.slice(to=32) - if (~/.local/share/tomo/installed/$hash).is_directory() - say("Already installed: $url") - skip - - alias : Text? - curl_flags := ["-L"] - if github := url_without_protocol.pattern_captures($Pat"github.com/{!/}/{!/}#{..}") - user := github[1] - repo := github[2] - tag := github[3] - url = "https://api.github.com/repos/$user/$repo/tarball/$tag" - alias = "$(repo.without_prefix("tomo-")).$(tag).$(user)" - if github_token - curl_flags ++= ["-H", "Authorization: Bearer $github_token"] - curl_flags ++= [ - "-H", "Accept: application/vnd.github+json", - "-H", "X-GitHub-Api-Version: 2022-11-28", - ] - - (~/.local/share/tomo/downloads/$hash).create_directory() - say($Shell@` - set -euo pipefail - cd ~/.local/share/tomo/downloads/@hash - curl @curl_flags @url | tar xz -C ~/.local/share/tomo/installed --strip-components=1 --one-top-level=@hash - echo @original_url > ~/.local/share/tomo/installed/@hash/source.url - tomo -L ~/.local/share/tomo/installed/@hash - if [ "`uname -s`" = "Darwin" ]; then - ln -f -s ../installed/@hash/lib@hash.dylib ~/.local/share/tomo/lib/lib@hash.dylib - else - ln -f -s ../installed/@hash/lib@hash.so ~/.local/share/tomo/lib/lib@hash.so - fi - `.get_output()!) - - if alias - say($Shell( - set -exuo pipefail - ln -f -s @hash ~/.local/share/tomo/installed/@alias - if [ "`uname -s`" = "Darwin" ]; then - ln -f -s lib@hash.dylib ~/.local/share/tomo/lib/lib@alias.dylib - else - ln -f -s lib@hash.so ~/.local/share/tomo/lib/lib@alias.so - fi - ).get_output()!) - - say("\[1]Installed $url!\[]") - diff --git a/examples/tomodeps/CHANGES.md b/examples/tomodeps/CHANGES.md deleted file mode 100644 index 42ae752c..00000000 --- a/examples/tomodeps/CHANGES.md +++ /dev/null @@ -1,5 +0,0 @@ -# Version History - -## v1.0 - -Initial version diff --git a/examples/tomodeps/tomodeps.tm b/examples/tomodeps/tomodeps.tm deleted file mode 100644 index af7f2573..00000000 --- a/examples/tomodeps/tomodeps.tm +++ /dev/null @@ -1,117 +0,0 @@ -# Show a Tomo dependency graph - -use patterns_v1.0 - -_USAGE := "Usage: tomodeps " - -_HELP := " - tomodeps: Show a file dependency graph for Tomo source files. - $_USAGE -" - -enum Dependency(File(path:Path), Module(name:Text)) - -func _get_file_dependencies(file:Path -> |Dependency|) - if not file.is_file() - say("Could not read file: $file") - return || - - deps : @|Dependency| - if lines := file.by_line() - for line in lines - if line.matches_pattern($Pat/use {..}.tm/) - file_import := Path.from_text(line.replace_pattern($Pat/use {..}/, "@1")).resolved(relative_to=file) - deps.add(Dependency.File(file_import)) - else if line.matches_pattern($Pat/use {id}/) - module_name := line.replace_pattern($Pat/use {..}/, "@1") - deps.add(Dependency.Module(module_name)) - return deps[] - -func _build_dependency_graph(dep:Dependency, dependencies:@{Dependency=|Dependency|}) - return if dependencies.has(dep) - - dependencies[dep] = || # Placeholder - - dep_deps := when dep is File(path) - _get_file_dependencies(path) - is Module(module) - dir := (~/.local/share/tomo/installed/$module) - module_deps : @|Dependency| - visited : @|Path| - unvisited := @|f.resolved() for f in dir.files() if f.extension() == ".tm"| - while unvisited.length > 0 - file := unvisited.items[-1] - unvisited.remove(file) - visited.add(file) - - for file_dep in _get_file_dependencies(file) - when file_dep is File(f) - if not visited.has(f) - unvisited.add(f) - is Module(m) - module_deps.add(file_dep) - module_deps[] - - dependencies[dep] = dep_deps - - for dep2 in dep_deps - _build_dependency_graph(dep2, dependencies) - -func get_dependency_graph(dep:Dependency -> {Dependency=|Dependency|}) - graph : @{Dependency=|Dependency|} - _build_dependency_graph(dep, graph) - return graph - -func _printable_name(dep:Dependency -> Text) - when dep is Module(module) - return "\[34;1]$module\[]" - is File(f) - f = f.relative_to((.)) - if f.exists() - return Text(f) - else - return "\[31;1]$f (not found)\[]" - -func _draw_tree(dep:Dependency, dependencies:{Dependency=|Dependency|}, already_printed:@|Dependency|, prefix="", is_last=yes) - if already_printed.has(dep) - say(prefix ++ (if is_last then "└── " else "├── ") ++ _printable_name(dep) ++ " \[2](recursive)\[]") - return - - say(prefix ++ (if is_last then "└── " else "├── ") ++ _printable_name(dep)) - already_printed.add(dep) - - child_prefix := prefix ++ (if is_last then " " else "│ ") - - children := dependencies[dep] or || - for i,child in children.items - is_child_last := (i == children.length) - _draw_tree(child, dependencies, already_printed, child_prefix, is_child_last) - -func draw_tree(dep:Dependency, dependencies:{Dependency=|Dependency|}) - printed : @|Dependency| - say(_printable_name(dep)) - printed.add(dep) - deps := dependencies[dep] or || - for i,child in deps.items - is_child_last := (i == deps.length) - _draw_tree(child, dependencies, already_printed=printed, is_last=is_child_last) - -func main(files:[Text]) - if files.length == 0 - exit(" - Please provide at least one file! - $_USAGE - ") - - for arg in files - if arg.matches_pattern($Pat/{..}.tm/) - path := Path.from_text(arg).resolved() - dependencies := get_dependency_graph(File(path)) - draw_tree(File(path), dependencies) - else if arg.matches_pattern($Pat/{id}/) - dependencies := get_dependency_graph(Module(arg)) - draw_tree(Module(arg), dependencies) - else - say("\[2]Skipping $arg\[]") - skip - -- cgit v1.2.3