{"id":18088210,"url":"https://github.com/yurique/embedded-files","last_synced_at":"2025-10-24T18:32:55.051Z","repository":{"id":40331608,"uuid":"326080156","full_name":"yurique/embedded-files","owner":"yurique","description":"An sbt plugin to generate Scala objects containing the contents of glob-specified files as strings or byte-arrays.","archived":false,"fork":false,"pushed_at":"2024-08-20T01:36:18.000Z","size":117,"stargazers_count":10,"open_issues_count":6,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-13T03:10:00.623Z","etag":null,"topics":["sbt","sbt-plugin","scala","scalajs","source-gen","source-generation"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yurique.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-02T00:28:03.000Z","updated_at":"2024-05-27T04:15:50.000Z","dependencies_parsed_at":"2024-10-31T17:12:16.754Z","dependency_job_id":"ef0b6288-362f-47d4-b478-69c78896199e","html_url":"https://github.com/yurique/embedded-files","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yurique%2Fembedded-files","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yurique%2Fembedded-files/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yurique%2Fembedded-files/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yurique%2Fembedded-files/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yurique","download_url":"https://codeload.github.com/yurique/embedded-files/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248657917,"owners_count":21140846,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sbt","sbt-plugin","scala","scalajs","source-gen","source-generation"],"created_at":"2024-10-31T17:12:11.225Z","updated_at":"2025-10-24T18:32:54.978Z","avatar_url":"https://github.com/yurique.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# embedded-files\n\nAn sbt plugin to generate Scala objects containing the contents of glob-specified files as strings or byte-arrays.\n\nThe accompanying macro allowing to access those objects more easily: [embedded-files-macro](https://github.com/yurique/embedded-files-macro).\n\n## Installation\n\n### `plugins.sbt`\n\n```scala\naddSbtPlugin(\"com.yurique\" % \"sbt-embedded-files\" % \"0.4.0\")\n```\n\n### `build.sbt`\n\n```scala\n libraryDependencies += \"com.yurique\" %%% \"embedded-files-macro\" % \"{embedded-files-macro-version}\"\n```\n\n## Example usage\n\nPut a file into `src/main/resources/docs/test.txt`:\n\n```\nI'm a test text.\n```\n\nAdd `embedFiles` to the `Compile / sourceGenerators`:\n\n```scala\n  project\n    // ...\n    .enablePlugins(EmbeddedFilesPlugin)\n    // ...\n    .settings(\n      (Compile / sourceGenerators) += embedFiles\n    )\n```\n\nIn the code:\n\n```scala\nimport com.yurique.embedded.FileAsString\n\nval testTxtContents = FileAsString(\"/docs/test.txt\") // \"I'm a test text.\"\n```\n\n## Configuration\n\nThe sbt plugin has the following configuration keys:\n\n```scala\n  project\n    // ...\n    .settings(\n      // default is __embedded_files, which is assumed by the macro\n      // the generated objects and classes are put into this package (and sub-packages)\n      embedRootPackage := \"custom_root_package\",\n\n      // a list of directories to look for files to embed in\n      // default is (Compile / unmanagedResourceDirectories)\n      embedDirectories ++= (Compile / unmanagedSourceDirectories).value,\n\n      // a list of globs for text files\n      // default is Seq(\"**/*.txt\")\n      embedTextGlobs := Seq(\"**/*.txt\", \"**/*.md\"),\n\n      // a list of globs for binary files\n      // default is Seq.empty\n      embedBinGlobs := Seq(\"**/*.bin\"),\n\n      // whether or not to generate a EmbeddedFilesIndex object containing references to all embedded files\n      // default is false\n      embedGenerateIndex := true,\n\n      // the intended usage is to use the output of the embedFiles task as generated sources\n      (Compile / sourceGenerators) += embedFiles\n    )\n```\n\n## Generated files\n\n### Interfaces\n\nThe `embedFiles` always generates these two abstract classes:\n\n```scala\npackage ${embedRootPackage.value}\n\nabstract class EmbeddedTextFile {\n  def path: String\n  def content: String\n}\n\n```\n\nand\n\n```scala\npackage ${embedRootPackage.value}\n\nabstract class EmbeddedBinFile {\n  def path: String\n  def content: Array[Byte]\n}\n```\n\n### Text files\n\nFor each file in the `embedDirectories` that matches any of the `embedTextGlobs` a file like the following is generated:\n\n```scala\npackage ${embedRootPackage.value}.${subPackage}\n\nobject ${className} extends __embedded_files.EmbeddedTextFile {\n\n  val path: String = \"\"\"path/to/the/file/filename.txt\"\"\"\n\n  val content: String = \"\"\"the content of the file\"\"\"\n\n}\n```\n\n### Binary files\n\nFor each file in the `embedDirectories` that matches any of the `embedBinGlobs` a file like the following is generated:\n\n```scala\npackage ${embedRootPackage.value}.${subPackage}\n\nobject ${className} extends __embedded_files.EmbeddedBinFile {\n\n  val path: String = \"\"\"path/to/the/file/filename.bin\"\"\"\n\n  val content: Array[Byte] = Array(\n    // example bytes\n    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f\n  )\n\n}\n```\n\n### Package- and class-names\n\nFor each file, its path is taken relative to the one of the `embedDirectories` and converted into the package name and the class name.\n\nFor example, if the file was `/home/user/.../.../project/src/main/resources/some-dir/1 some sub dir/some things \u0026 other things.txt`:\n\n- a relative path is `some-dir/1 some sub dir/some things \u0026 other things.txt` (relative to `Compile / unmanagedSourceDirectories` in this example)\n- the dirname is `some-dir/1 some sub dir`, it is split by `/`, every part is converted to a valid Scala ID (by replacing non alpha-numerics by `_` and prepending `_` is the path starts with a digit)\n- the resulting package name is `some_dir._1_some_sub_dir`\n- the class name is derived from the file name: `some_things_other_things`\n\n## Index file\n\nif `embedGenerateIndex` is set to `true`, the index file is generated like the following:\n\n```scala\npackage ${embedRootPackage.value}\n\nobject EmbeddedFilesIndex {\n  val textFiles: Seq[(String, EmbeddedTextFile)] = Seq(\n    \"test/test-resource.txt\" -\u003e __embedded_files.test.test_resource_txt,\n    \"com/company/test_file_1.txt\" -\u003e __embedded_files.com.company.test_file_1_txt\n  )\n  val binFiles: Seq[(String, EmbeddedBinFile)] = Seq(\n    \"test/test-bin-resource.bin\" -\u003e __embedded_files.test.test_bin_resource_bin,\n    \"com/company/test_bin_file_1.bin\" -\u003e __embedded_files.com.company.test_bin_file_1_bin\n  )\n}\n```\n\n## Transforming text\n\nIt is possible to configure a basic `String =\u003e String` transformation for text files.\n\n\n```scala\nproject\n  // ...\n  .settings(\n    embedDirectories ++= (Compile / unmanagedSourceDirectories).value,\n    embedTextGlobs := Seq(\"**/*.md\"),\n    embedTransform := Seq(\n      TransformConfig(\n        when = _.getFileName.toString.endsWith(\".md\"),\n        transform = _.toUpperCase          \n      )\n    ),\n    (Compile / sourceGenerators) += embedFiles\n  )\n```\n\nFor each text file, the `.transform` function of the first of the `TransformConfig`-s that matches the path (`.when` returns `true`) \nwill be applied to the contents of the file.\n\nIf none of the configuration matches - the file contents will be used as is.\n\nIf more than one configuration matches, only the first one will be used.\n\n## macros\n\nAssuming the `embedFiles` is used as a source generator with the default root package, you can use the macros provided by the `embedded-files-macro` library to get the string/byte-array content of the files like this:\n\n```scala\nimport com.yurique.embedded._\nval s: String = FileAsString(\"/docs/test.txt\")\nval b: Array[Byte] = FileAsByteArray(\"/bins/test.bin\")\n```\n\nIf the path passed to the macros starts with a slash, it is used as is.\n\nIf it doesn't start with a slash, the macro does the following:\n\n`/home/user/.../project/src/main/scala/com/company/MyClass.scala`\n\n```scala\npackage com.company.MyClass\n\nobject MyClass {\n  val s: String = FileAsString(\"dir/data.txt\")\n}\n```\n\nHere, the file name doesn't start with a `/` – `dir/data.txt`.\n\nThe calling site is in the `/home/user/.../project/src/main/scala/com/company/` directory.\n\nThe requested file name is appended to this directory, resulting in `/home/user/.../project/src/main/scala/com/company/dir/data.txt`.\n\nThis file is taken relative to the first `scala` directory in the path, resulting in `/com/company/dir/data.txt`.\n\n## Missing embedded files\n\nThe macros are not currently doing any checks for whether the embedded files exist. If they don't, `scalac` will just fail to compile.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyurique%2Fembedded-files","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyurique%2Fembedded-files","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyurique%2Fembedded-files/lists"}