-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move packaging to glimpse main module and increase error context
- Loading branch information
1 parent
7e30d8b
commit c23042c
Showing
7 changed files
with
139 additions
and
125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import glance | ||
import gleam/dict | ||
import gleam/list | ||
import gleam/result | ||
|
||
pub type Module { | ||
/// A Module is a wrapper of a glance.Module, but maintains some additional | ||
/// information such as the name of the package and the names of any dependencies | ||
/// of that module. | ||
Module(name: String, module: glance.Module, dependencies: List(String)) | ||
} | ||
|
||
pub type Package { | ||
/// A Package has a name and a collection of modules. Each module is named | ||
/// according to its import. A module can be converted to a filename | ||
///(relative to the global source / directory) simply by appending '.gleam' | ||
Package(name: String, modules: dict.Dict(String, Module)) | ||
} | ||
|
||
pub type LoadError(a) { | ||
LoadError(a) | ||
ParseError( | ||
glance_error: glance.Error, | ||
module_name: String, | ||
module_content: String, | ||
) | ||
} | ||
|
||
/// Load a package using just it's name and a loader function. The name is | ||
/// required to be identical to the entry point module for the package (which | ||
/// is normal in gleam packages). | ||
/// | ||
/// Recursively loads all imports in the entrypoint using the supplied | ||
/// loader function. | ||
pub fn load_package( | ||
package_name: String, | ||
loader: fn(String) -> Result(String, a), | ||
) -> Result(Package, LoadError(a)) { | ||
let package = Package(package_name, dict.new()) | ||
load_module_recurse(package, [package_name], loader) | ||
} | ||
|
||
/// Given an existing Gleam Module and its name, parse its imports to determine | ||
/// what its dependencies are. Return a Glimpse Module that wraps the Gleam module. | ||
/// | ||
/// Note: If the returned Module has any dependencies, it is up to the caller to ensure | ||
/// they are loaded, along with their dependencies. | ||
pub fn load_module(module: glance.Module, name: String) -> Module { | ||
module.imports | ||
|> list.map(fn(import_def) { | ||
case import_def { | ||
glance.Definition(definition: import_, ..) -> import_.module | ||
} | ||
}) | ||
|> Module(name, module, _) | ||
} | ||
|
||
/// given a module and package, identify any dependencies in the module that | ||
/// are *not* present in the package, and return them as a list. | ||
/// | ||
/// The dependencies will be a list of strings like `gleam/io` or `glance` | ||
pub fn filter_new_dependencies(module: Module, package: Package) -> List(String) { | ||
module.dependencies | ||
|> list.filter(fn(dep) { !dict.has_key(package.modules, dep) }) | ||
} | ||
|
||
fn load_module_recurse( | ||
package: Package, | ||
modules: List(String), | ||
loader: fn(String) -> Result(String, a), | ||
) -> Result(Package, LoadError(a)) { | ||
case modules { | ||
[] -> Ok(package) | ||
[module_name, ..rest] -> { | ||
case dict.has_key(package.modules, module_name) { | ||
True -> load_module_recurse(package, rest, loader) | ||
False -> { | ||
use module_content <- result.try( | ||
loader(module_name) |> result.map_error(LoadError), | ||
) | ||
use glance_module <- result.try( | ||
glance.module(module_content) | ||
|> result.map_error(ParseError(_, module_name, module_content)), | ||
) | ||
let glimpse_module = load_module(glance_module, module_name) | ||
let unknown_dependencies = | ||
filter_new_dependencies(glimpse_module, package) | ||
let recurse_package = | ||
Package( | ||
..package, | ||
modules: dict.insert(package.modules, module_name, glimpse_module), | ||
) | ||
load_module_recurse( | ||
recurse_package, | ||
list.append(unknown_dependencies, rest), | ||
loader, | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters