From 40265344573ccf2abb77cc828881861c1b647ccf Mon Sep 17 00:00:00 2001 From: mdwagner Date: Sat, 15 Jul 2023 17:07:20 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20luckyfra?= =?UTF-8?q?mework/lucky=5Ftemplate@dd924c70881617803287ca8eaebb0dcc773f40c?= =?UTF-8?q?9=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LuckyTemplate.html | 28 +++++++++++++-------------- LuckyTemplate/Error.html | 2 +- LuckyTemplate/FileIO.html | 2 +- LuckyTemplate/FileSystem.html | 6 +++--- LuckyTemplate/Fileable.html | 4 ++-- LuckyTemplate/Folder.html | 36 +++++++++++++++++------------------ LuckyTemplate/Snapshot.html | 2 +- LuckyTemplate/Spec.html | 4 ++-- index.json | 2 +- search-index.js | 2 +- 10 files changed, 44 insertions(+), 44 deletions(-) diff --git a/LuckyTemplate.html b/LuckyTemplate.html index 216d130..509ce9f 100644 --- a/LuckyTemplate.html +++ b/LuckyTemplate.html @@ -167,49 +167,49 @@

- + lucky_template.cr
- + lucky_template/error.cr
- + lucky_template/file.cr
- + lucky_template/file_system.cr
- + lucky_template/folder.cr
- + lucky_template/version.cr
- + spec.cr @@ -349,7 +349,7 @@


- [View source] + [View source]
@@ -373,7 +373,7 @@


- [View source] + [View source]
@@ -412,7 +412,7 @@


- [View source] + [View source]
@@ -444,7 +444,7 @@


- [View source] + [View source]
@@ -470,7 +470,7 @@


- [View source] + [View source]
@@ -496,7 +496,7 @@


- [View source] + [View source]
@@ -521,7 +521,7 @@


- [View source] + [View source]
diff --git a/LuckyTemplate/Error.html b/LuckyTemplate/Error.html index ece10dd..2e68326 100644 --- a/LuckyTemplate/Error.html +++ b/LuckyTemplate/Error.html @@ -155,7 +155,7 @@

- + lucky_template/error.cr diff --git a/LuckyTemplate/FileIO.html b/LuckyTemplate/FileIO.html index c3addaf..43438df 100644 --- a/LuckyTemplate/FileIO.html +++ b/LuckyTemplate/FileIO.html @@ -152,7 +152,7 @@

- + lucky_template/file.cr diff --git a/LuckyTemplate/FileSystem.html b/LuckyTemplate/FileSystem.html index 8ecc87e..c37949e 100644 --- a/LuckyTemplate/FileSystem.html +++ b/LuckyTemplate/FileSystem.html @@ -153,7 +153,7 @@

- + lucky_template/file_system.cr @@ -287,7 +287,7 @@


- [View source] + [View source]
@@ -303,7 +303,7 @@


- [View source] + [View source]
diff --git a/LuckyTemplate/Fileable.html b/LuckyTemplate/Fileable.html index c229dbc..8b193f3 100644 --- a/LuckyTemplate/Fileable.html +++ b/LuckyTemplate/Fileable.html @@ -189,7 +189,7 @@

- + lucky_template/file.cr @@ -261,7 +261,7 @@


- [View source] + [View source]
diff --git a/LuckyTemplate/Folder.html b/LuckyTemplate/Folder.html index 67a73b9..34be6fd 100644 --- a/LuckyTemplate/Folder.html +++ b/LuckyTemplate/Folder.html @@ -155,7 +155,7 @@

- + lucky_template/folder.cr @@ -369,7 +369,7 @@


- [View source] + [View source]
@@ -400,7 +400,7 @@


- [View source] + [View source]
@@ -435,7 +435,7 @@


- [View source] + [View source]
@@ -470,7 +470,7 @@


- [View source] + [View source]
@@ -506,7 +506,7 @@


- [View source] + [View source]
@@ -542,7 +542,7 @@


- [View source] + [View source]
@@ -569,7 +569,7 @@


- [View source] + [View source]
@@ -596,7 +596,7 @@


- [View source] + [View source]
@@ -627,7 +627,7 @@


- [View source] + [View source]
@@ -658,7 +658,7 @@


- [View source] + [View source]
@@ -689,7 +689,7 @@


- [View source] + [View source]
@@ -718,7 +718,7 @@


- [View source] + [View source]
@@ -747,7 +747,7 @@


- [View source] + [View source]
@@ -776,7 +776,7 @@


- [View source] + [View source]
@@ -797,7 +797,7 @@


- [View source] + [View source]
@@ -828,7 +828,7 @@


- [View source] + [View source]
@@ -850,7 +850,7 @@


- [View source] + [View source]
diff --git a/LuckyTemplate/Snapshot.html b/LuckyTemplate/Snapshot.html index b043531..1276cf6 100644 --- a/LuckyTemplate/Snapshot.html +++ b/LuckyTemplate/Snapshot.html @@ -165,7 +165,7 @@

- + lucky_template.cr diff --git a/LuckyTemplate/Spec.html b/LuckyTemplate/Spec.html index a4d2002..b292344 100644 --- a/LuckyTemplate/Spec.html +++ b/LuckyTemplate/Spec.html @@ -156,7 +156,7 @@

- + spec.cr @@ -229,7 +229,7 @@


- [View source] + [View source]
diff --git a/index.json b/index.json index f26d949..f15b90a 100644 --- a/index.json +++ b/index.json @@ -1 +1 @@ -{"repository_name":"lucky_template","body":"# LuckyTemplate\n\n[![CI](https://github.com/luckyframework/lucky_template/actions/workflows/ci.yml/badge.svg)](https://github.com/mdwagner/lucky_template/actions/workflows/ci.yml)\n\n[LuckyTemplate](https://github.com/luckyframework/lucky_template) is a simple, yet versatile, library for creating file and folder structures as code templates. It has a lot in common with [Teeplate](https://github.com/mosop/teeplate), but it offers more capabilities and more ways to generate content.\n\n## Features\n\n* Allows you to create a virtual file/folder structure, which can be written to disk anywhere.\n* Supports using folders like building blocks, allowing you to reuse folders within other folders.\n* File content can be static or dynamic\n* Includes a Spec helper to validate that the files/folders within a location exist after writing to disk.\n* Provides a snapshot of a folder structure for custom validation or for any other purpose like generating log output.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n ```yaml\n dependencies:\n lucky_template:\n github: luckyframework/lucky_template\n version: ~> 0.1.0\n ```\n\n2. Run `shards install`\n\n## Quick Start\n\nHere's a basic example of how to use LuckyTemplate:\n\n```crystal\nrequire \"lucky_template\"\n\nLuckyTemplate.write!(Path[\".\"]) do |folder|\n folder.add_file(\".keep\")\nend\n```\n\nThis will create a folder at the current directory with an empty `.keep` file. See the sections below for more complex examples.\n\n## Examples\n\n### Simple Template\n\nIn this example, we create a simple README file using an ECR template, a welcome file, and a license file. We also create a new file and folder dynamically in a subfolder.\n\n```crystal\nrequire \"lucky_template\"\n\nclass Readme\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"README.md.ecr\"\nend\n\nname = \"John\"\nfolder = LuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"README.md\", Readme.new(name))\n\n dir.add_file(\"Welcome.md\") do |io|\n io << \"# Welcome \" << name << \"!\\n\"\n end\n\n dir.add_file(\"LICENSE\", <<-LICENSE)\n The MIT License (MIT)\n ...\n LICENSE\n\n dir.add_folder(\"src\") do |src|\n src.add_file(\".keep\")\n\n src.add_folder(name.downcase) do |name_dir|\n name_dir.add_file(\"#{name.downcase}.cr\", <<-CR)\n class #{name}\n end\n\n pp! #{name}.new\n CR\n end\n end\nend\n```\n\n### Creating Multiple Folders\n\nYou can also create multiple folders at once or nest them within other folders:\n\n```crystal\nfolder1 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_one.txt\")\nend\nfolder2 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_two.txt\")\nend\nfolder3 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_three.txt\")\n dir.insert_folder(\"folder1\", folder1)\n dir.insert_folder(\"folder2\", folder2)\nend\nLuckyTemplate.write!(Path[\".\"], folder3)\n```\n\n### Snapshot Folders\n\nAnother great feature is that you can take snapshots of folder structures:\n\n```crystal\nsnapshot = LuckyTemplate.snapshot(folder3)\n\nsnapshot.each do |path, type|\n case type\n in .file?\n puts \"File: #{path}\"\n in .folder?\n puts \"Folder: #{path}\"\n end\nend\n```\n\n### Using Non-Crystal Templates\n\nIf you prefer to use another template engine besides Crystal's, you can do so by creating a running process, as shown in the following example with gettext `envsubst`:\n\n```crystal\nclass ExternalTemplate\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => @name,\n }\n )\n end\nend\n\nLuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"external_file\", ExternalTemplate.new(\"John\"))\nend\n```\n\n## FAQ\n\n- Why create this if Teeplate already exists? Initially, I tried to add Windows support to Teeplate, but ran into some issues, that prompted me to just ask the question: Is this effort worth it? [This discussion](https://github.com/luckyframework/lucky/discussions/1812) gave me the push I needed to create a POC (proof-of-concept), which this library is the result of.\n- Does it support Windows? Yes, it runs the spec suite on Linux & Windows.\n- Why do folder snapshots not contain the file content? Because I haven't found a good enough use-case to support this. Snapshots are supposed to be an escape hatch, where you can get the file/folder structure, but decide what you would like to do with it. Having it include file content doesn't really make sense when LuckyTemplate already writes it to disk for you. But, if you have a good use-case that I haven't thought of, open an issue!\n- Can I use it with `crinja`, `kilt`, `slang`, ...? Yes, or at least, that's the goal! If you find it doesn't work with something, open an issue.\n\n## Contributing\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Michael Wagner](https://github.com/mdwagner) - creator and maintainer\n","program":{"html_id":"lucky_template/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"lucky_template","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"lucky_template/LuckyTemplate","path":"LuckyTemplate.html","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L5"},{"filename":"src/lucky_template/error.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/error.cr#L1"},{"filename":"src/lucky_template/file.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L1"},{"filename":"src/lucky_template/file_system.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L1"},{"filename":"src/lucky_template/folder.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L1"},{"filename":"src/lucky_template/version.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/version.cr#L1"},{"filename":"src/spec.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/spec.cr#L1"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VERSION","name":"VERSION","value":"{{ (`shards version /home/runner/work/lucky_template/lucky_template/src/lucky_template`).chomp.stringify }}"}],"extended_modules":[{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}],"doc":"Public interface","summary":"

Public interface

","instance_methods":[{"html_id":"create_folder(&:Folder->):Folder-instance-method","name":"create_folder","doc":"Creates a `Folder` and yields it, before returning the **unlocked** `Folder`\n\nNOTE: `Folder` is **locked** when being yielded. See `Folder#locked?`.\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.locked? # => true\n dir.add_file(\".keep\")\nend\nfolder.locked? # => false\n```","summary":"

Creates a Folder and yields it, before returning the unlocked Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":27,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L27"},"def":{"name":"create_folder","yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"Folder.new.tap do |folder|\n folder.lock do\n yield folder\n end\nend"}},{"html_id":"create_folder:Folder-instance-method","name":"create_folder","doc":"Creates an empty `Folder`\n\nExample:\n```\nfolder = LuckyTemplate.create_folder\nfolder.locked? # => false\n```","summary":"

Creates an empty Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":42,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L42"},"def":{"name":"create_folder","return_type":"Folder","visibility":"Public","body":"create_folder do\nend"}},{"html_id":"snapshot(folder:Folder):Snapshot-instance-method","name":"snapshot","doc":"Returns a new `Snapshot` of all files and folders within this _folder_\n\nRaises `Error` if _folder_ is **locked**\n\nNOTE: **Does not** include file instances in results, only paths\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.add_file(\".keep\")\n dir.add_file(\"README.md\")\n dir.add_folder(\"src\") do |src|\n src.add_file(\"hello.cr\")\n end\nend\nputs LuckyTemplate.snapshot(folder)\n```\n\nOutput:\n```\n{\n \".keep\" => LuckyTemplate::FileSystem::File,\n \"README.md\" => LuckyTemplate::FileSystem::File,\n \"src\" => LuckyTemplate::FileSystem::Folder,\n \"src/hello.cr\" => LuckyTemplate::FileSystem::File,\n}\n```","summary":"

Returns a new Snapshot of all files and folders within this folder

","abstract":false,"args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(folder : Folder) : Snapshot","args_html":"(folder : Folder) : Snapshot","location":{"filename":"src/lucky_template.cr","line_number":179,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L179"},"def":{"name":"snapshot","args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Snapshot","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot get snapshot if folder is locked\"))\nend\nSnapshot.new.tap do |_snapshot|\n snapshot_folder(Path.new, folder, _snapshot)\nend\n"}},{"html_id":"validate!(location:Path,folder:Folder):Bool-instance-method","name":"validate!","doc":"Returns `true` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nRaises `::File::NotFoundError` if either a file or folder does not exist\n\nRaises `Error` if _folder_ is **locked**\n\nExample:\n```\nbegin\n templates_folder = LuckyTemplate.create_folder\n LuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\nrescue err : ::File::NotFoundError\n puts err.message\nend\n```","summary":"

Returns true if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":119,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L119"},"def":{"name":"validate!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot validate while folder is locked\"))\nend\n(snapshot(folder)).each do |filepath, type|\n path = location / filepath\n case type\n in .file?\n ::File.size(path)\n in .folder?\n Dir.open(path) do\n end\n end\nend\ntrue\n"}},{"html_id":"validate?(location:Path,folder:Folder):Bool-instance-method","name":"validate?","doc":"Returns a `Bool` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\n```","summary":"

Returns a Bool if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":146,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L146"},"def":{"name":"validate?","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"begin\n validate!(location, folder)\nrescue\n false\nend"}},{"html_id":"write!(location:Path,folder:Folder):Nil-instance-method","name":"write!","doc":"Writes the folder to disk at the given _location_\n\nRaises `Error` if _folder_ is **locked**\n\nRaises `::File::AlreadyExistsError` if _location_ is not an existing folder\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.write!(Path[\"./templates\"], templates_folder)\n```","summary":"

Writes the folder to disk at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Nil","args_html":"(location : Path, folder : Folder) : Nil","location":{"filename":"src/lucky_template.cr","line_number":57,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L57"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Nil","visibility":"Public","body":"Dir.mkdir_p(location)\nif folder.locked?\n raise(Error.new(\"Cannot write to disk if folder is locked\"))\nend\nwrite_folder!(location, folder)\n"}},{"html_id":"write!(location:Path,&:Folder->):Folder-instance-method","name":"write!","doc":"Shorthand for `.create_folder` and `.write!`\n\nExample:\n```\nfolder = LuckyTemplate.write!(Path[\"./templates\"]) do |templates_folder|\n templates_folder.add_file(\".keep\")\nend\n```","summary":"

Shorthand for .create_folder and .write!

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path, & : Folder -> ) : Folder","args_html":"(location : Path, & : Folder -> ) : Folder","location":{"filename":"src/lucky_template.cr","line_number":92,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L92"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"create_folder do |folder|\n yield folder\nend.tap do |folder|\n write!(location, folder)\nend"}}],"types":[{"html_id":"lucky_template/LuckyTemplate/Error","path":"LuckyTemplate/Error.html","kind":"class","full_name":"LuckyTemplate::Error","name":"Error","abstract":false,"superclass":{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/error.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/error.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A generic error class used within `LuckyTemplate`.","summary":"

A generic error class used within LuckyTemplate.

"},{"html_id":"lucky_template/LuckyTemplate/Fileable","path":"LuckyTemplate/Fileable.html","kind":"module","full_name":"LuckyTemplate::Fileable","name":"Fileable","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":48,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L48"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"An interface for a file\n\nSimple example using IO:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n```\n\nExample using ECR templates:\n```\nrequire \"ecr\"\n\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"hello.ecr\"\nend\n```\n\nExample using Process to run `envsubst`:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => \"World\",\n }\n )\n end\nend\n```","summary":"

An interface for a file

","instance_methods":[{"html_id":"to_file(io:IO):Nil-instance-method","name":"to_file","doc":"Appends contents to `IO` for a file","summary":"

Appends contents to IO for a file

","abstract":true,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO) : Nil","args_html":"(io : IO) : Nil","location":{"filename":"src/lucky_template/file.cr","line_number":50,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L50"},"def":{"name":"to_file","args":[{"name":"io","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":""}}]},{"html_id":"lucky_template/LuckyTemplate/FileIO","path":"LuckyTemplate/FileIO.html","kind":"alias","full_name":"LuckyTemplate::FileIO","name":"FileIO","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":53,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L53"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Proc(IO, Nil)","aliased_html":"IO -> Nil","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}},{"html_id":"lucky_template/LuckyTemplate/FileSystem","path":"LuckyTemplate/FileSystem.html","kind":"enum","full_name":"LuckyTemplate::FileSystem","name":"FileSystem","abstract":false,"ancestors":[{"html_id":"lucky_template/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"lucky_template/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"lucky_template/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/file_system.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"File","name":"File","value":"0"},{"id":"Folder","name":"Folder","value":"1"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `FileSystem` represents the files in the filesystem.","summary":"

A FileSystem represents the files in the filesystem.

","instance_methods":[{"html_id":"file?-instance-method","name":"file?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":4,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L4"},"def":{"name":"file?","visibility":"Public","body":"self == File"}},{"html_id":"folder?-instance-method","name":"folder?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L5"},"def":{"name":"folder?","visibility":"Public","body":"self == Folder"}}]},{"html_id":"lucky_template/LuckyTemplate/Folder","path":"LuckyTemplate/Folder.html","kind":"class","full_name":"LuckyTemplate::Folder","name":"Folder","abstract":false,"superclass":{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/folder.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `Folder` represents a filesystem directory, but in a virtual form.","summary":"

A Folder represents a filesystem directory, but in a virtual form.

","instance_methods":[{"html_id":"add_file(name:String,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(\"hello.txt\", \"hello world\")\n\nadd_file(\"hello.txt\", <<-TEXT)\nhello world\nTEXT\n\nadd_file(\"hello.txt\", \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, content : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":32,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L32"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], content, perms)"}},{"html_id":"add_file(path:Path,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(Path[\"./hello.txt\"], \"hello world\")\n\nadd_file(Path[\"./hello.txt\"], <<-TEXT)\nhello world\nTEXT\n\nadd_file(Path[\"./hello.txt\"], \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":52,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L52"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(content, perms))"}},{"html_id":"add_file(name:String,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(\"hello.txt\", Hello.new)\n\nadd_file(\"hello.txt\", Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":76,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L76"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], klass, perms)"}},{"html_id":"add_file(path:Path,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(Path[\"./hello.txt\"], Hello.new)\n\nadd_file(Path[\"./hello.txt\"], Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":100,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L100"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(klass, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\") do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(\"hello.txt\", 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(\"hello.txt\", &proc)\n\nadd_file(\"hello.txt\", 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":125,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L125"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms, &block)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(Path[\"./hello.txt\"]) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(Path[\"./hello.txt\"], 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(Path[\"./hello.txt\"], &proc)\n\nadd_file(Path[\"./hello.txt\"], 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":150,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L150"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(path, File.new(block, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\")\n\nadd_file(\"hello.txt\", 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":166,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L166"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms: perms)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample:\n```\nadd_file(Path[\"./hello.txt\"])\n\nadd_file(Path[\"./hello.txt\"], 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":182,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L182"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(nil, perms))"}},{"html_id":"add_folder(names:Enumerable(String),&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String), & : Folder -> ) : self","args_html":"(names : Enumerable(String), & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":228,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L228"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"begin\n names = (normalize_path(Path[names])).parts\nrescue Error\n raise(Error.new(\"Cannot add folders with invalid folder names\"))\nend\nprev : Folder | ::Nil = nil\nnames.each_with_index do |name, index|\n _folder : Folder = prev || self\n if found_file = _folder.files[name]?\n case found_file\n in Folder\n current_folder = found_file\n in File\n current_folder = Folder.new\n end\n else\n current_folder = Folder.new\n end\n if index == (names.size - 1)\n current_folder.lock do\n yield current_folder\n end\n end\n _folder.insert_folder(name, current_folder)\n prev = current_folder\nend\nself\n"}},{"html_id":"add_folder(path:Path,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path, & : Folder -> ) : self","args_html":"(path : Path, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":284,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L284"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(*names:String,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\") do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String, & : Folder -> ) : self","args_html":"(*names : String, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":308,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L308"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(names) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(names:Enumerable(String)):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\", \"d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String)) : self","args_html":"(names : Enumerable(String)) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":330,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L330"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"return_type":"self","visibility":"Public","body":"add_folder(names) do\nend"}},{"html_id":"add_folder(path:Path):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c/d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path) : self","args_html":"(path : Path) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":350,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L350"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do\nend"}},{"html_id":"add_folder(*names:String):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\", \"d\")\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String) : self","args_html":"(*names : String) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":370,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L370"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"return_type":"self","visibility":"Public","body":"add_folder(names)"}},{"html_id":"empty?:Bool-instance-method","name":"empty?","doc":"Checks if folder has no files or folders","summary":"

Checks if folder has no files or folders

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":405,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L405"},"def":{"name":"empty?","return_type":"Bool","visibility":"Public","body":"@files.empty?"}},{"html_id":"insert_folder(name:String,folder:Folder):self-instance-method","name":"insert_folder","doc":"Insert an existing folder\n\nRaises `Error` if one of the following are true:\n - existing folder is equal to itself\n - existing folder is locked\n\nExample:\n```\nanother_folder = LuckyTemplate::Folder.new\nLuckyTemplate.create_folder do |folder|\n folder.insert_folder(another_folder)\nend\n```","summary":"

Insert an existing folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(name : String, folder : Folder) : self","args_html":"(name : String, folder : Folder) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":387,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L387"},"def":{"name":"insert_folder","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"self","visibility":"Public","body":"if folder == self\n raise(Error.new(\"Cannot add folder equal to itself\"))\nelse\n if folder.locked?\n raise(Error.new(\"Cannot add locked folder\"))\n end\nend\n@files[name] = folder\nself\n"}},{"html_id":"locked?:Bool-instance-method","name":"locked?","doc":"Checks if folder is _locked_\n\nUsually means it's being yielded already.","summary":"

Checks if folder is locked

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":400,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L400"},"def":{"name":"locked?","return_type":"Bool","visibility":"Public","body":"@locked"}}]},{"html_id":"lucky_template/LuckyTemplate/Snapshot","path":"LuckyTemplate/Snapshot.html","kind":"alias","full_name":"LuckyTemplate::Snapshot","name":"Snapshot","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":13,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L13"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Hash(String, LuckyTemplate::FileSystem)","aliased_html":"Hash(String, LuckyTemplate::FileSystem)","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `LuckyTemplate::Snapshot` represents files and folders included within a `LuckyTemplate::Folder` at a moment in time\n\n**Key:** String path in **POSIX** form\n\n**Value:** Type of `LuckyTemplate::FileSystem`","summary":"

A LuckyTemplate::Snapshot represents files and folders included within a LuckyTemplate::Folder at a moment in time

"},{"html_id":"lucky_template/LuckyTemplate/Spec","path":"LuckyTemplate/Spec.html","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec","abstract":false,"locations":[{"filename":"src/spec.cr","line_number":2,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/spec.cr#L2"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"lucky_template/LuckyTemplate/Spec","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"instance_methods":[{"html_id":"be_valid_at(location:Path)-instance-method","name":"be_valid_at","doc":"Validates all files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem","summary":"

Validates all files and folders exist within the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path)","args_html":"(location : Path)","location":{"filename":"src/spec.cr","line_number":8,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/spec.cr#L8"},"def":{"name":"be_valid_at","args":[{"name":"location","external_name":"location","restriction":"Path"}],"visibility":"Public","body":"BeValidAtExpectation.new(location)"}}]}]}]}} \ No newline at end of file +{"repository_name":"lucky_template","body":"# LuckyTemplate\n\n[![CI](https://github.com/luckyframework/lucky_template/actions/workflows/ci.yml/badge.svg)](https://github.com/mdwagner/lucky_template/actions/workflows/ci.yml)\n\n[LuckyTemplate](https://github.com/luckyframework/lucky_template) is a simple, yet versatile, library for creating file and folder structures as code templates. It has a lot in common with [Teeplate](https://github.com/mosop/teeplate), but it offers more capabilities and more ways to generate content.\n\n## Features\n\n* Allows you to create a virtual file/folder structure, which can be written to disk anywhere.\n* Supports using folders like building blocks, allowing you to reuse folders within other folders.\n* File content can be static or dynamic\n* Includes a Spec helper to validate that the files/folders within a location exist after writing to disk.\n* Provides a snapshot of a folder structure for custom validation or for any other purpose like generating log output.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n ```yaml\n dependencies:\n lucky_template:\n github: luckyframework/lucky_template\n version: ~> 0.1.0\n ```\n\n2. Run `shards install`\n\n## Quick Start\n\nHere's a basic example of how to use LuckyTemplate:\n\n```crystal\nrequire \"lucky_template\"\n\nLuckyTemplate.write!(Path[\".\"]) do |folder|\n folder.add_file(\".keep\")\nend\n```\n\nThis will create a folder at the current directory with an empty `.keep` file. See the sections below for more complex examples.\n\n## Examples\n\n### Simple Template\n\nIn this example, we create a simple README file using an ECR template, a welcome file, and a license file. We also create a new file and folder dynamically in a subfolder.\n\n```crystal\nrequire \"lucky_template\"\n\nclass Readme\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"README.md.ecr\"\nend\n\nname = \"John\"\nfolder = LuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"README.md\", Readme.new(name))\n\n dir.add_file(\"Welcome.md\") do |io|\n io << \"# Welcome \" << name << \"!\\n\"\n end\n\n dir.add_file(\"LICENSE\", <<-LICENSE)\n The MIT License (MIT)\n ...\n LICENSE\n\n dir.add_folder(\"src\") do |src|\n src.add_file(\".keep\")\n\n src.add_folder(name.downcase) do |name_dir|\n name_dir.add_file(\"#{name.downcase}.cr\", <<-CR)\n class #{name}\n end\n\n pp! #{name}.new\n CR\n end\n end\nend\n```\n\n### Creating Multiple Folders\n\nYou can also create multiple folders at once or nest them within other folders:\n\n```crystal\nfolder1 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_one.txt\")\nend\nfolder2 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_two.txt\")\nend\nfolder3 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_three.txt\")\n dir.insert_folder(\"folder1\", folder1)\n dir.insert_folder(\"folder2\", folder2)\nend\nLuckyTemplate.write!(Path[\".\"], folder3)\n```\n\n### Snapshot Folders\n\nAnother great feature is that you can take snapshots of folder structures:\n\n```crystal\nsnapshot = LuckyTemplate.snapshot(folder3)\n\nsnapshot.each do |path, type|\n case type\n in .file?\n puts \"File: #{path}\"\n in .folder?\n puts \"Folder: #{path}\"\n end\nend\n```\n\n### Using Non-Crystal Templates\n\nIf you prefer to use another template engine besides Crystal's, you can do so by creating a running process, as shown in the following example with gettext `envsubst`:\n\n```crystal\nclass ExternalTemplate\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => @name,\n }\n )\n end\nend\n\nLuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"external_file\", ExternalTemplate.new(\"John\"))\nend\n```\n\n## FAQ\n\n- Why create this if Teeplate already exists? Initially, I tried to add Windows support to Teeplate, but ran into some issues, that prompted me to just ask the question: Is this effort worth it? [This discussion](https://github.com/luckyframework/lucky/discussions/1812) gave me the push I needed to create a POC (proof-of-concept), which this library is the result of.\n- Does it support Windows? Yes, it runs the spec suite on Linux & Windows.\n- Why do folder snapshots not contain the file content? Because I haven't found a good enough use-case to support this. Snapshots are supposed to be an escape hatch, where you can get the file/folder structure, but decide what you would like to do with it. Having it include file content doesn't really make sense when LuckyTemplate already writes it to disk for you. But, if you have a good use-case that I haven't thought of, open an issue!\n- Can I use it with `crinja`, `kilt`, `slang`, ...? Yes, or at least, that's the goal! If you find it doesn't work with something, open an issue.\n\n## Contributing\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Michael Wagner](https://github.com/mdwagner) - creator and maintainer\n","program":{"html_id":"lucky_template/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"lucky_template","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"lucky_template/LuckyTemplate","path":"LuckyTemplate.html","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L5"},{"filename":"src/lucky_template/error.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/error.cr#L1"},{"filename":"src/lucky_template/file.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L1"},{"filename":"src/lucky_template/file_system.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L1"},{"filename":"src/lucky_template/folder.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L1"},{"filename":"src/lucky_template/version.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/version.cr#L1"},{"filename":"src/spec.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/spec.cr#L1"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VERSION","name":"VERSION","value":"{{ (`shards version /home/runner/work/lucky_template/lucky_template/src/lucky_template`).chomp.stringify }}"}],"extended_modules":[{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}],"doc":"Public interface","summary":"

Public interface

","instance_methods":[{"html_id":"create_folder(&:Folder->):Folder-instance-method","name":"create_folder","doc":"Creates a `Folder` and yields it, before returning the **unlocked** `Folder`\n\nNOTE: `Folder` is **locked** when being yielded. See `Folder#locked?`.\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.locked? # => true\n dir.add_file(\".keep\")\nend\nfolder.locked? # => false\n```","summary":"

Creates a Folder and yields it, before returning the unlocked Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":27,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L27"},"def":{"name":"create_folder","yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"Folder.new.tap do |folder|\n folder.lock do\n yield folder\n end\nend"}},{"html_id":"create_folder:Folder-instance-method","name":"create_folder","doc":"Creates an empty `Folder`\n\nExample:\n```\nfolder = LuckyTemplate.create_folder\nfolder.locked? # => false\n```","summary":"

Creates an empty Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":42,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L42"},"def":{"name":"create_folder","return_type":"Folder","visibility":"Public","body":"create_folder do\nend"}},{"html_id":"snapshot(folder:Folder):Snapshot-instance-method","name":"snapshot","doc":"Returns a new `Snapshot` of all files and folders within this _folder_\n\nRaises `Error` if _folder_ is **locked**\n\nNOTE: **Does not** include file instances in results, only paths\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.add_file(\".keep\")\n dir.add_file(\"README.md\")\n dir.add_folder(\"src\") do |src|\n src.add_file(\"hello.cr\")\n end\nend\nputs LuckyTemplate.snapshot(folder)\n```\n\nOutput:\n```\n{\n \".keep\" => LuckyTemplate::FileSystem::File,\n \"README.md\" => LuckyTemplate::FileSystem::File,\n \"src\" => LuckyTemplate::FileSystem::Folder,\n \"src/hello.cr\" => LuckyTemplate::FileSystem::File,\n}\n```","summary":"

Returns a new Snapshot of all files and folders within this folder

","abstract":false,"args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(folder : Folder) : Snapshot","args_html":"(folder : Folder) : Snapshot","location":{"filename":"src/lucky_template.cr","line_number":179,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L179"},"def":{"name":"snapshot","args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Snapshot","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot get snapshot if folder is locked\"))\nend\nSnapshot.new.tap do |_snapshot|\n snapshot_folder(Path.new, folder, _snapshot)\nend\n"}},{"html_id":"validate!(location:Path,folder:Folder):Bool-instance-method","name":"validate!","doc":"Returns `true` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nRaises `::File::NotFoundError` if either a file or folder does not exist\n\nRaises `Error` if _folder_ is **locked**\n\nExample:\n```\nbegin\n templates_folder = LuckyTemplate.create_folder\n LuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\nrescue err : ::File::NotFoundError\n puts err.message\nend\n```","summary":"

Returns true if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":119,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L119"},"def":{"name":"validate!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot validate while folder is locked\"))\nend\n(snapshot(folder)).each do |filepath, type|\n path = location / filepath\n case type\n in .file?\n ::File.size(path)\n in .folder?\n Dir.open(path) do\n end\n end\nend\ntrue\n"}},{"html_id":"validate?(location:Path,folder:Folder):Bool-instance-method","name":"validate?","doc":"Returns a `Bool` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\n```","summary":"

Returns a Bool if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":146,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L146"},"def":{"name":"validate?","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"begin\n validate!(location, folder)\nrescue\n false\nend"}},{"html_id":"write!(location:Path,folder:Folder):Nil-instance-method","name":"write!","doc":"Writes the folder to disk at the given _location_\n\nRaises `Error` if _folder_ is **locked**\n\nRaises `::File::AlreadyExistsError` if _location_ is not an existing folder\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.write!(Path[\"./templates\"], templates_folder)\n```","summary":"

Writes the folder to disk at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Nil","args_html":"(location : Path, folder : Folder) : Nil","location":{"filename":"src/lucky_template.cr","line_number":57,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L57"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Nil","visibility":"Public","body":"Dir.mkdir_p(location)\nif folder.locked?\n raise(Error.new(\"Cannot write to disk if folder is locked\"))\nend\nwrite_folder!(location, folder)\n"}},{"html_id":"write!(location:Path,&:Folder->):Folder-instance-method","name":"write!","doc":"Shorthand for `.create_folder` and `.write!`\n\nExample:\n```\nfolder = LuckyTemplate.write!(Path[\"./templates\"]) do |templates_folder|\n templates_folder.add_file(\".keep\")\nend\n```","summary":"

Shorthand for .create_folder and .write!

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path, & : Folder -> ) : Folder","args_html":"(location : Path, & : Folder -> ) : Folder","location":{"filename":"src/lucky_template.cr","line_number":92,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L92"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"create_folder do |folder|\n yield folder\nend.tap do |folder|\n write!(location, folder)\nend"}}],"types":[{"html_id":"lucky_template/LuckyTemplate/Error","path":"LuckyTemplate/Error.html","kind":"class","full_name":"LuckyTemplate::Error","name":"Error","abstract":false,"superclass":{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/error.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/error.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A generic error class used within `LuckyTemplate`.","summary":"

A generic error class used within LuckyTemplate.

"},{"html_id":"lucky_template/LuckyTemplate/Fileable","path":"LuckyTemplate/Fileable.html","kind":"module","full_name":"LuckyTemplate::Fileable","name":"Fileable","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":48,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L48"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"An interface for a file\n\nSimple example using IO:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n```\n\nExample using ECR templates:\n```\nrequire \"ecr\"\n\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"hello.ecr\"\nend\n```\n\nExample using Process to run `envsubst`:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => \"World\",\n }\n )\n end\nend\n```","summary":"

An interface for a file

","instance_methods":[{"html_id":"to_file(io:IO):Nil-instance-method","name":"to_file","doc":"Appends contents to `IO` for a file","summary":"

Appends contents to IO for a file

","abstract":true,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO) : Nil","args_html":"(io : IO) : Nil","location":{"filename":"src/lucky_template/file.cr","line_number":50,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L50"},"def":{"name":"to_file","args":[{"name":"io","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":""}}]},{"html_id":"lucky_template/LuckyTemplate/FileIO","path":"LuckyTemplate/FileIO.html","kind":"alias","full_name":"LuckyTemplate::FileIO","name":"FileIO","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":53,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L53"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Proc(IO, Nil)","aliased_html":"IO -> Nil","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}},{"html_id":"lucky_template/LuckyTemplate/FileSystem","path":"LuckyTemplate/FileSystem.html","kind":"enum","full_name":"LuckyTemplate::FileSystem","name":"FileSystem","abstract":false,"ancestors":[{"html_id":"lucky_template/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"lucky_template/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"lucky_template/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/file_system.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"File","name":"File","value":"0"},{"id":"Folder","name":"Folder","value":"1"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `FileSystem` represents the files in the filesystem.","summary":"

A FileSystem represents the files in the filesystem.

","instance_methods":[{"html_id":"file?-instance-method","name":"file?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":4,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L4"},"def":{"name":"file?","visibility":"Public","body":"self == File"}},{"html_id":"folder?-instance-method","name":"folder?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L5"},"def":{"name":"folder?","visibility":"Public","body":"self == Folder"}}]},{"html_id":"lucky_template/LuckyTemplate/Folder","path":"LuckyTemplate/Folder.html","kind":"class","full_name":"LuckyTemplate::Folder","name":"Folder","abstract":false,"superclass":{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/folder.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `Folder` represents a filesystem directory, but in a virtual form.","summary":"

A Folder represents a filesystem directory, but in a virtual form.

","instance_methods":[{"html_id":"add_file(name:String,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(\"hello.txt\", \"hello world\")\n\nadd_file(\"hello.txt\", <<-TEXT)\nhello world\nTEXT\n\nadd_file(\"hello.txt\", \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, content : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":32,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L32"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], content, perms)"}},{"html_id":"add_file(path:Path,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(Path[\"./hello.txt\"], \"hello world\")\n\nadd_file(Path[\"./hello.txt\"], <<-TEXT)\nhello world\nTEXT\n\nadd_file(Path[\"./hello.txt\"], \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":52,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L52"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(content, perms))"}},{"html_id":"add_file(name:String,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(\"hello.txt\", Hello.new)\n\nadd_file(\"hello.txt\", Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":76,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L76"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], klass, perms)"}},{"html_id":"add_file(path:Path,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(Path[\"./hello.txt\"], Hello.new)\n\nadd_file(Path[\"./hello.txt\"], Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":100,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L100"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(klass, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\") do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(\"hello.txt\", 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(\"hello.txt\", &proc)\n\nadd_file(\"hello.txt\", 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":125,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L125"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms, &block)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(Path[\"./hello.txt\"]) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(Path[\"./hello.txt\"], 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(Path[\"./hello.txt\"], &proc)\n\nadd_file(Path[\"./hello.txt\"], 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":150,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L150"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(path, File.new(block, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\")\n\nadd_file(\"hello.txt\", 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":166,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L166"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms: perms)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample:\n```\nadd_file(Path[\"./hello.txt\"])\n\nadd_file(Path[\"./hello.txt\"], 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":182,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L182"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(nil, perms))"}},{"html_id":"add_folder(names:Enumerable(String),&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String), & : Folder -> ) : self","args_html":"(names : Enumerable(String), & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":228,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L228"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"begin\n names = (normalize_path(Path[names])).parts\nrescue Error\n raise(Error.new(\"Cannot add folders with invalid folder names\"))\nend\nprev : Folder | ::Nil = nil\nnames.each_with_index do |name, index|\n _folder : Folder = prev || self\n if found_file = _folder.files[name]?\n case found_file\n in Folder\n current_folder = found_file\n in File\n current_folder = Folder.new\n end\n else\n current_folder = Folder.new\n end\n if index == (names.size - 1)\n current_folder.lock do\n yield current_folder\n end\n end\n _folder.insert_folder(name, current_folder)\n prev = current_folder\nend\nself\n"}},{"html_id":"add_folder(path:Path,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path, & : Folder -> ) : self","args_html":"(path : Path, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":284,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L284"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(*names:String,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\") do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String, & : Folder -> ) : self","args_html":"(*names : String, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":308,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L308"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(names) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(names:Enumerable(String)):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\", \"d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String)) : self","args_html":"(names : Enumerable(String)) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":330,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L330"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"return_type":"self","visibility":"Public","body":"add_folder(names) do\nend"}},{"html_id":"add_folder(path:Path):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c/d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path) : self","args_html":"(path : Path) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":350,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L350"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do\nend"}},{"html_id":"add_folder(*names:String):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\", \"d\")\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String) : self","args_html":"(*names : String) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":370,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L370"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"return_type":"self","visibility":"Public","body":"add_folder(names)"}},{"html_id":"empty?:Bool-instance-method","name":"empty?","doc":"Checks if folder has no files or folders","summary":"

Checks if folder has no files or folders

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":405,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L405"},"def":{"name":"empty?","return_type":"Bool","visibility":"Public","body":"@files.empty?"}},{"html_id":"insert_folder(name:String,folder:Folder):self-instance-method","name":"insert_folder","doc":"Insert an existing folder\n\nRaises `Error` if one of the following are true:\n - existing folder is equal to itself\n - existing folder is locked\n\nExample:\n```\nanother_folder = LuckyTemplate::Folder.new\nLuckyTemplate.create_folder do |folder|\n folder.insert_folder(another_folder)\nend\n```","summary":"

Insert an existing folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(name : String, folder : Folder) : self","args_html":"(name : String, folder : Folder) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":387,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L387"},"def":{"name":"insert_folder","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"self","visibility":"Public","body":"if folder == self\n raise(Error.new(\"Cannot add folder equal to itself\"))\nelse\n if folder.locked?\n raise(Error.new(\"Cannot add locked folder\"))\n end\nend\n@files[name] = folder\nself\n"}},{"html_id":"locked?:Bool-instance-method","name":"locked?","doc":"Checks if folder is _locked_\n\nUsually means it's being yielded already.","summary":"

Checks if folder is locked

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":400,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L400"},"def":{"name":"locked?","return_type":"Bool","visibility":"Public","body":"@locked"}}]},{"html_id":"lucky_template/LuckyTemplate/Snapshot","path":"LuckyTemplate/Snapshot.html","kind":"alias","full_name":"LuckyTemplate::Snapshot","name":"Snapshot","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":13,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L13"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Hash(String, LuckyTemplate::FileSystem)","aliased_html":"Hash(String, LuckyTemplate::FileSystem)","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `LuckyTemplate::Snapshot` represents files and folders included within a `LuckyTemplate::Folder` at a moment in time\n\n**Key:** String path in **POSIX** form\n\n**Value:** Type of `LuckyTemplate::FileSystem`","summary":"

A LuckyTemplate::Snapshot represents files and folders included within a LuckyTemplate::Folder at a moment in time

"},{"html_id":"lucky_template/LuckyTemplate/Spec","path":"LuckyTemplate/Spec.html","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec","abstract":false,"locations":[{"filename":"src/spec.cr","line_number":2,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/spec.cr#L2"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"lucky_template/LuckyTemplate/Spec","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"instance_methods":[{"html_id":"be_valid_at(location:Path)-instance-method","name":"be_valid_at","doc":"Validates all files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem","summary":"

Validates all files and folders exist within the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path)","args_html":"(location : Path)","location":{"filename":"src/spec.cr","line_number":8,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/spec.cr#L8"},"def":{"name":"be_valid_at","args":[{"name":"location","external_name":"location","restriction":"Path"}],"visibility":"Public","body":"BeValidAtExpectation.new(location)"}}]}]}]}} \ No newline at end of file diff --git a/search-index.js b/search-index.js index caba4fb..132f435 100644 --- a/search-index.js +++ b/search-index.js @@ -1 +1 @@ -crystal_doc_search_index_callback({"repository_name":"lucky_template","body":"# LuckyTemplate\n\n[![CI](https://github.com/luckyframework/lucky_template/actions/workflows/ci.yml/badge.svg)](https://github.com/mdwagner/lucky_template/actions/workflows/ci.yml)\n\n[LuckyTemplate](https://github.com/luckyframework/lucky_template) is a simple, yet versatile, library for creating file and folder structures as code templates. It has a lot in common with [Teeplate](https://github.com/mosop/teeplate), but it offers more capabilities and more ways to generate content.\n\n## Features\n\n* Allows you to create a virtual file/folder structure, which can be written to disk anywhere.\n* Supports using folders like building blocks, allowing you to reuse folders within other folders.\n* File content can be static or dynamic\n* Includes a Spec helper to validate that the files/folders within a location exist after writing to disk.\n* Provides a snapshot of a folder structure for custom validation or for any other purpose like generating log output.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n ```yaml\n dependencies:\n lucky_template:\n github: luckyframework/lucky_template\n version: ~> 0.1.0\n ```\n\n2. Run `shards install`\n\n## Quick Start\n\nHere's a basic example of how to use LuckyTemplate:\n\n```crystal\nrequire \"lucky_template\"\n\nLuckyTemplate.write!(Path[\".\"]) do |folder|\n folder.add_file(\".keep\")\nend\n```\n\nThis will create a folder at the current directory with an empty `.keep` file. See the sections below for more complex examples.\n\n## Examples\n\n### Simple Template\n\nIn this example, we create a simple README file using an ECR template, a welcome file, and a license file. We also create a new file and folder dynamically in a subfolder.\n\n```crystal\nrequire \"lucky_template\"\n\nclass Readme\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"README.md.ecr\"\nend\n\nname = \"John\"\nfolder = LuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"README.md\", Readme.new(name))\n\n dir.add_file(\"Welcome.md\") do |io|\n io << \"# Welcome \" << name << \"!\\n\"\n end\n\n dir.add_file(\"LICENSE\", <<-LICENSE)\n The MIT License (MIT)\n ...\n LICENSE\n\n dir.add_folder(\"src\") do |src|\n src.add_file(\".keep\")\n\n src.add_folder(name.downcase) do |name_dir|\n name_dir.add_file(\"#{name.downcase}.cr\", <<-CR)\n class #{name}\n end\n\n pp! #{name}.new\n CR\n end\n end\nend\n```\n\n### Creating Multiple Folders\n\nYou can also create multiple folders at once or nest them within other folders:\n\n```crystal\nfolder1 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_one.txt\")\nend\nfolder2 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_two.txt\")\nend\nfolder3 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_three.txt\")\n dir.insert_folder(\"folder1\", folder1)\n dir.insert_folder(\"folder2\", folder2)\nend\nLuckyTemplate.write!(Path[\".\"], folder3)\n```\n\n### Snapshot Folders\n\nAnother great feature is that you can take snapshots of folder structures:\n\n```crystal\nsnapshot = LuckyTemplate.snapshot(folder3)\n\nsnapshot.each do |path, type|\n case type\n in .file?\n puts \"File: #{path}\"\n in .folder?\n puts \"Folder: #{path}\"\n end\nend\n```\n\n### Using Non-Crystal Templates\n\nIf you prefer to use another template engine besides Crystal's, you can do so by creating a running process, as shown in the following example with gettext `envsubst`:\n\n```crystal\nclass ExternalTemplate\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => @name,\n }\n )\n end\nend\n\nLuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"external_file\", ExternalTemplate.new(\"John\"))\nend\n```\n\n## FAQ\n\n- Why create this if Teeplate already exists? Initially, I tried to add Windows support to Teeplate, but ran into some issues, that prompted me to just ask the question: Is this effort worth it? [This discussion](https://github.com/luckyframework/lucky/discussions/1812) gave me the push I needed to create a POC (proof-of-concept), which this library is the result of.\n- Does it support Windows? Yes, it runs the spec suite on Linux & Windows.\n- Why do folder snapshots not contain the file content? Because I haven't found a good enough use-case to support this. Snapshots are supposed to be an escape hatch, where you can get the file/folder structure, but decide what you would like to do with it. Having it include file content doesn't really make sense when LuckyTemplate already writes it to disk for you. But, if you have a good use-case that I haven't thought of, open an issue!\n- Can I use it with `crinja`, `kilt`, `slang`, ...? Yes, or at least, that's the goal! If you find it doesn't work with something, open an issue.\n\n## Contributing\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Michael Wagner](https://github.com/mdwagner) - creator and maintainer\n","program":{"html_id":"lucky_template/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"lucky_template","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"lucky_template/LuckyTemplate","path":"LuckyTemplate.html","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L5"},{"filename":"src/lucky_template/error.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/error.cr#L1"},{"filename":"src/lucky_template/file.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L1"},{"filename":"src/lucky_template/file_system.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L1"},{"filename":"src/lucky_template/folder.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L1"},{"filename":"src/lucky_template/version.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/version.cr#L1"},{"filename":"src/spec.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/spec.cr#L1"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VERSION","name":"VERSION","value":"{{ (`shards version /home/runner/work/lucky_template/lucky_template/src/lucky_template`).chomp.stringify }}"}],"extended_modules":[{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}],"doc":"Public interface","summary":"

Public interface

","instance_methods":[{"html_id":"create_folder(&:Folder->):Folder-instance-method","name":"create_folder","doc":"Creates a `Folder` and yields it, before returning the **unlocked** `Folder`\n\nNOTE: `Folder` is **locked** when being yielded. See `Folder#locked?`.\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.locked? # => true\n dir.add_file(\".keep\")\nend\nfolder.locked? # => false\n```","summary":"

Creates a Folder and yields it, before returning the unlocked Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":27,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L27"},"def":{"name":"create_folder","yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"Folder.new.tap do |folder|\n folder.lock do\n yield folder\n end\nend"}},{"html_id":"create_folder:Folder-instance-method","name":"create_folder","doc":"Creates an empty `Folder`\n\nExample:\n```\nfolder = LuckyTemplate.create_folder\nfolder.locked? # => false\n```","summary":"

Creates an empty Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":42,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L42"},"def":{"name":"create_folder","return_type":"Folder","visibility":"Public","body":"create_folder do\nend"}},{"html_id":"snapshot(folder:Folder):Snapshot-instance-method","name":"snapshot","doc":"Returns a new `Snapshot` of all files and folders within this _folder_\n\nRaises `Error` if _folder_ is **locked**\n\nNOTE: **Does not** include file instances in results, only paths\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.add_file(\".keep\")\n dir.add_file(\"README.md\")\n dir.add_folder(\"src\") do |src|\n src.add_file(\"hello.cr\")\n end\nend\nputs LuckyTemplate.snapshot(folder)\n```\n\nOutput:\n```\n{\n \".keep\" => LuckyTemplate::FileSystem::File,\n \"README.md\" => LuckyTemplate::FileSystem::File,\n \"src\" => LuckyTemplate::FileSystem::Folder,\n \"src/hello.cr\" => LuckyTemplate::FileSystem::File,\n}\n```","summary":"

Returns a new Snapshot of all files and folders within this folder

","abstract":false,"args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(folder : Folder) : Snapshot","args_html":"(folder : Folder) : Snapshot","location":{"filename":"src/lucky_template.cr","line_number":179,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L179"},"def":{"name":"snapshot","args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Snapshot","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot get snapshot if folder is locked\"))\nend\nSnapshot.new.tap do |_snapshot|\n snapshot_folder(Path.new, folder, _snapshot)\nend\n"}},{"html_id":"validate!(location:Path,folder:Folder):Bool-instance-method","name":"validate!","doc":"Returns `true` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nRaises `::File::NotFoundError` if either a file or folder does not exist\n\nRaises `Error` if _folder_ is **locked**\n\nExample:\n```\nbegin\n templates_folder = LuckyTemplate.create_folder\n LuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\nrescue err : ::File::NotFoundError\n puts err.message\nend\n```","summary":"

Returns true if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":119,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L119"},"def":{"name":"validate!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot validate while folder is locked\"))\nend\n(snapshot(folder)).each do |filepath, type|\n path = location / filepath\n case type\n in .file?\n ::File.size(path)\n in .folder?\n Dir.open(path) do\n end\n end\nend\ntrue\n"}},{"html_id":"validate?(location:Path,folder:Folder):Bool-instance-method","name":"validate?","doc":"Returns a `Bool` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\n```","summary":"

Returns a Bool if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":146,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L146"},"def":{"name":"validate?","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"begin\n validate!(location, folder)\nrescue\n false\nend"}},{"html_id":"write!(location:Path,folder:Folder):Nil-instance-method","name":"write!","doc":"Writes the folder to disk at the given _location_\n\nRaises `Error` if _folder_ is **locked**\n\nRaises `::File::AlreadyExistsError` if _location_ is not an existing folder\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.write!(Path[\"./templates\"], templates_folder)\n```","summary":"

Writes the folder to disk at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Nil","args_html":"(location : Path, folder : Folder) : Nil","location":{"filename":"src/lucky_template.cr","line_number":57,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L57"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Nil","visibility":"Public","body":"Dir.mkdir_p(location)\nif folder.locked?\n raise(Error.new(\"Cannot write to disk if folder is locked\"))\nend\nwrite_folder!(location, folder)\n"}},{"html_id":"write!(location:Path,&:Folder->):Folder-instance-method","name":"write!","doc":"Shorthand for `.create_folder` and `.write!`\n\nExample:\n```\nfolder = LuckyTemplate.write!(Path[\"./templates\"]) do |templates_folder|\n templates_folder.add_file(\".keep\")\nend\n```","summary":"

Shorthand for .create_folder and .write!

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path, & : Folder -> ) : Folder","args_html":"(location : Path, & : Folder -> ) : Folder","location":{"filename":"src/lucky_template.cr","line_number":92,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L92"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"create_folder do |folder|\n yield folder\nend.tap do |folder|\n write!(location, folder)\nend"}}],"types":[{"html_id":"lucky_template/LuckyTemplate/Error","path":"LuckyTemplate/Error.html","kind":"class","full_name":"LuckyTemplate::Error","name":"Error","abstract":false,"superclass":{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/error.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/error.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A generic error class used within `LuckyTemplate`.","summary":"

A generic error class used within LuckyTemplate.

"},{"html_id":"lucky_template/LuckyTemplate/Fileable","path":"LuckyTemplate/Fileable.html","kind":"module","full_name":"LuckyTemplate::Fileable","name":"Fileable","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":48,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L48"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"An interface for a file\n\nSimple example using IO:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n```\n\nExample using ECR templates:\n```\nrequire \"ecr\"\n\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"hello.ecr\"\nend\n```\n\nExample using Process to run `envsubst`:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => \"World\",\n }\n )\n end\nend\n```","summary":"

An interface for a file

","instance_methods":[{"html_id":"to_file(io:IO):Nil-instance-method","name":"to_file","doc":"Appends contents to `IO` for a file","summary":"

Appends contents to IO for a file

","abstract":true,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO) : Nil","args_html":"(io : IO) : Nil","location":{"filename":"src/lucky_template/file.cr","line_number":50,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L50"},"def":{"name":"to_file","args":[{"name":"io","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":""}}]},{"html_id":"lucky_template/LuckyTemplate/FileIO","path":"LuckyTemplate/FileIO.html","kind":"alias","full_name":"LuckyTemplate::FileIO","name":"FileIO","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":53,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file.cr#L53"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Proc(IO, Nil)","aliased_html":"IO -> Nil","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}},{"html_id":"lucky_template/LuckyTemplate/FileSystem","path":"LuckyTemplate/FileSystem.html","kind":"enum","full_name":"LuckyTemplate::FileSystem","name":"FileSystem","abstract":false,"ancestors":[{"html_id":"lucky_template/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"lucky_template/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"lucky_template/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/file_system.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"File","name":"File","value":"0"},{"id":"Folder","name":"Folder","value":"1"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `FileSystem` represents the files in the filesystem.","summary":"

A FileSystem represents the files in the filesystem.

","instance_methods":[{"html_id":"file?-instance-method","name":"file?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":4,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L4"},"def":{"name":"file?","visibility":"Public","body":"self == File"}},{"html_id":"folder?-instance-method","name":"folder?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/file_system.cr#L5"},"def":{"name":"folder?","visibility":"Public","body":"self == Folder"}}]},{"html_id":"lucky_template/LuckyTemplate/Folder","path":"LuckyTemplate/Folder.html","kind":"class","full_name":"LuckyTemplate::Folder","name":"Folder","abstract":false,"superclass":{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/folder.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `Folder` represents a filesystem directory, but in a virtual form.","summary":"

A Folder represents a filesystem directory, but in a virtual form.

","instance_methods":[{"html_id":"add_file(name:String,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(\"hello.txt\", \"hello world\")\n\nadd_file(\"hello.txt\", <<-TEXT)\nhello world\nTEXT\n\nadd_file(\"hello.txt\", \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, content : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":32,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L32"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], content, perms)"}},{"html_id":"add_file(path:Path,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(Path[\"./hello.txt\"], \"hello world\")\n\nadd_file(Path[\"./hello.txt\"], <<-TEXT)\nhello world\nTEXT\n\nadd_file(Path[\"./hello.txt\"], \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":52,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L52"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(content, perms))"}},{"html_id":"add_file(name:String,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(\"hello.txt\", Hello.new)\n\nadd_file(\"hello.txt\", Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":76,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L76"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], klass, perms)"}},{"html_id":"add_file(path:Path,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(Path[\"./hello.txt\"], Hello.new)\n\nadd_file(Path[\"./hello.txt\"], Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":100,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L100"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(klass, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\") do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(\"hello.txt\", 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(\"hello.txt\", &proc)\n\nadd_file(\"hello.txt\", 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":125,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L125"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms, &block)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(Path[\"./hello.txt\"]) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(Path[\"./hello.txt\"], 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(Path[\"./hello.txt\"], &proc)\n\nadd_file(Path[\"./hello.txt\"], 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":150,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L150"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(path, File.new(block, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\")\n\nadd_file(\"hello.txt\", 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":166,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L166"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms: perms)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample:\n```\nadd_file(Path[\"./hello.txt\"])\n\nadd_file(Path[\"./hello.txt\"], 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":182,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L182"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(nil, perms))"}},{"html_id":"add_folder(names:Enumerable(String),&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String), & : Folder -> ) : self","args_html":"(names : Enumerable(String), & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":228,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L228"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"begin\n names = (normalize_path(Path[names])).parts\nrescue Error\n raise(Error.new(\"Cannot add folders with invalid folder names\"))\nend\nprev : Folder | ::Nil = nil\nnames.each_with_index do |name, index|\n _folder : Folder = prev || self\n if found_file = _folder.files[name]?\n case found_file\n in Folder\n current_folder = found_file\n in File\n current_folder = Folder.new\n end\n else\n current_folder = Folder.new\n end\n if index == (names.size - 1)\n current_folder.lock do\n yield current_folder\n end\n end\n _folder.insert_folder(name, current_folder)\n prev = current_folder\nend\nself\n"}},{"html_id":"add_folder(path:Path,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path, & : Folder -> ) : self","args_html":"(path : Path, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":284,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L284"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(*names:String,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\") do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String, & : Folder -> ) : self","args_html":"(*names : String, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":308,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L308"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(names) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(names:Enumerable(String)):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\", \"d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String)) : self","args_html":"(names : Enumerable(String)) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":330,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L330"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"return_type":"self","visibility":"Public","body":"add_folder(names) do\nend"}},{"html_id":"add_folder(path:Path):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c/d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path) : self","args_html":"(path : Path) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":350,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L350"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do\nend"}},{"html_id":"add_folder(*names:String):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\", \"d\")\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String) : self","args_html":"(*names : String) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":370,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L370"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"return_type":"self","visibility":"Public","body":"add_folder(names)"}},{"html_id":"empty?:Bool-instance-method","name":"empty?","doc":"Checks if folder has no files or folders","summary":"

Checks if folder has no files or folders

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":405,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L405"},"def":{"name":"empty?","return_type":"Bool","visibility":"Public","body":"@files.empty?"}},{"html_id":"insert_folder(name:String,folder:Folder):self-instance-method","name":"insert_folder","doc":"Insert an existing folder\n\nRaises `Error` if one of the following are true:\n - existing folder is equal to itself\n - existing folder is locked\n\nExample:\n```\nanother_folder = LuckyTemplate::Folder.new\nLuckyTemplate.create_folder do |folder|\n folder.insert_folder(another_folder)\nend\n```","summary":"

Insert an existing folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(name : String, folder : Folder) : self","args_html":"(name : String, folder : Folder) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":387,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L387"},"def":{"name":"insert_folder","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"self","visibility":"Public","body":"if folder == self\n raise(Error.new(\"Cannot add folder equal to itself\"))\nelse\n if folder.locked?\n raise(Error.new(\"Cannot add locked folder\"))\n end\nend\n@files[name] = folder\nself\n"}},{"html_id":"locked?:Bool-instance-method","name":"locked?","doc":"Checks if folder is _locked_\n\nUsually means it's being yielded already.","summary":"

Checks if folder is locked

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":400,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template/folder.cr#L400"},"def":{"name":"locked?","return_type":"Bool","visibility":"Public","body":"@locked"}}]},{"html_id":"lucky_template/LuckyTemplate/Snapshot","path":"LuckyTemplate/Snapshot.html","kind":"alias","full_name":"LuckyTemplate::Snapshot","name":"Snapshot","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":13,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/lucky_template.cr#L13"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Hash(String, LuckyTemplate::FileSystem)","aliased_html":"Hash(String, LuckyTemplate::FileSystem)","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `LuckyTemplate::Snapshot` represents files and folders included within a `LuckyTemplate::Folder` at a moment in time\n\n**Key:** String path in **POSIX** form\n\n**Value:** Type of `LuckyTemplate::FileSystem`","summary":"

A LuckyTemplate::Snapshot represents files and folders included within a LuckyTemplate::Folder at a moment in time

"},{"html_id":"lucky_template/LuckyTemplate/Spec","path":"LuckyTemplate/Spec.html","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec","abstract":false,"locations":[{"filename":"src/spec.cr","line_number":2,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/spec.cr#L2"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"lucky_template/LuckyTemplate/Spec","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"instance_methods":[{"html_id":"be_valid_at(location:Path)-instance-method","name":"be_valid_at","doc":"Validates all files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem","summary":"

Validates all files and folders exist within the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path)","args_html":"(location : Path)","location":{"filename":"src/spec.cr","line_number":8,"url":"https://github.com/luckyframework/lucky_template/blob/35db457ab4c15e414666a709be318f6e3e9d701d/src/spec.cr#L8"},"def":{"name":"be_valid_at","args":[{"name":"location","external_name":"location","restriction":"Path"}],"visibility":"Public","body":"BeValidAtExpectation.new(location)"}}]}]}]}}) \ No newline at end of file +crystal_doc_search_index_callback({"repository_name":"lucky_template","body":"# LuckyTemplate\n\n[![CI](https://github.com/luckyframework/lucky_template/actions/workflows/ci.yml/badge.svg)](https://github.com/mdwagner/lucky_template/actions/workflows/ci.yml)\n\n[LuckyTemplate](https://github.com/luckyframework/lucky_template) is a simple, yet versatile, library for creating file and folder structures as code templates. It has a lot in common with [Teeplate](https://github.com/mosop/teeplate), but it offers more capabilities and more ways to generate content.\n\n## Features\n\n* Allows you to create a virtual file/folder structure, which can be written to disk anywhere.\n* Supports using folders like building blocks, allowing you to reuse folders within other folders.\n* File content can be static or dynamic\n* Includes a Spec helper to validate that the files/folders within a location exist after writing to disk.\n* Provides a snapshot of a folder structure for custom validation or for any other purpose like generating log output.\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n ```yaml\n dependencies:\n lucky_template:\n github: luckyframework/lucky_template\n version: ~> 0.1.0\n ```\n\n2. Run `shards install`\n\n## Quick Start\n\nHere's a basic example of how to use LuckyTemplate:\n\n```crystal\nrequire \"lucky_template\"\n\nLuckyTemplate.write!(Path[\".\"]) do |folder|\n folder.add_file(\".keep\")\nend\n```\n\nThis will create a folder at the current directory with an empty `.keep` file. See the sections below for more complex examples.\n\n## Examples\n\n### Simple Template\n\nIn this example, we create a simple README file using an ECR template, a welcome file, and a license file. We also create a new file and folder dynamically in a subfolder.\n\n```crystal\nrequire \"lucky_template\"\n\nclass Readme\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"README.md.ecr\"\nend\n\nname = \"John\"\nfolder = LuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"README.md\", Readme.new(name))\n\n dir.add_file(\"Welcome.md\") do |io|\n io << \"# Welcome \" << name << \"!\\n\"\n end\n\n dir.add_file(\"LICENSE\", <<-LICENSE)\n The MIT License (MIT)\n ...\n LICENSE\n\n dir.add_folder(\"src\") do |src|\n src.add_file(\".keep\")\n\n src.add_folder(name.downcase) do |name_dir|\n name_dir.add_file(\"#{name.downcase}.cr\", <<-CR)\n class #{name}\n end\n\n pp! #{name}.new\n CR\n end\n end\nend\n```\n\n### Creating Multiple Folders\n\nYou can also create multiple folders at once or nest them within other folders:\n\n```crystal\nfolder1 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_one.txt\")\nend\nfolder2 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_two.txt\")\nend\nfolder3 = LuckyTemplate.create_folder do |dir|\n dir.add_file(\"folder_three.txt\")\n dir.insert_folder(\"folder1\", folder1)\n dir.insert_folder(\"folder2\", folder2)\nend\nLuckyTemplate.write!(Path[\".\"], folder3)\n```\n\n### Snapshot Folders\n\nAnother great feature is that you can take snapshots of folder structures:\n\n```crystal\nsnapshot = LuckyTemplate.snapshot(folder3)\n\nsnapshot.each do |path, type|\n case type\n in .file?\n puts \"File: #{path}\"\n in .folder?\n puts \"Folder: #{path}\"\n end\nend\n```\n\n### Using Non-Crystal Templates\n\nIf you prefer to use another template engine besides Crystal's, you can do so by creating a running process, as shown in the following example with gettext `envsubst`:\n\n```crystal\nclass ExternalTemplate\n include LuckyTemplate::Fileable\n\n def initialize(@name : String)\n end\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => @name,\n }\n )\n end\nend\n\nLuckyTemplate.write!(Path[\".\"]) do |dir|\n dir.add_file(\"external_file\", ExternalTemplate.new(\"John\"))\nend\n```\n\n## FAQ\n\n- Why create this if Teeplate already exists? Initially, I tried to add Windows support to Teeplate, but ran into some issues, that prompted me to just ask the question: Is this effort worth it? [This discussion](https://github.com/luckyframework/lucky/discussions/1812) gave me the push I needed to create a POC (proof-of-concept), which this library is the result of.\n- Does it support Windows? Yes, it runs the spec suite on Linux & Windows.\n- Why do folder snapshots not contain the file content? Because I haven't found a good enough use-case to support this. Snapshots are supposed to be an escape hatch, where you can get the file/folder structure, but decide what you would like to do with it. Having it include file content doesn't really make sense when LuckyTemplate already writes it to disk for you. But, if you have a good use-case that I haven't thought of, open an issue!\n- Can I use it with `crinja`, `kilt`, `slang`, ...? Yes, or at least, that's the goal! If you find it doesn't work with something, open an issue.\n\n## Contributing\n\n1. Fork it ()\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Contributors\n\n- [Michael Wagner](https://github.com/mdwagner) - creator and maintainer\n","program":{"html_id":"lucky_template/toplevel","path":"toplevel.html","kind":"module","full_name":"Top Level Namespace","name":"Top Level Namespace","abstract":false,"locations":[],"repository_name":"lucky_template","program":true,"enum":false,"alias":false,"const":false,"types":[{"html_id":"lucky_template/LuckyTemplate","path":"LuckyTemplate.html","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L5"},{"filename":"src/lucky_template/error.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/error.cr#L1"},{"filename":"src/lucky_template/file.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L1"},{"filename":"src/lucky_template/file_system.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L1"},{"filename":"src/lucky_template/folder.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L1"},{"filename":"src/lucky_template/version.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/version.cr#L1"},{"filename":"src/spec.cr","line_number":1,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/spec.cr#L1"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"constants":[{"id":"VERSION","name":"VERSION","value":"{{ (`shards version /home/runner/work/lucky_template/lucky_template/src/lucky_template`).chomp.stringify }}"}],"extended_modules":[{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}],"doc":"Public interface","summary":"

Public interface

","instance_methods":[{"html_id":"create_folder(&:Folder->):Folder-instance-method","name":"create_folder","doc":"Creates a `Folder` and yields it, before returning the **unlocked** `Folder`\n\nNOTE: `Folder` is **locked** when being yielded. See `Folder#locked?`.\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.locked? # => true\n dir.add_file(\".keep\")\nend\nfolder.locked? # => false\n```","summary":"

Creates a Folder and yields it, before returning the unlocked Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":27,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L27"},"def":{"name":"create_folder","yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"Folder.new.tap do |folder|\n folder.lock do\n yield folder\n end\nend"}},{"html_id":"create_folder:Folder-instance-method","name":"create_folder","doc":"Creates an empty `Folder`\n\nExample:\n```\nfolder = LuckyTemplate.create_folder\nfolder.locked? # => false\n```","summary":"

Creates an empty Folder

","abstract":false,"location":{"filename":"src/lucky_template.cr","line_number":42,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L42"},"def":{"name":"create_folder","return_type":"Folder","visibility":"Public","body":"create_folder do\nend"}},{"html_id":"snapshot(folder:Folder):Snapshot-instance-method","name":"snapshot","doc":"Returns a new `Snapshot` of all files and folders within this _folder_\n\nRaises `Error` if _folder_ is **locked**\n\nNOTE: **Does not** include file instances in results, only paths\n\nExample:\n```\nfolder = LuckyTemplate.create_folder do |dir|\n dir.add_file(\".keep\")\n dir.add_file(\"README.md\")\n dir.add_folder(\"src\") do |src|\n src.add_file(\"hello.cr\")\n end\nend\nputs LuckyTemplate.snapshot(folder)\n```\n\nOutput:\n```\n{\n \".keep\" => LuckyTemplate::FileSystem::File,\n \"README.md\" => LuckyTemplate::FileSystem::File,\n \"src\" => LuckyTemplate::FileSystem::Folder,\n \"src/hello.cr\" => LuckyTemplate::FileSystem::File,\n}\n```","summary":"

Returns a new Snapshot of all files and folders within this folder

","abstract":false,"args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(folder : Folder) : Snapshot","args_html":"(folder : Folder) : Snapshot","location":{"filename":"src/lucky_template.cr","line_number":179,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L179"},"def":{"name":"snapshot","args":[{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Snapshot","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot get snapshot if folder is locked\"))\nend\nSnapshot.new.tap do |_snapshot|\n snapshot_folder(Path.new, folder, _snapshot)\nend\n"}},{"html_id":"validate!(location:Path,folder:Folder):Bool-instance-method","name":"validate!","doc":"Returns `true` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nRaises `::File::NotFoundError` if either a file or folder does not exist\n\nRaises `Error` if _folder_ is **locked**\n\nExample:\n```\nbegin\n templates_folder = LuckyTemplate.create_folder\n LuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\nrescue err : ::File::NotFoundError\n puts err.message\nend\n```","summary":"

Returns true if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":119,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L119"},"def":{"name":"validate!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"if folder.locked?\n raise(Error.new(\"Cannot validate while folder is locked\"))\nend\n(snapshot(folder)).each do |filepath, type|\n path = location / filepath\n case type\n in .file?\n ::File.size(path)\n in .folder?\n Dir.open(path) do\n end\n end\nend\ntrue\n"}},{"html_id":"validate?(location:Path,folder:Folder):Bool-instance-method","name":"validate?","doc":"Returns a `Bool` if the _folder_ is **valid** at the given _location_\n\n**valid** - files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.validate!(Path[\"./templates\"], templates_folder) # => true\n```","summary":"

Returns a Bool if the folder is valid at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Bool","args_html":"(location : Path, folder : Folder) : Bool","location":{"filename":"src/lucky_template.cr","line_number":146,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L146"},"def":{"name":"validate?","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Bool","visibility":"Public","body":"begin\n validate!(location, folder)\nrescue\n false\nend"}},{"html_id":"write!(location:Path,folder:Folder):Nil-instance-method","name":"write!","doc":"Writes the folder to disk at the given _location_\n\nRaises `Error` if _folder_ is **locked**\n\nRaises `::File::AlreadyExistsError` if _location_ is not an existing folder\n\nExample:\n```\ntemplates_folder = LuckyTemplate.create_folder\nLuckyTemplate.write!(Path[\"./templates\"], templates_folder)\n```","summary":"

Writes the folder to disk at the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(location : Path, folder : Folder) : Nil","args_html":"(location : Path, folder : Folder) : Nil","location":{"filename":"src/lucky_template.cr","line_number":57,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L57"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"Nil","visibility":"Public","body":"Dir.mkdir_p(location)\nif folder.locked?\n raise(Error.new(\"Cannot write to disk if folder is locked\"))\nend\nwrite_folder!(location, folder)\n"}},{"html_id":"write!(location:Path,&:Folder->):Folder-instance-method","name":"write!","doc":"Shorthand for `.create_folder` and `.write!`\n\nExample:\n```\nfolder = LuckyTemplate.write!(Path[\"./templates\"]) do |templates_folder|\n templates_folder.add_file(\".keep\")\nend\n```","summary":"

Shorthand for .create_folder and .write!

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path, & : Folder -> ) : Folder","args_html":"(location : Path, & : Folder -> ) : Folder","location":{"filename":"src/lucky_template.cr","line_number":92,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L92"},"def":{"name":"write!","args":[{"name":"location","external_name":"location","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"Folder","visibility":"Public","body":"create_folder do |folder|\n yield folder\nend.tap do |folder|\n write!(location, folder)\nend"}}],"types":[{"html_id":"lucky_template/LuckyTemplate/Error","path":"LuckyTemplate/Error.html","kind":"class","full_name":"LuckyTemplate::Error","name":"Error","abstract":false,"superclass":{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},"ancestors":[{"html_id":"lucky_template/Exception","kind":"class","full_name":"Exception","name":"Exception"},{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/error.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/error.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A generic error class used within `LuckyTemplate`.","summary":"

A generic error class used within LuckyTemplate.

"},{"html_id":"lucky_template/LuckyTemplate/Fileable","path":"LuckyTemplate/Fileable.html","kind":"module","full_name":"LuckyTemplate::Fileable","name":"Fileable","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":48,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L48"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"An interface for a file\n\nSimple example using IO:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n```\n\nExample using ECR templates:\n```\nrequire \"ecr\"\n\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n to_s(io)\n end\n\n ECR.def_to_s \"hello.ecr\"\nend\n```\n\nExample using Process to run `envsubst`:\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n input = IO::Memory.new(\"Hello $NAME!\")\n Process.run(\n command: \"envsubst\",\n input: input,\n output: io,\n env: {\n \"NAME\" => \"World\",\n }\n )\n end\nend\n```","summary":"

An interface for a file

","instance_methods":[{"html_id":"to_file(io:IO):Nil-instance-method","name":"to_file","doc":"Appends contents to `IO` for a file","summary":"

Appends contents to IO for a file

","abstract":true,"args":[{"name":"io","external_name":"io","restriction":"IO"}],"args_string":"(io : IO) : Nil","args_html":"(io : IO) : Nil","location":{"filename":"src/lucky_template/file.cr","line_number":50,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L50"},"def":{"name":"to_file","args":[{"name":"io","external_name":"io","restriction":"IO"}],"return_type":"Nil","visibility":"Public","body":""}}]},{"html_id":"lucky_template/LuckyTemplate/FileIO","path":"LuckyTemplate/FileIO.html","kind":"alias","full_name":"LuckyTemplate::FileIO","name":"FileIO","abstract":false,"locations":[{"filename":"src/lucky_template/file.cr","line_number":53,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file.cr#L53"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Proc(IO, Nil)","aliased_html":"IO -> Nil","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"}},{"html_id":"lucky_template/LuckyTemplate/FileSystem","path":"LuckyTemplate/FileSystem.html","kind":"enum","full_name":"LuckyTemplate::FileSystem","name":"FileSystem","abstract":false,"ancestors":[{"html_id":"lucky_template/Enum","kind":"struct","full_name":"Enum","name":"Enum"},{"html_id":"lucky_template/Comparable","kind":"module","full_name":"Comparable","name":"Comparable"},{"html_id":"lucky_template/Value","kind":"struct","full_name":"Value","name":"Value"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/file_system.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":true,"alias":false,"const":false,"constants":[{"id":"File","name":"File","value":"0"},{"id":"Folder","name":"Folder","value":"1"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `FileSystem` represents the files in the filesystem.","summary":"

A FileSystem represents the files in the filesystem.

","instance_methods":[{"html_id":"file?-instance-method","name":"file?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":4,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L4"},"def":{"name":"file?","visibility":"Public","body":"self == File"}},{"html_id":"folder?-instance-method","name":"folder?","abstract":false,"location":{"filename":"src/lucky_template/file_system.cr","line_number":5,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/file_system.cr#L5"},"def":{"name":"folder?","visibility":"Public","body":"self == Folder"}}]},{"html_id":"lucky_template/LuckyTemplate/Folder","path":"LuckyTemplate/Folder.html","kind":"class","full_name":"LuckyTemplate::Folder","name":"Folder","abstract":false,"superclass":{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},"ancestors":[{"html_id":"lucky_template/Reference","kind":"class","full_name":"Reference","name":"Reference"},{"html_id":"lucky_template/Object","kind":"class","full_name":"Object","name":"Object"}],"locations":[{"filename":"src/lucky_template/folder.cr","line_number":3,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L3"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `Folder` represents a filesystem directory, but in a virtual form.","summary":"

A Folder represents a filesystem directory, but in a virtual form.

","instance_methods":[{"html_id":"add_file(name:String,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(\"hello.txt\", \"hello world\")\n\nadd_file(\"hello.txt\", <<-TEXT)\nhello world\nTEXT\n\nadd_file(\"hello.txt\", \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, content : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":32,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L32"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], content, perms)"}},{"html_id":"add_file(path:Path,content:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _content_\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExamples(s):\n```\nadd_file(Path[\"./hello.txt\"], \"hello world\")\n\nadd_file(Path[\"./hello.txt\"], <<-TEXT)\nhello world\nTEXT\n\nadd_file(Path[\"./hello.txt\"], \"hello world\", 0o644)\n```","summary":"

Adds a new file to the folder with content

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, content : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":52,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L52"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"content","external_name":"content","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(content, perms))"}},{"html_id":"add_file(name:String,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(\"hello.txt\", Hello.new)\n\nadd_file(\"hello.txt\", Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(name : String, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":76,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L76"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], klass, perms)"}},{"html_id":"add_file(path:Path,klass:Fileable,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new file to the folder with _klass_ implementing `Fileable` interface\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nclass Hello\n include LuckyTemplate::Fileable\n\n def to_file(io : IO) : Nil\n io << \"hello\"\n end\nend\n\nadd_file(Path[\"./hello.txt\"], Hello.new)\n\nadd_file(Path[\"./hello.txt\"], Hello.new, 0o644)\n```","summary":"

Adds a new file to the folder with klass implementing Fileable interface

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, klass : Fileable, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":100,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L100"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"klass","external_name":"klass","restriction":"Fileable"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(klass, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\") do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(\"hello.txt\", 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(\"hello.txt\", &proc)\n\nadd_file(\"hello.txt\", 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(name : String, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":125,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L125"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms, &block)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil,&block:FileIO):self-instance-method","name":"add_file","doc":"Adds a new file to the folder yielding an `IO`\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(Path[\"./hello.txt\"]) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nadd_file(Path[\"./hello.txt\"], 0o644) do |io|\n ECR.embed(\"hello.ecr\", io)\nend\n\nproc = LuckyTemplate::FileIO.new { |io| ECR.embed(\"hello.ecr\", io) }\nadd_file(Path[\"./hello.txt\"], &proc)\n\nadd_file(Path[\"./hello.txt\"], 0o644, &proc)\n```","summary":"

Adds a new file to the folder yielding an IO

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","args_html":"(path : Path, perms : Int16 | Nil = nil, &block : FileIO) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":150,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L150"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"yields":0,"block_arity":0,"block_arg":{"name":"block","external_name":"block","restriction":"FileIO"},"return_type":"self","visibility":"Public","body":"add_file(path, File.new(block, perms))"}},{"html_id":"add_file(name:String,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _name_ contains invalid path(s)\n\nExample(s):\n```\nadd_file(\"hello.txt\")\n\nadd_file(\"hello.txt\", 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(name : String, perms : Int16 | Nil = nil) : self","args_html":"(name : String, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":166,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L166"},"def":{"name":"add_file","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(Path[name], perms: perms)"}},{"html_id":"add_file(path:Path,perms:Int16|Nil=nil):self-instance-method","name":"add_file","doc":"Adds a new empty file to the folder\n\nOptionally, provide _perms_ to specify file permissions\n\nRaises `Error` if _path_ contains invalid path(s)\n\nExample:\n```\nadd_file(Path[\"./hello.txt\"])\n\nadd_file(Path[\"./hello.txt\"], 0o644)\n```","summary":"

Adds a new empty file to the folder

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"args_string":"(path : Path, perms : Int16 | Nil = nil) : self","args_html":"(path : Path, perms : Int16 | Nil = nil) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":182,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L182"},"def":{"name":"add_file","args":[{"name":"path","external_name":"path","restriction":"Path"},{"name":"perms","default_value":"nil","external_name":"perms","restriction":"Int16 | ::Nil"}],"return_type":"self","visibility":"Public","body":"add_file(path, File.new(nil, perms))"}},{"html_id":"add_folder(names:Enumerable(String),&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String), & : Folder -> ) : self","args_html":"(names : Enumerable(String), & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":228,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L228"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"begin\n names = (normalize_path(Path[names])).parts\nrescue Error\n raise(Error.new(\"Cannot add folders with invalid folder names\"))\nend\nprev : Folder | ::Nil = nil\nnames.each_with_index do |name, index|\n _folder : Folder = prev || self\n if found_file = _folder.files[name]?\n case found_file\n in Folder\n current_folder = found_file\n in File\n current_folder = Folder.new\n end\n else\n current_folder = Folder.new\n end\n if index == (names.size - 1)\n current_folder.lock do\n yield current_folder\n end\n end\n _folder.insert_folder(name, current_folder)\n prev = current_folder\nend\nself\n"}},{"html_id":"add_folder(path:Path,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c\"]) do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path, & : Folder -> ) : self","args_html":"(path : Path, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":284,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L284"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(*names:String,&:Folder->):self-instance-method","name":"add_folder","doc":"Adds nested folders, yielding the last one\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\") do |c|\n c.add_file(\"hello.txt\")\nend\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/hello.txt\n```","summary":"

Adds nested folders, yielding the last one

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String, & : Folder -> ) : self","args_html":"(*names : String, & : Folder -> ) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":308,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L308"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"yields":1,"block_arity":1,"block_arg":{"name":"","external_name":"","restriction":"(Folder ->)"},"return_type":"self","visibility":"Public","body":"add_folder(names) do |folder|\n yield folder\nend"}},{"html_id":"add_folder(names:Enumerable(String)):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder([\"a\", \"b\", \"c\", \"d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"args_string":"(names : Enumerable(String)) : self","args_html":"(names : Enumerable(String)) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":330,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L330"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"Enumerable(String)"}],"return_type":"self","visibility":"Public","body":"add_folder(names) do\nend"}},{"html_id":"add_folder(path:Path):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _path_ contains invalid folder names\n\nExample:\n```\nadd_folder(Path[\"a/b/c/d\"])\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"path","external_name":"path","restriction":"Path"}],"args_string":"(path : Path) : self","args_html":"(path : Path) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":350,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L350"},"def":{"name":"add_folder","args":[{"name":"path","external_name":"path","restriction":"Path"}],"return_type":"self","visibility":"Public","body":"add_folder(path.parts) do\nend"}},{"html_id":"add_folder(*names:String):self-instance-method","name":"add_folder","doc":"Adds nested empty folders\n\nRaises `Error` if _names_ contains invalid folder names\n\nExample:\n```\nadd_folder(\"a\", \"b\", \"c\", \"d\")\n```\n\nProduces these folder paths:\n```text\na\na/b\na/b/c\na/b/c/d\n```","summary":"

Adds nested empty folders

","abstract":false,"args":[{"name":"names","external_name":"names","restriction":"String"}],"args_string":"(*names : String) : self","args_html":"(*names : String) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":370,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L370"},"def":{"name":"add_folder","args":[{"name":"names","external_name":"names","restriction":"String"}],"splat_index":0,"return_type":"self","visibility":"Public","body":"add_folder(names)"}},{"html_id":"empty?:Bool-instance-method","name":"empty?","doc":"Checks if folder has no files or folders","summary":"

Checks if folder has no files or folders

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":405,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L405"},"def":{"name":"empty?","return_type":"Bool","visibility":"Public","body":"@files.empty?"}},{"html_id":"insert_folder(name:String,folder:Folder):self-instance-method","name":"insert_folder","doc":"Insert an existing folder\n\nRaises `Error` if one of the following are true:\n - existing folder is equal to itself\n - existing folder is locked\n\nExample:\n```\nanother_folder = LuckyTemplate::Folder.new\nLuckyTemplate.create_folder do |folder|\n folder.insert_folder(another_folder)\nend\n```","summary":"

Insert an existing folder

","abstract":false,"args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"args_string":"(name : String, folder : Folder) : self","args_html":"(name : String, folder : Folder) : self","location":{"filename":"src/lucky_template/folder.cr","line_number":387,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L387"},"def":{"name":"insert_folder","args":[{"name":"name","external_name":"name","restriction":"String"},{"name":"folder","external_name":"folder","restriction":"Folder"}],"return_type":"self","visibility":"Public","body":"if folder == self\n raise(Error.new(\"Cannot add folder equal to itself\"))\nelse\n if folder.locked?\n raise(Error.new(\"Cannot add locked folder\"))\n end\nend\n@files[name] = folder\nself\n"}},{"html_id":"locked?:Bool-instance-method","name":"locked?","doc":"Checks if folder is _locked_\n\nUsually means it's being yielded already.","summary":"

Checks if folder is locked

","abstract":false,"location":{"filename":"src/lucky_template/folder.cr","line_number":400,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template/folder.cr#L400"},"def":{"name":"locked?","return_type":"Bool","visibility":"Public","body":"@locked"}}]},{"html_id":"lucky_template/LuckyTemplate/Snapshot","path":"LuckyTemplate/Snapshot.html","kind":"alias","full_name":"LuckyTemplate::Snapshot","name":"Snapshot","abstract":false,"locations":[{"filename":"src/lucky_template.cr","line_number":13,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/lucky_template.cr#L13"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":true,"aliased":"Hash(String, LuckyTemplate::FileSystem)","aliased_html":"Hash(String, LuckyTemplate::FileSystem)","const":false,"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"doc":"A `LuckyTemplate::Snapshot` represents files and folders included within a `LuckyTemplate::Folder` at a moment in time\n\n**Key:** String path in **POSIX** form\n\n**Value:** Type of `LuckyTemplate::FileSystem`","summary":"

A LuckyTemplate::Snapshot represents files and folders included within a LuckyTemplate::Folder at a moment in time

"},{"html_id":"lucky_template/LuckyTemplate/Spec","path":"LuckyTemplate/Spec.html","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec","abstract":false,"locations":[{"filename":"src/spec.cr","line_number":2,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/spec.cr#L2"}],"repository_name":"lucky_template","program":false,"enum":false,"alias":false,"const":false,"extended_modules":[{"html_id":"lucky_template/LuckyTemplate/Spec","kind":"module","full_name":"LuckyTemplate::Spec","name":"Spec"}],"namespace":{"html_id":"lucky_template/LuckyTemplate","kind":"module","full_name":"LuckyTemplate","name":"LuckyTemplate"},"instance_methods":[{"html_id":"be_valid_at(location:Path)-instance-method","name":"be_valid_at","doc":"Validates all files and folders exist within the given _location_\n\nNOTE: **Does not** check _contents_ of files, only the presence of them in the filesystem","summary":"

Validates all files and folders exist within the given location

","abstract":false,"args":[{"name":"location","external_name":"location","restriction":"Path"}],"args_string":"(location : Path)","args_html":"(location : Path)","location":{"filename":"src/spec.cr","line_number":8,"url":"https://github.com/luckyframework/lucky_template/blob/dd924c70881617803287ca8eaebb0dcc773f40c9/src/spec.cr#L8"},"def":{"name":"be_valid_at","args":[{"name":"location","external_name":"location","restriction":"Path"}],"visibility":"Public","body":"BeValidAtExpectation.new(location)"}}]}]}]}}) \ No newline at end of file