Skip to content

Commit

Permalink
Document
Browse files Browse the repository at this point in the history
  • Loading branch information
lpil committed Nov 11, 2023
1 parent ecd8598 commit 1baadc6
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 69 deletions.
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
# filepath

Work with file paths in Gleam!

[![Package Version](https://img.shields.io/hexpm/v/filepath)](https://hex.pm/packages/filepath)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/filepath/)

## Quick start

```sh
gleam run # Run the project
gleam test # Run the tests
gleam shell # Run an Erlang shell
gleam add filepath
```
```gleam
import filepath
## Installation

If available on Hex this package can be added to your Gleam project:

```sh
gleam add filepath
pub fn main() {
let path = filepath.join("/home/lucy", "pokemon-cards")
// -> "/home/lucy/pokemon-cards"
}
```

and its documentation can be found at <https://hexdocs.pm/filepath>.
Documentation can be found here: <https://hexdocs.pm/filepath>.
11 changes: 4 additions & 7 deletions gleam.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
name = "filepath"
version = "0.1.0"

# Fill out these fields if you intend to generate HTML documentation or publish
# your project to the Hex package manager.
#
# description = ""
# licences = ["Apache-2.0"]
# repository = { type = "github", user = "username", repo = "project" }
# links = [{ title = "Website", href = "https://gleam.run" }]
description = "Work with file paths in Gleam!"
licences = ["Apache-2.0"]
repository = { type = "github", user = "lpil", repo = "filepath" }
links = [{ title = "Website", href = "https://gleam.run" }]

[dependencies]
gleam_stdlib = "~> 0.32"
Expand Down
109 changes: 98 additions & 11 deletions src/filepath.gleam
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//// Work with file paths in Gleam!
////
//// This package does not yet support Windows paths, but it will in the future.

// References:
// https://github.com/erlang/otp/blob/master/lib/stdlib/src/filename.erl
// https://github.com/elixir-lang/elixir/blob/main/lib/elixir/lib/path.ex
Expand All @@ -13,7 +17,18 @@ import gleam/result
@external(javascript, "./filepath_ffi.mjs", "is_windows")
fn is_windows() -> Bool

// TODO: document
/// Join two paths together.
///
/// This function does not expand `..` or `.` segments, use the `expand`
/// function to do this.
///
/// ## Examples
///
/// ```gleam
/// join("/usr/local", "bin")
/// // -> "/usr/local/bin"
/// ```
///
pub fn join(left: String, right: String) -> String {
case left, right {
_, "/" -> left
Expand All @@ -27,9 +42,7 @@ pub fn join(left: String, right: String) -> String {
|> remove_trailing_slash
}

// TODO: document
// TODO: windows support
pub fn relative(path: String) -> String {
fn relative(path: String) -> String {
case path {
"/" <> path -> relative(path)
_ -> path
Expand All @@ -43,8 +56,16 @@ fn remove_trailing_slash(path: String) -> String {
}
}

// TODO: document
// TODO: Windows support
/// Split a path into its segments.
///
/// ## Examples
///
/// ```gleam
/// split("/usr/local/bin", "bin")
/// // -> ["/", "usr", "local", "bin"]
/// ```
///
pub fn split(path: String) -> List(String) {
case is_windows() {
True -> split_windows(path)
Expand All @@ -66,7 +87,20 @@ fn split_windows(path: String) -> List(String) {
split_unix(path)
}

// TODO: document
/// Get the file extension of a path.
///
/// ## Examples
///
/// ```gleam
/// extension("src/main.gleam")
/// // -> Ok("gleam")
/// ```
///
/// ```gleam
/// extension("package.tar.gz")
/// // -> Ok("gz")
/// ```
///
pub fn extension(path: String) -> Result(String, Nil) {
case string.split(path, ".") {
[_, extension] -> Ok(extension)
Expand All @@ -75,8 +109,17 @@ pub fn extension(path: String) -> Result(String, Nil) {
}
}

// TODO: document
// TODO: windows support
/// Get the base name of a path, that is the name of the file without the
/// containing directory.
///
/// ## Examples
///
/// ```gleam
/// base_name("/usr/local/bin")
/// // -> "bin"
/// ```
///
pub fn base_name(path: String) -> String {
use <- bool.guard(when: path == "/", return: "")

Expand All @@ -86,8 +129,16 @@ pub fn base_name(path: String) -> String {
|> result.unwrap("")
}

// TODO: document
// TODO: windows support
/// Get the directory name of a path, that is the path without the file name.
///
/// ## Examples
///
/// ```gleam
/// directory_name("/usr/local/bin")
/// // -> "/usr/local"
/// ```
///
pub fn directory_name(path: String) -> String {
let path = remove_trailing_slash(path)
case path {
Expand All @@ -108,14 +159,50 @@ fn get_directory_name(
}
}

// TODO: document
// TODO: windows support
/// Check if a path is absolute.
///
/// ## Examples
///
/// ```gleam
/// is_absolute("/usr/local/bin")
/// // -> True
/// ```
///
/// ```gleam
/// is_absolute("usr/local/bin")
/// // -> False
/// ```
///
pub fn is_absolute(path: String) -> Bool {
string.starts_with(path, "/")
}

// TODO: document
// TODO: windows support
//TODO: windows support
/// Expand `..` and `.` segments in a path.
///
/// If the path has a `..` segment that would go up past the root of the path
/// then an error is returned.
///
/// If the path is absolute then the result will always be absolute.
///
/// ## Examples
///
/// ```gleam
/// expand("/usr/local/../bin")
/// // -> Ok("/usr/bin")
/// ```
///
/// ```gleam
/// expand("/tmp/../..")
/// // -> Error(Nil)
/// ```
///
/// ```gleam
/// expand("src/../..")
/// // -> Error("..")
/// ```
///
pub fn expand(path: String) -> Result(String, Nil) {
let is_absolute = is_absolute(path)
let result =
Expand Down
39 changes: 0 additions & 39 deletions test/filepath_test.gleam
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import filepath
import gleeunit
import gleeunit/should
import gleam/io

pub fn main() {
gleeunit.main()
Expand All @@ -11,11 +10,6 @@ pub fn main() {
@external(javascript, "./filepath_ffi.mjs", "is_windows")
fn is_windows() -> Bool

fn skip(_f: fn() -> whatever) -> Nil {
io.print_error("[skipped]")
Nil
}

fn windows_only(f: fn() -> whatever) -> Nil {
case is_windows() {
True -> {
Expand Down Expand Up @@ -113,39 +107,6 @@ pub fn join_11_test() {
|> should.equal("/one/two/three")
}

pub fn relative_0_test() {
use <- skip
filepath.relative("C:/usr/local/bin")
|> should.equal("usr/local/bin")
}

pub fn relative_1_test() {
use <- skip
filepath.relative("C:\\usr\\local\\bin")
|> should.equal("usr\\local\\bin")
}

pub fn relative_2_test() {
use <- skip
filepath.relative("C:usr\\local\\bin")
|> should.equal("usr\\local\\bin")
}

pub fn relative_3_test() {
filepath.relative("/usr/local/bin")
|> should.equal("usr/local/bin")
}

pub fn relative_4_test() {
filepath.relative("usr/local/bin")
|> should.equal("usr/local/bin")
}

pub fn relative_5_test() {
filepath.relative("../usr/local/bin")
|> should.equal("../usr/local/bin")
}

pub fn extension_0_test() {
filepath.extension("file")
|> should.equal(Error(Nil))
Expand Down

0 comments on commit 1baadc6

Please sign in to comment.