From 8f200a39dbc8b03de920c8f4b4605135695b65d7 Mon Sep 17 00:00:00 2001 From: Steven Vandevelde Date: Tue, 6 Feb 2024 15:04:16 +0100 Subject: [PATCH] fix: issue with listing extension-less files --- CHANGELOG.md | 4 + docs.json | 2 +- gren.json | 2 +- package-lock.json | 247 ++++------------------------------- package.json | 2 +- src/Shikensu.gren | 2 +- src/Shikensu/Definition.gren | 16 ++- src/Shikensu/Path.gren | 2 +- 8 files changed, 42 insertions(+), 235 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca22ec6..26d340d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.0.1 + +Fixes an issue with listing extension-less files. + ## 5.0.0 * Added `Shikensu.bundle` diff --git a/docs.json b/docs.json index 5813d59..8ade0dd 100644 --- a/docs.json +++ b/docs.json @@ -1 +1 @@ -{"Shikensu":{"name":"Shikensu","comment":"\n\n# ๐Ÿš€\n\n@docs program, programs, Program, Task, list, perform\n\n\n# IO\n\n@docs read, write\n\n\n# ๐Ÿ› ๏ธ\n\n@docs bundle, currentWorkingDirectory\n\n","unions":[],"aliases":[{"name":"Program","comment":" Alias for a Node program.\n","args":[],"type":"Node.Program {} {}"},{"name":"Task","comment":" Alias for the main `Task` type we'll be working with here.\n","args":[],"type":"Task.Task Shikensu.Error.Error Shikensu.Bundle.Bundle"}],"values":[{"name":"bundle","comment":" A `Task` that bundles an array of definitions (compendium).\n\nUse this to write a custom array of definitions to disk\n(there's an example in the `perform` function docs).\n\nThis is basically a small wrapper around `currentWorkingDirectory`\nthat makes a `Bundle`.\n\n","type":"FileSystem.Permission -> Array.Array Shikensu.Definition.Definition -> Shikensu.Task"},{"name":"currentWorkingDirectory","comment":" Get the absolute directory path of the current working directory.\n","type":"FileSystem.Permission -> Task.Task Shikensu.Error.Error (Shikensu.Path.Path Shikensu.Path.Directory)"},{"name":"list","comment":" The `list` function itself, unwrapped.\n\nRecursively lists a directory and then gives you a `Task`\ncontaining a `Bundle` which in turns has an array of `Definition`s\nstored under the property named `compendium`.\n\nThis collection of `Definition`s is the main thing you'll be working with.\nThe goal of this library is to scan a file tree, manipulate it and then\noptionally write it back to disk. This is done through these definitions.\n\n import Shikensu\n import Shikensu.Focus exposing (Focus(..))\n\n Shikensu.perform\n -- To ignore, return `Cmd.none`\n { onSuccess = \\env _ -> Stream.sendLine env.stdout \"๐Ÿงช Sequence completed\"\n , onError = \\env err -> Stream.sendLine env.stderr (\"๐Ÿšจ \" ++ Error.toString err)\n }\n (\\fsPermission ->\n CurrentDirectory\n |> Shikensu.list fsPermission\n |> Task.map (Shikensu.withExtension \"md\")\n )\n\nโš ๏ธ The given `Focus` will always be in the context of\nthe environment of the resulting Gren binary that is being executed.\nSo for example, say your `pwd` command returns `~/code/shikensu/`,\nand your focus is `Relative (Path.Directory [ \"..\", \"example\" ])`.\nIf you run `./binary/app` the resulting path will be `~/code/example/`.\n\n","type":"FileSystem.Permission -> Shikensu.Focus.Focus -> Shikensu.Task"},{"name":"perform","comment":" A utility function that helps you create programs.\n\nThis function is also useful for when you want to write definitions to disk.\nMaybe you have a JSON file and you want to split it up in multiple files,\nthat's something you can do with this function.\n\n import Shikensu\n import Shikensu.Focus exposing (Focus(..))\n\n Shikensu.perform\n -- To ignore, return `Cmd.none`\n { onSuccess = \\env _ -> Stream.sendLine env.stdout \"๐Ÿงช Sequence completed\"\n , onError = \\env err -> Stream.sendLine env.stderr (\"๐Ÿšจ \" ++ Error.toString err)\n }\n (\\fsPermission ->\n [ { baseName = \"json-file-1\"\n , content = Just jsonBytes\n , directoryPath = Path.directory [ \"splitted\" ]\n , extensionName = Just \"json\"\n , metadata = Dict.empty\n }\n ]\n |> Shikensu.bundle fsPermission\n |> Task.andThen (Shikensu.write CurrentDirectory)\n )\n\nThis uses `Node.defineSimpleProgram` and `FileSystem.initialize` underneath\nand then manages the `Shikensu.Task` value created by `list` or some other function.\n\nSee the `list` function above for an example using `list`.\n\n","type":"{ onSuccess : Node.Environment -> a -> Platform.Cmd.Cmd {}, onError : Node.Environment -> Shikensu.Error.Error -> Platform.Cmd.Cmd {} } -> (FileSystem.Permission -> Task.Task Shikensu.Error.Error a) -> Shikensu.Program"},{"name":"program","comment":" Create a Shikensu Program.\n\nThis is basically a wrapper around `list` and `perform`.\nIt creates a `SimpleProgram` for you, initialises the needed permissions,\nlists the given directory (ie. the focus), and finally performs the given task (sequence).\nIt also prints errors to stderr or a success message to stdout.\n\nThe example below with the comments should help you understand the flow:\n\n import Shikensu\n import Shikensu.Contrib as Shikensu\n import Shikensu.Focus exposing (Focus(..))\n import Task\n\n -- Our `Program` which references out `sequence` (more on that later)\n -- and our `Focus`, the target directory we want to list.\n main =\n Shikensu.program sequence CurrentDirectory\n\n -- This is our `sequence`.\n -- Here we receive a `Task` that contains the directory listing (aka. the compendium)\n -- We essentially do two things with this listing:\n -- (1) We manipulate it (these are the `Task.map` calls)\n -- (2) Or we perform some IO operation (these are the `Task.andThen` calls)\n -> `read` reads the content of the files.\n -> `write` writes the manipulated in-memory representations of the files back to disk.\n sequence task =\n task\n |> Task.map (Shikensu.withExtension \"md\")\n |> Task.andThen Shikensu.read\n |> Task.map (Shikensu.renderContent markdownRenderer) -- See `example` folder\n |> Task.andThen (Shikensu.write destinationFocus)\n\n","type":"(Shikensu.Task -> Shikensu.Task) -> Shikensu.Focus.Focus -> Shikensu.Program"},{"name":"programs","comment":" Provides a way to make multiple lists and operate on them.\n\nTechnically not multiple programs, but same idea as\nthe `program` function, just with multiple lists.\n\n import Shikensu\n import Shikensu.Focus exposing (Focus(..))\n\n Shikensu.programs\n [ { focus = Relative (Path.directory [ \"posts\" ])\n , sequence = Task.andThen Shikensu.read\n }\n , { focus = Relative (Path.directory [ \"images\" ])\n , sequence = Task.map (\\bundle -> ...)\n }\n ]\n\n","type":"Array.Array { focus : Shikensu.Focus.Focus, sequence : Shikensu.Task -> Shikensu.Task } -> Shikensu.Program"},{"name":"read","comment":" Read the files in the given compendium/bundle,\nsetting the `content` property in the definition.\n","type":"Shikensu.Bundle.Bundle -> Shikensu.Task"},{"name":"write","comment":" Write each definition to their respective location.\nThe location will depend on the focus and the environment it was run in.\n","type":"Shikensu.Focus.Focus -> Shikensu.Bundle.Bundle -> Shikensu.Task"}],"binops":[]},"Shikensu.Bundle":{"name":"Shikensu.Bundle","comment":"\n\n# Bundle\n\n@docs Bundle, mapCompendium\n\n","unions":[],"aliases":[{"name":"Bundle","comment":" The bundle which is the value of the `Shikensu.Task` type.\n\nMost important part here is the `compendium`, the list of definitions.\nThe rest is contextual information.\n\n","args":[],"type":"{ compendium : Array.Array Shikensu.Definition.Definition, fsPermission : FileSystem.Permission, readingDirectory : Maybe.Maybe (Shikensu.Path.Path Shikensu.Path.Directory), workingDirectory : Shikensu.Path.Path Shikensu.Path.Directory }"}],"values":[{"name":"mapCompendium","comment":" Convenience function to map over array of `Definition`s.\n","type":"(Array.Array Shikensu.Definition.Definition -> Array.Array Shikensu.Definition.Definition) -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"}],"binops":[]},"Shikensu.Contrib":{"name":"Shikensu.Contrib","comment":"\n\nPremade functions to manipulate your bundles/definitions with.\n\n\n# Contrib\n\n@docs clearMetadata, clone, copyPropsToMetadata, enclose, exclude, insertMetadata, permalink, rename, renameExtension, renderContent, replaceMetadata, setContent, transformContent, withBaseName, withDirectory, withExtension, withMetadata\n\n","unions":[],"aliases":[],"values":[{"name":"clearMetadata","comment":" Clear metadata.\n","type":"Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"clone","comment":" Clone.\n\nFor each definition that has the given `relativePath` (1st argument),\nmake a clone with a new `relativePath` (2nd argument),\nand add that into the compendium just after the matching definition.\n\n >>> clone \"index.html\" \"200.html\" bundle\n\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"copyPropsToMetadata","comment":" Copy definition properties into the metadata.\n","type":"Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"enclose","comment":" Append the given directory path to the directory path of each definition.\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"exclude","comment":" Exclude.\n\nFilter out the definitions that have the given `relativePath`.\n\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"insertMetadata","comment":" Insert additional metadata.\n","type":"Dict.Dict String.String Json.Encode.Value -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"permalink","comment":" Permalink.\n\nAppend the baseName to the directoryPath\nand change the baseName to the given string.\nIt will NOT change definitions that already have the new baseName.\n\n >>> permalink \"index\" compendium\n\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"rename","comment":" Rename.\n\nChange the `relativePath` of the definitions that match a given `relativePath`.\nFor example, if you have a definition with the relativePath path `a/b/example.html`:\n\n >>> rename\n ..> (Path.file [ \"a\", \"b\", \"example.html\" ])\n ..> (Path.file [ \"example\", \"index.html\" ])\n ..> compendium\n\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"renameExtension","comment":" Rename extension.\n\nExample:\n\n >>> renameExtension \"markdown\" \"html\" compendium\n ..> -- The definitions that had the extensionName \"markdown\"\n ..> -- now have the extensionName \"html\"\n\n","type":"String.String -> String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"renderContent","comment":" Render content.\n\nReplace the `content` property by providing a renderer.\nA renderer is a function with the signature `Definition -> Maybe Bytes`.\nYou can use this to render templates, markdown, etc.\n\n","type":"(Shikensu.Definition.Definition -> Maybe.Maybe Bytes.Bytes) -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"replaceMetadata","comment":" Replace metadata.\n\nReplace the current metadata dictionary with another one.\n\n","type":"Dict.Dict String.String Json.Encode.Value -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"setContent","comment":" Set content.\n\nSet content directly.\n\n","type":"Bytes.Bytes -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"transformContent","comment":" Transform content.\n\nAlias for `renderContent`.\n\n","type":"(Shikensu.Definition.Definition -> Maybe.Maybe Bytes.Bytes) -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withBaseName","comment":" Only keep definitions with the given base name.\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withDirectory","comment":" Only keep definitions with the given directory path.\n","type":"Shikensu.Path.Path Shikensu.Path.Directory -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withExtension","comment":" Only keep definitions with the given extension.\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withMetadata","comment":" Only keep definitions with the given metadata.\n","type":"String.String -> Json.Encode.Value -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"}],"binops":[]},"Shikensu.Definition":{"name":"Shikensu.Definition","comment":"\n\n# Definition\n\n@docs Definition, create, fork, relativePath\n\n","unions":[],"aliases":[{"name":"Definition","comment":" **A piece of content.**\n\nExample definition, given:\nThe working directory root path `/Users/icidasset/Projects/shikensu/example/`\nand the full item path `/Users/icidasset/Projects/shikensu/example/test/hello.md`\n\n { baseName = \"hello\"\n , content = Nothing\n , directoryPath = Path.directory [ \"test\" ]\n , extensionName = Just \"md\"\n , metadata = Dict.empty\n }\n\n","args":[],"type":"{ baseName : String.String, content : Maybe.Maybe Bytes.Bytes, directoryPath : Shikensu.Path.Path Shikensu.Path.Directory, extensionName : Maybe.Maybe String.String, metadata : Dict.Dict String.String Json.Encode.Value }"}],"values":[{"name":"create","comment":" Create a definition, given a relative path.\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Definition.Definition"},{"name":"fork","comment":" Fork a definition, given a relative path.\nTaking the metadata and content of the original definition.\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Definition.Definition -> Shikensu.Definition.Definition"},{"name":"relativePath","comment":" The path relative to the working directory.\n","type":"Shikensu.Definition.Definition -> Shikensu.Path.Path Shikensu.Path.File"}],"binops":[]},"Shikensu.Error":{"name":"Shikensu.Error","comment":"\n\n# Error\n\n@docs Error, toString\n\n","unions":[{"name":"Error","comment":"","args":[],"cases":[["ErrorMessage",["String.String"]],["PlatformAccessError",["Shikensu.Path.Path Shikensu.Path.Encapsulated","FileSystem.AccessError"]],["PlatformUnknownError",["FileSystem.UnknownFileSystemError"]]]}],"aliases":[],"values":[{"name":"toString","comment":"","type":"Shikensu.Error.Error -> String.String"}],"binops":[]},"Shikensu.Focus":{"name":"Shikensu.Focus","comment":"\n\n# Focus\n\n@docs Focus, toAbsolutePath\n\n","unions":[{"name":"Focus","comment":"","args":[],"cases":[["CurrentDirectory",[]],["Relative",["Shikensu.Path.Path Shikensu.Path.Directory"]],["Absolute",["Shikensu.Path.Path Shikensu.Path.Directory"]]]}],"aliases":[],"values":[{"name":"toAbsolutePath","comment":"","type":"{ cwd : Shikensu.Path.Path Shikensu.Path.Directory } -> Shikensu.Focus.Focus -> Shikensu.Path.Path Shikensu.Path.Directory"}],"binops":[]},"Shikensu.Path":{"name":"Shikensu.Path","comment":"\n\n# Paths\n\n@docs Path, Directory, File, Encapsulated, Kind\n\n\n# Creation\n\n@docs directory, file\n\n\n# POSIX\n\n@docs fromPosix, toPosix\n\n\n# Encapsulation\n\n@docs encapsulate\n\n\n# Functions\n\n@docs combine, kind, length, map, unwrap\n\n","unions":[{"name":"Directory","comment":" ๐Ÿ‘ป Directory\n","args":[],"cases":[]},{"name":"Encapsulated","comment":" ๐Ÿ‘ป Encapsulated\n","args":[],"cases":[]},{"name":"File","comment":" ๐Ÿ‘ป File\n","args":[],"cases":[]},{"name":"Kind","comment":" ","args":[],"cases":[["Directory",[]],["File",[]]]},{"name":"Path","comment":" Path type.\nThis is used with the [phantom ๐Ÿ‘ป types](#phantom-types).\n\n directoryPath : Path Directory\n filePath : Path File\n encapsulatedPath : Path Encapsulated\n\n","args":["kind"],"cases":[]}],"aliases":[],"values":[{"name":"combine","comment":" Combine a directory path and another path.\n\n","type":"Shikensu.Path.Path Shikensu.Path.Directory -> Shikensu.Path.Path kind -> Shikensu.Path.Path kind"},{"name":"directory","comment":" Create a directory path.\n\n directory [ \"Audio\", \"Playlists\" ]\n\n","type":"Array.Array String.String -> Shikensu.Path.Path Shikensu.Path.Directory"},{"name":"encapsulate","comment":" Encapsulate a path.\n","type":"Shikensu.Path.Path kind -> Shikensu.Path.Path Shikensu.Path.Encapsulated"},{"name":"file","comment":" Create a file path.\n\n file [ \"Document\", \"invoice.pdf\" ]\n\n","type":"Array.Array String.String -> Shikensu.Path.Path Shikensu.Path.File"},{"name":"fromPosix","comment":" Convert a POSIX formatted string to a path.\nThis will return a `Encapsulated` path. To get a path of the type `Path Directory` or `Path File`, use the functions in the `Webnative.Path.Encapsulated` module.\n\n >>> import Shikensu.Path.Encapsulated\n >>> \"foo/bar/\"\n ..> |> fromPosix\n ..> |> Shikensu.Path.Encapsulated.toDirectory\n Just (directory [ \"foo\", \"bar\" ])\n\n >>> \"foo/bar\"\n ..> |> fromPosix\n ..> |> Shikensu.Path.Encapsulated.toFile\n Just (file [ \"foo\", \"bar\" ])\n\n","type":"String.String -> Shikensu.Path.Path Shikensu.Path.Encapsulated"},{"name":"kind","comment":" Get the path kind.\n\n >>> kind (directory [])\n Directory\n >>> kind (file [])\n File\n\nEven if a path is encapsulated,\nyou can still check the kind of path it is.\n\n >>> kind (encapsulate <| directory [])\n Directory\n >>> kind (encapsulate <| file [])\n File\n\n","type":"Shikensu.Path.Path kind -> Shikensu.Path.Kind"},{"name":"length","comment":" Length.\n","type":"Shikensu.Path.Path kind -> Basics.Int"},{"name":"map","comment":" Map.\n","type":"(Array.Array String.String -> Array.Array String.String) -> Shikensu.Path.Path kind -> Shikensu.Path.Path kind"},{"name":"toPosix","comment":" Convert a path to the POSIX format.\n\n >>> toPosix { absolute = True } (directory [ \"foo\", \"bar\"])\n \"/foo/bar/\"\n >>> toPosix { absolute = False } (file [ \"foo\", \"bar\"])\n \"foo/bar\"\n\n","type":"{ absolute : Basics.Bool } -> Shikensu.Path.Path kind -> String.String"},{"name":"unwrap","comment":" Get the path parts.\n\n >>> unwrap (directory [ \"foo\", \"bar\" ])\n [ \"foo\", \"bar\" ]\n >>> unwrap (file [ \"foo\", \"bar\" ])\n [ \"foo\", \"bar\" ]\n\n","type":"Shikensu.Path.Path kind -> Array.Array String.String"}],"binops":[]},"Shikensu.Path.Encapsulated":{"name":"Shikensu.Path.Encapsulated","comment":"\n\n# Encapsulated Paths\n\n@docs toDirectory, toFile\n\n","unions":[],"aliases":[],"values":[{"name":"toDirectory","comment":" Remove the membrane and extract a `Path Directory`.\n","type":"Shikensu.Path.Path Shikensu.Path.Encapsulated -> Maybe.Maybe (Shikensu.Path.Path Shikensu.Path.Directory)"},{"name":"toFile","comment":" Remove the membrane and extract a `Path File`.\n","type":"Shikensu.Path.Path Shikensu.Path.Encapsulated -> Maybe.Maybe (Shikensu.Path.Path Shikensu.Path.File)"}],"binops":[]}} \ No newline at end of file +{"Shikensu":{"name":"Shikensu","comment":"\n\n# ๐Ÿš€\n\n@docs program, programs, Program, Task, list, perform\n\n\n# IO\n\n@docs read, write\n\n\n# ๐Ÿ› ๏ธ\n\n@docs bundle, currentWorkingDirectory\n\n","unions":[],"aliases":[{"name":"Program","comment":" Alias for a Node program.\n","args":[],"type":"Node.Program {} {}"},{"name":"Task","comment":" Alias for the main `Task` type we'll be working with here.\n","args":[],"type":"Task.Task Shikensu.Error.Error Shikensu.Bundle.Bundle"}],"values":[{"name":"bundle","comment":" A `Task` that bundles an array of definitions (compendium).\n\nUse this to write a custom array of definitions to disk\n(there's an example in the `perform` function docs).\n\nThis is basically a small wrapper around `currentWorkingDirectory`\nthat makes a `Bundle`.\n\n","type":"FileSystem.Permission -> Array.Array Shikensu.Definition.Definition -> Shikensu.Task"},{"name":"currentWorkingDirectory","comment":" Get the absolute directory path of the current working directory.\n","type":"FileSystem.Permission -> Task.Task Shikensu.Error.Error (Shikensu.Path.Path Shikensu.Path.Directory)"},{"name":"list","comment":" The `list` function itself, unwrapped.\n\nRecursively lists a directory and then gives you a `Task`\ncontaining a `Bundle` which in turns has an array of `Definition`s\nstored under the property named `compendium`.\n\nThis collection of `Definition`s is the main thing you'll be working with.\nThe goal of this library is to scan a file tree, manipulate it and then\noptionally write it back to disk. This is done through these definitions.\n\n import Shikensu\n import Shikensu.Focus exposing (Focus(..))\n\n Shikensu.perform\n -- To ignore, return `Cmd.none`\n { onSuccess = \\env _ -> Stream.sendLine env.stdout \"๐Ÿงช Sequence completed\"\n , onError = \\env err -> Stream.sendLine env.stderr (\"๐Ÿšจ \" ++ Error.toString err)\n }\n (\\fsPermission ->\n CurrentDirectory\n |> Shikensu.list fsPermission\n |> Task.map (Shikensu.withExtension \"md\")\n )\n\nโš ๏ธ The given `Focus` will always be in the context of\nthe environment of the resulting Gren binary that is being executed.\nSo for example, say your `pwd` command returns `~/code/shikensu/`,\nand your focus is `Relative (Path.Directory [ \"..\", \"example\" ])`.\nIf you run `./binary/app` the resulting path will be `~/code/example/`.\n\n","type":"FileSystem.Permission -> Shikensu.Focus.Focus -> Shikensu.Task"},{"name":"perform","comment":" A utility function that helps you create programs.\n\nThis function is also useful for when you want to write definitions to disk.\nMaybe you have a JSON file and you want to split it up in multiple files,\nthat's something you can do with this function.\n\n import Shikensu\n import Shikensu.Focus exposing (Focus(..))\n\n Shikensu.perform\n -- To ignore, return `Cmd.none`\n { onSuccess = \\env _ -> Stream.sendLine env.stdout \"๐Ÿงช Sequence completed\"\n , onError = \\env err -> Stream.sendLine env.stderr (\"๐Ÿšจ \" ++ Error.toString err)\n }\n (\\fsPermission ->\n [ { baseName = \"json-file-1\"\n , content = Just jsonBytes\n , directoryPath = Path.directory [ \"splitted\" ]\n , extensionName = Just \"json\"\n , metadata = Dict.empty\n }\n ]\n |> Shikensu.bundle fsPermission\n |> Task.andThen (Shikensu.write CurrentDirectory)\n )\n\nThis uses `Node.defineSimpleProgram` and `FileSystem.initialize` underneath\nand then manages the `Shikensu.Task` value created by `list` or some other function.\n\nSee the `list` function above for an example using `list`.\n\n","type":"{ onSuccess : Node.Environment -> a -> Platform.Cmd.Cmd {}, onError : Node.Environment -> Shikensu.Error.Error -> Platform.Cmd.Cmd {} } -> (FileSystem.Permission -> Task.Task Shikensu.Error.Error a) -> Shikensu.Program"},{"name":"program","comment":" Create a Shikensu Program.\n\nThis is basically a wrapper around `list` and `perform`.\nIt creates a `SimpleProgram` for you, initialises the needed permissions,\nlists the given directory (ie. the focus), and finally performs the given task (sequence).\nIt also prints errors to stderr or a success message to stdout.\n\nThe example below with the comments should help you understand the flow:\n\n import Shikensu\n import Shikensu.Contrib as Shikensu\n import Shikensu.Focus exposing (Focus(..))\n import Task\n\n -- Our `Program` which references out `sequence` (more on that later)\n -- and our `Focus`, the target directory we want to list.\n main =\n Shikensu.program sequence CurrentDirectory\n\n -- This is our `sequence`.\n -- Here we receive a `Task` that contains the directory listing (aka. the compendium)\n -- We essentially do two things with this listing:\n -- (1) We manipulate it (these are the `Task.map` calls)\n -- (2) Or we perform some IO operation (these are the `Task.andThen` calls)\n -> `read` reads the content of the files.\n -> `write` writes the manipulated in-memory representations of the files back to disk.\n sequence task =\n task\n |> Task.map (Shikensu.withExtension \"md\")\n |> Task.andThen Shikensu.read\n |> Task.map (Shikensu.renderContent markdownRenderer) -- See `example` folder\n |> Task.andThen (Shikensu.write destinationFocus)\n\n","type":"(Shikensu.Task -> Shikensu.Task) -> Shikensu.Focus.Focus -> Shikensu.Program"},{"name":"programs","comment":" Provides a way to make multiple lists and operate on them.\n\nTechnically not multiple programs, but same idea as\nthe `program` function, just with multiple lists.\n\n import Shikensu\n import Shikensu.Focus exposing (Focus(..))\n\n Shikensu.programs\n [ { focus = Relative (Path.directory [ \"posts\" ])\n , sequence = Task.andThen Shikensu.read\n }\n , { focus = Relative (Path.directory [ \"images\" ])\n , sequence = Task.map (\\bundle -> ...)\n }\n ]\n\n","type":"Array.Array { focus : Shikensu.Focus.Focus, sequence : Shikensu.Task -> Shikensu.Task } -> Shikensu.Program"},{"name":"read","comment":" Read the files in the given compendium/bundle,\nsetting the `content` property in the definition.\n","type":"Shikensu.Bundle.Bundle -> Shikensu.Task"},{"name":"write","comment":" Write each definition to their respective location.\nThe location will depend on the focus and the environment it was run in.\n","type":"Shikensu.Focus.Focus -> Shikensu.Bundle.Bundle -> Shikensu.Task"}],"binops":[]},"Shikensu.Bundle":{"name":"Shikensu.Bundle","comment":"\n\n# Bundle\n\n@docs Bundle, mapCompendium\n\n","unions":[],"aliases":[{"name":"Bundle","comment":" The bundle which is the value of the `Shikensu.Task` type.\n\nMost important part here is the `compendium`, the list of definitions.\nThe rest is contextual information.\n\n","args":[],"type":"{ compendium : Array.Array Shikensu.Definition.Definition, fsPermission : FileSystem.Permission, readingDirectory : Maybe.Maybe (Shikensu.Path.Path Shikensu.Path.Directory), workingDirectory : Shikensu.Path.Path Shikensu.Path.Directory }"}],"values":[{"name":"mapCompendium","comment":" Convenience function to map over array of `Definition`s.\n","type":"(Array.Array Shikensu.Definition.Definition -> Array.Array Shikensu.Definition.Definition) -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"}],"binops":[]},"Shikensu.Contrib":{"name":"Shikensu.Contrib","comment":"\n\nPremade functions to manipulate your bundles/definitions with.\n\n\n# Contrib\n\n@docs clearMetadata, clone, copyPropsToMetadata, enclose, exclude, insertMetadata, permalink, rename, renameExtension, renderContent, replaceMetadata, setContent, transformContent, withBaseName, withDirectory, withExtension, withMetadata\n\n","unions":[],"aliases":[],"values":[{"name":"clearMetadata","comment":" Clear metadata.\n","type":"Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"clone","comment":" Clone.\n\nFor each definition that has the given `relativePath` (1st argument),\nmake a clone with a new `relativePath` (2nd argument),\nand add that into the compendium just after the matching definition.\n\n >>> clone \"index.html\" \"200.html\" bundle\n\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"copyPropsToMetadata","comment":" Copy definition properties into the metadata.\n","type":"Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"enclose","comment":" Append the given directory path to the directory path of each definition.\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"exclude","comment":" Exclude.\n\nFilter out the definitions that have the given `relativePath`.\n\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"insertMetadata","comment":" Insert additional metadata.\n","type":"Dict.Dict String.String Json.Encode.Value -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"permalink","comment":" Permalink.\n\nAppend the baseName to the directoryPath\nand change the baseName to the given string.\nIt will NOT change definitions that already have the new baseName.\n\n >>> permalink \"index\" compendium\n\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"rename","comment":" Rename.\n\nChange the `relativePath` of the definitions that match a given `relativePath`.\nFor example, if you have a definition with the relativePath path `a/b/example.html`:\n\n >>> rename\n ..> (Path.file [ \"a\", \"b\", \"example.html\" ])\n ..> (Path.file [ \"example\", \"index.html\" ])\n ..> compendium\n\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"renameExtension","comment":" Rename extension.\n\nExample:\n\n >>> renameExtension \"markdown\" \"html\" compendium\n ..> -- The definitions that had the extensionName \"markdown\"\n ..> -- now have the extensionName \"html\"\n\n","type":"String.String -> String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"renderContent","comment":" Render content.\n\nReplace the `content` property by providing a renderer.\nA renderer is a function with the signature `Definition -> Maybe Bytes`.\nYou can use this to render templates, markdown, etc.\n\n","type":"(Shikensu.Definition.Definition -> Maybe.Maybe Bytes.Bytes) -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"replaceMetadata","comment":" Replace metadata.\n\nReplace the current metadata dictionary with another one.\n\n","type":"Dict.Dict String.String Json.Encode.Value -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"setContent","comment":" Set content.\n\nSet content directly.\n\n","type":"Bytes.Bytes -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"transformContent","comment":" Transform content.\n\nAlias for `renderContent`.\n\n","type":"(Shikensu.Definition.Definition -> Maybe.Maybe Bytes.Bytes) -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withBaseName","comment":" Only keep definitions with the given base name.\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withDirectory","comment":" Only keep definitions with the given directory path.\n","type":"Shikensu.Path.Path Shikensu.Path.Directory -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withExtension","comment":" Only keep definitions with the given extension.\n","type":"String.String -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"},{"name":"withMetadata","comment":" Only keep definitions with the given metadata.\n","type":"String.String -> Json.Encode.Value -> Shikensu.Bundle.Bundle -> Shikensu.Bundle.Bundle"}],"binops":[]},"Shikensu.Definition":{"name":"Shikensu.Definition","comment":"\n\n# Definition\n\n@docs Definition, create, fork, relativePath\n\n","unions":[],"aliases":[{"name":"Definition","comment":" **A piece of content.**\n\nExample definition, given:\nThe working directory root path `/Users/icidasset/Projects/shikensu/example/`\nand the full item path `/Users/icidasset/Projects/shikensu/example/test/hello.md`\n\n { baseName = \"hello\"\n , content = Nothing\n , directoryPath = Path.directory [ \"test\" ]\n , extensionName = Just \"md\"\n , metadata = Dict.empty\n }\n\n","args":[],"type":"{ baseName : String.String, content : Maybe.Maybe Bytes.Bytes, directoryPath : Shikensu.Path.Path Shikensu.Path.Directory, extensionName : Maybe.Maybe String.String, metadata : Dict.Dict String.String Json.Encode.Value }"}],"values":[{"name":"create","comment":" Create a definition, given a relative path.\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Definition.Definition"},{"name":"fork","comment":" Fork a definition, given a relative path.\nTaking the metadata and content of the original definition.\n","type":"Shikensu.Path.Path Shikensu.Path.File -> Shikensu.Definition.Definition -> Shikensu.Definition.Definition"},{"name":"relativePath","comment":" The path relative to the working directory.\n","type":"Shikensu.Definition.Definition -> Shikensu.Path.Path Shikensu.Path.File"}],"binops":[]},"Shikensu.Error":{"name":"Shikensu.Error","comment":"\n\n# Error\n\n@docs Error, toString\n\n","unions":[{"name":"Error","comment":"","args":[],"cases":[["ErrorMessage",["String.String"]],["PlatformAccessError",["Shikensu.Path.Path Shikensu.Path.Encapsulated","FileSystem.AccessError"]],["PlatformUnknownError",["FileSystem.UnknownFileSystemError"]]]}],"aliases":[],"values":[{"name":"toString","comment":"","type":"Shikensu.Error.Error -> String.String"}],"binops":[]},"Shikensu.Focus":{"name":"Shikensu.Focus","comment":"\n\n# Focus\n\n@docs Focus, toAbsolutePath\n\n","unions":[{"name":"Focus","comment":"","args":[],"cases":[["CurrentDirectory",[]],["Relative",["Shikensu.Path.Path Shikensu.Path.Directory"]],["Absolute",["Shikensu.Path.Path Shikensu.Path.Directory"]]]}],"aliases":[],"values":[{"name":"toAbsolutePath","comment":"","type":"{ cwd : Shikensu.Path.Path Shikensu.Path.Directory } -> Shikensu.Focus.Focus -> Shikensu.Path.Path Shikensu.Path.Directory"}],"binops":[]},"Shikensu.Path":{"name":"Shikensu.Path","comment":"\n\n# Paths\n\n@docs Path, Directory, File, Encapsulated, Kind\n\n\n# Creation\n\n@docs directory, file\n\n\n# POSIX\n\n@docs fromPosix, toPosix\n\n\n# Encapsulation\n\n@docs encapsulate\n\n\n# Functions\n\n@docs combine, kind, length, map, unwrap\n\n","unions":[{"name":"Directory","comment":" ๐Ÿ‘ป Directory\n","args":[],"cases":[]},{"name":"Encapsulated","comment":" ๐Ÿ‘ป Encapsulated\n","args":[],"cases":[]},{"name":"File","comment":" ๐Ÿ‘ป File\n","args":[],"cases":[]},{"name":"Kind","comment":" ","args":[],"cases":[["Directory",[]],["File",[]]]},{"name":"Path","comment":" Path type.\nThis is used with the [phantom ๐Ÿ‘ป types](#phantom-types).\n\n directoryPath : Path Directory\n filePath : Path File\n encapsulatedPath : Path Encapsulated\n\n","args":["kind"],"cases":[]}],"aliases":[],"values":[{"name":"combine","comment":" Combine a directory path and another path.\n\n","type":"Shikensu.Path.Path Shikensu.Path.Directory -> Shikensu.Path.Path kind -> Shikensu.Path.Path kind"},{"name":"directory","comment":" Create a directory path.\n\n directory [ \"Audio\", \"Playlists\" ]\n\n","type":"Array.Array String.String -> Shikensu.Path.Path Shikensu.Path.Directory"},{"name":"encapsulate","comment":" Encapsulate a path.\n","type":"Shikensu.Path.Path kind -> Shikensu.Path.Path Shikensu.Path.Encapsulated"},{"name":"file","comment":" Create a file path.\n\n file [ \"Document\", \"invoice.pdf\" ]\n\n","type":"Array.Array String.String -> Shikensu.Path.Path Shikensu.Path.File"},{"name":"fromPosix","comment":" Convert a POSIX formatted string to a path.\nThis will return a `Encapsulated` path. To get a path of the type `Path Directory` or `Path File`, use the functions in the `Shikensu.Path.Encapsulated` module.\n\n >>> import Shikensu.Path.Encapsulated\n >>> \"foo/bar/\"\n ..> |> fromPosix\n ..> |> Shikensu.Path.Encapsulated.toDirectory\n Just (directory [ \"foo\", \"bar\" ])\n\n >>> \"foo/bar\"\n ..> |> fromPosix\n ..> |> Shikensu.Path.Encapsulated.toFile\n Just (file [ \"foo\", \"bar\" ])\n\n","type":"String.String -> Shikensu.Path.Path Shikensu.Path.Encapsulated"},{"name":"kind","comment":" Get the path kind.\n\n >>> kind (directory [])\n Directory\n >>> kind (file [])\n File\n\nEven if a path is encapsulated,\nyou can still check the kind of path it is.\n\n >>> kind (encapsulate <| directory [])\n Directory\n >>> kind (encapsulate <| file [])\n File\n\n","type":"Shikensu.Path.Path kind -> Shikensu.Path.Kind"},{"name":"length","comment":" Length.\n","type":"Shikensu.Path.Path kind -> Basics.Int"},{"name":"map","comment":" Map.\n","type":"(Array.Array String.String -> Array.Array String.String) -> Shikensu.Path.Path kind -> Shikensu.Path.Path kind"},{"name":"toPosix","comment":" Convert a path to the POSIX format.\n\n >>> toPosix { absolute = True } (directory [ \"foo\", \"bar\"])\n \"/foo/bar/\"\n >>> toPosix { absolute = False } (file [ \"foo\", \"bar\"])\n \"foo/bar\"\n\n","type":"{ absolute : Basics.Bool } -> Shikensu.Path.Path kind -> String.String"},{"name":"unwrap","comment":" Get the path parts.\n\n >>> unwrap (directory [ \"foo\", \"bar\" ])\n [ \"foo\", \"bar\" ]\n >>> unwrap (file [ \"foo\", \"bar\" ])\n [ \"foo\", \"bar\" ]\n\n","type":"Shikensu.Path.Path kind -> Array.Array String.String"}],"binops":[]},"Shikensu.Path.Encapsulated":{"name":"Shikensu.Path.Encapsulated","comment":"\n\n# Encapsulated Paths\n\n@docs toDirectory, toFile\n\n","unions":[],"aliases":[],"values":[{"name":"toDirectory","comment":" Remove the membrane and extract a `Path Directory`.\n","type":"Shikensu.Path.Path Shikensu.Path.Encapsulated -> Maybe.Maybe (Shikensu.Path.Path Shikensu.Path.Directory)"},{"name":"toFile","comment":" Remove the membrane and extract a `Path File`.\n","type":"Shikensu.Path.Path Shikensu.Path.Encapsulated -> Maybe.Maybe (Shikensu.Path.Path Shikensu.Path.File)"}],"binops":[]}} \ No newline at end of file diff --git a/gren.json b/gren.json index 2582f98..dea5b64 100644 --- a/gren.json +++ b/gren.json @@ -4,7 +4,7 @@ "name": "icidasset/shikensu-gren", "summary": "Run a sequence of functions on in-memory representations of files", "license": "BSD-3-Clause", - "version": "5.0.0", + "version": "5.0.1", "exposed-modules": [ "Shikensu", "Shikensu.Bundle", diff --git a/package-lock.json b/package-lock.json index 4b768e3..0db9d31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "devDependencies": { - "gren": "^0.0.1", + "gren-lang": "^0.3.0", "gren-packages": "^3.1.0" } }, @@ -742,15 +742,6 @@ "node": ">=6" } }, - "node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -852,16 +843,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/bent": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/bent/-/bent-1.6.1.tgz", - "integrity": "sha512-20yih3t4mYlC1+xxIoAtHrs4FOQK+k+ucFTAV+sFbKUQfdsHtgogr3GKe1SdOwc729edGXiHJmgxQiR0xNFSIw==", - "dev": true, - "dependencies": { - "caseless": "~0.12.0", - "is-stream": "^2.0.0" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -1052,12 +1033,6 @@ } ] }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, "node_modules/chai": { "version": "4.3.10", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", @@ -2003,22 +1978,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/gren": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/gren/-/gren-0.0.1.tgz", - "integrity": "sha512-ID68qSUuLh05SUITnvzZ2AfE2RnKGtnFkufp1APExoGvoevzL6WJ3CYZmcSpAoPsYTLN14//gTpwFofPDy6PKQ==", - "dev": true, - "dependencies": { - "bent": "^1.1.0", - "chalk": "^2.3.2", - "json-colorizer": "^1.1.0", - "lodash": "^4.17.5", - "minimist": "^1.2.0" - }, - "bin": { - "gren": "bin/gren" - } - }, "node_modules/gren-compiler-library": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/gren-compiler-library/-/gren-compiler-library-0.3.0.tgz", @@ -2029,6 +1988,18 @@ "xdg-basedir": "^5.1.0" } }, + "node_modules/gren-lang": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gren-lang/-/gren-lang-0.3.0.tgz", + "integrity": "sha512-Gl/0jckyK97BH/lUPj68vP4m05d1QTrLlhZ2ELQgKfDJu8PVKeG+LtRRkdpIzcncCfgR/htWdwt2UkwpPXzalA==", + "dev": true, + "dependencies": { + "gren-compiler-library": "0.3.0" + }, + "bin": { + "gren": "index.js" + } + }, "node_modules/gren-packages": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/gren-packages/-/gren-packages-3.1.0.tgz", @@ -2080,18 +2051,6 @@ "node": ">= 0.4.0" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2769,49 +2728,6 @@ "node": ">=4" } }, - "node_modules/json-colorizer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-1.1.1.tgz", - "integrity": "sha512-K+rrXXwZMLSuUsJRGTH5CgRNQaJWgTWS+jRoHf2CdTYVYUZf6x7D0UlLul5do+WpifJsSw85XH5PHV0Q+A6xIA==", - "dev": true, - "dependencies": { - "chalk": "^1.1.3" - } - }, - "node_modules/json-colorizer/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json-colorizer/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/json-colorizer/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3116,12 +3032,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -3419,15 +3329,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", @@ -4966,18 +4867,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -6203,12 +6092,6 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -6295,16 +6178,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "bent": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/bent/-/bent-1.6.1.tgz", - "integrity": "sha512-20yih3t4mYlC1+xxIoAtHrs4FOQK+k+ucFTAV+sFbKUQfdsHtgogr3GKe1SdOwc729edGXiHJmgxQiR0xNFSIw==", - "dev": true, - "requires": { - "caseless": "~0.12.0", - "is-stream": "^2.0.0" - } - }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -6437,12 +6310,6 @@ "integrity": "sha512-qxdO8KPWPQ+Zk6bvNpPeQIOH47qZSYdFZd6dXQzb2KzhnSXju4Kd7H1PkSJx6NICSMgo/IhRZRhhfPTHYpJUCA==", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true - }, "chai": { "version": "4.3.10", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", @@ -7168,19 +7035,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "gren": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/gren/-/gren-0.0.1.tgz", - "integrity": "sha512-ID68qSUuLh05SUITnvzZ2AfE2RnKGtnFkufp1APExoGvoevzL6WJ3CYZmcSpAoPsYTLN14//gTpwFofPDy6PKQ==", - "dev": true, - "requires": { - "bent": "^1.1.0", - "chalk": "^2.3.2", - "json-colorizer": "^1.1.0", - "lodash": "^4.17.5", - "minimist": "^1.2.0" - } - }, "gren-compiler-library": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/gren-compiler-library/-/gren-compiler-library-0.3.0.tgz", @@ -7191,6 +7045,15 @@ "xdg-basedir": "^5.1.0" } }, + "gren-lang": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/gren-lang/-/gren-lang-0.3.0.tgz", + "integrity": "sha512-Gl/0jckyK97BH/lUPj68vP4m05d1QTrLlhZ2ELQgKfDJu8PVKeG+LtRRkdpIzcncCfgR/htWdwt2UkwpPXzalA==", + "dev": true, + "requires": { + "gren-compiler-library": "0.3.0" + } + }, "gren-packages": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/gren-packages/-/gren-packages-3.1.0.tgz", @@ -7230,15 +7093,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7755,42 +7609,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-colorizer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/json-colorizer/-/json-colorizer-1.1.1.tgz", - "integrity": "sha512-K+rrXXwZMLSuUsJRGTH5CgRNQaJWgTWS+jRoHf2CdTYVYUZf6x7D0UlLul5do+WpifJsSw85XH5PHV0Q+A6xIA==", - "dev": true, - "requires": { - "chalk": "^1.1.3" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } - } - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -8042,12 +7860,6 @@ "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -8292,12 +8104,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, "minipass": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", @@ -9459,15 +9265,6 @@ } } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", diff --git a/package.json b/package.json index 249bfde..f78e61e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "devDependencies": { - "gren": "^0.0.1", + "gren-lang": "^0.3.0", "gren-packages": "^3.1.0" } } diff --git a/src/Shikensu.gren b/src/Shikensu.gren index 9d0ee2c..a1a3703 100644 --- a/src/Shikensu.gren +++ b/src/Shikensu.gren @@ -307,7 +307,7 @@ bundle fsPermission compendium = (\cwd -> { compendium = compendium - , -- + , -- fsPermission = fsPermission , readingDirectory = Nothing , workingDirectory = cwd diff --git a/src/Shikensu/Definition.gren b/src/Shikensu/Definition.gren index 6bafaff..0dc7213 100644 --- a/src/Shikensu/Definition.gren +++ b/src/Shikensu/Definition.gren @@ -105,10 +105,13 @@ fork relPath def = baseName : String -> String baseName name = - name - |> String.split "." - |> Array.dropLast 1 - |> String.join "." + if String.contains "." name then + name + |> String.split "." + |> Array.dropLast 1 + |> String.join "." + else + name directoryPath : Path File -> Path Directory @@ -121,4 +124,7 @@ directoryPath relPath = extensionName : String -> Maybe String extensionName name = - Array.last (String.split "." name) + if String.contains "." name then + Array.last (String.split "." name) + else + Nothing diff --git a/src/Shikensu/Path.gren b/src/Shikensu/Path.gren index 343f805..a0e95fb 100644 --- a/src/Shikensu/Path.gren +++ b/src/Shikensu/Path.gren @@ -99,7 +99,7 @@ file = {-| Convert a POSIX formatted string to a path. -This will return a `Encapsulated` path. To get a path of the type `Path Directory` or `Path File`, use the functions in the `Webnative.Path.Encapsulated` module. +This will return a `Encapsulated` path. To get a path of the type `Path Directory` or `Path File`, use the functions in the `Shikensu.Path.Encapsulated` module. >>> import Shikensu.Path.Encapsulated >>> "foo/bar/"