{"id":23872803,"url":"https://github.com/troublete/lua-chunk-manager","last_synced_at":"2025-10-19T22:53:43.547Z","repository":{"id":45928222,"uuid":"413709545","full_name":"troublete/lua-chunk-manager","owner":"troublete","description":"A dependency manager for Lua, written in (pure) Lua. 📚","archived":false,"fork":false,"pushed_at":"2021-11-28T12:44:40.000Z","size":138,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-03T16:33:28.408Z","etag":null,"topics":["dependency","dependency-manager","lua"],"latest_commit_sha":null,"homepage":"","language":"Lua","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/troublete.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-10-05T07:04:31.000Z","updated_at":"2021-11-24T19:03:17.000Z","dependencies_parsed_at":"2022-09-23T09:32:29.701Z","dependency_job_id":null,"html_url":"https://github.com/troublete/lua-chunk-manager","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troublete%2Flua-chunk-manager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troublete%2Flua-chunk-manager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troublete%2Flua-chunk-manager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/troublete%2Flua-chunk-manager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/troublete","download_url":"https://codeload.github.com/troublete/lua-chunk-manager/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240229978,"owners_count":19768597,"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":["dependency","dependency-manager","lua"],"created_at":"2025-01-03T16:33:07.241Z","updated_at":"2025-10-19T22:53:43.448Z","avatar_url":"https://github.com/troublete.png","language":"Lua","readme":"# LCM\n\n\u003e The Lua Chunk Manager \n\n\u003e The toolkit does not yet work on Windows, only if there is some kind\n\u003e of ?nix Environment available. This might change in the future though.\n\n## About\n\nThe Lua Chunk Manager aims to be a simpler toolkit for reusing lua code as\ndependencies and distributing lua code (as executable scripts, libs, ...).\n\nI created this toolkit because i wanted to have simpler tooling for my own lua\nand love2d project for managing requirements which does not depend on a\nregistry by default, since a lot of libs are just on Github.\n\n## Requirements\n\n* Lua\n* built-in tools and functions:\n\t- `bash`\n\t- `test`\n\t- `mkdir`\n\t- `curl`\n\t- `rm`\n\t- `tar`\n\t- `mv`\n\t- `wget`\n\n## Demo\n\n`chunkfile.lua` is the essential part that defines an projects' exports,\nrequirements and executable exports. Therefore below an example with all of\nthem. But you define what you need, you don't have to use all of them always.\nAnd in fact if there is an `init.lua` you do not need a `chunkfile.lua` at\nall, `init.lua` will be the default export for your library namespace.\n\nSome more info:\n\n- Requirements are installed 'recursively' so requirements' requirements are\n  loaded aswell\n\n- LCM resolves dependencies flat, so no nesting within libs\n\n- Uniqueness of requirements is defined by their respective `namespaces` so\n  multiple versions or even instances of the same lib can be used when named\n  differently\n\n- `namespaces` can contain `/` (to create nested directories) and will be\n  converted to `.`-notation to be loadable\n\n- LCM allows relative paths inside of libs; e.g. lets assume there is a lib\n  with namespace `simple_lib`. For a file that is located in\n  `*simple_lib_path*/src/main.lua` the require would be on lib level:\n  `require('src.main')`. This is remapped internally to\n  `lib.simple_lib.src.main` by the loader when used in scope of the project\n  containing the `chunkfile.lua` and will resolve correctly;\n  You can also retrieve a single module by using the module name.\n\n```lua\n-- chunkfile.lua\n\n-- EXPORTING --\n\n-- lets assume the library is imported with namespace `example`\n\n-- for exposing some file as default export\n-- (there is no need for this export if there is an `init.lua`)\nexport { 'relative_path/to/file.lua' }\n-- this will be the file returned when the library\n-- namespace is required: e.g. `require('example')`\n\n-- for exposing some file as named export\nexport { 'relative/path/to/file.lua', 'additional'}\n-- this will be the file returned when namespace is\n-- required: `require('example.additional')`\n\n-- REQUIRING --\n\n-- adding local directory as requirement\nsymlink { 'namespace', '/local/absolute/path' }\n-- can be loaded with: `require('namespace')`\n\n-- adding public github repo as requirement\ngithub { 'user/repo' }\n-- can be loaded with: `require('user.repo')`\n\n-- adding private github repo as requirement\ngithub { 'user/repo', user='user:api_token' }\n-- can be loaded with: `require('user.repo')`\n\n-- adding github repo with different state (version, branch, ...) then master (which is default)\ngithub { 'user/repo', at='v1.0.0' }\n-- can be loaded with: `require('user.repo')`\n\n-- adding requirement with custom namespace\n-- (e.g. to allow multiple versions)\ngithub { 'user/repo', namespace='other_name'}\n-- can be loaded with: `require('other_name')`\n\n-- adding requirement with custom env\n-- (will only be installed with `lcm install` or `lcm install --env='dev'`)\nsymlink { 'simple_lib', '/local/path', env='dev' }\n\n-- adding a post_install hook that runs after fetching the library\n-- (exec = os.execute, path = installed lib root)\n-- this feature is intentionally created to run on the consuming side\n-- to minimize security risks\nlocal lrandom = tar { 'lrandom', 'http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/ar/lrandom-100.tar.gz' }\n\nlrandom:post_install(function(exec, path)\n  exec('cd ' .. path .. ' \u0026\u0026 make')\nend)\n\n-- add the lib path to the lua search path\nsymlink { 'simple_lib', '/local/path', env='dev', include_path=true }\n\n-- also available\n-- tar { '*namespace*', '*url*' } – to fetch an arbitrary tar/tar.gz archive as lib\n\n-- `env`, `namespace`, `post_install` apply on any strategy\n-- `at`, `user` apply only on the github strategy\n\n-- EXECUTABLES -- \n\n-- is only be available when used in install context (i.e. when the lib is\n-- installed)\n\n-- adding a executable in `bin` directory\nbin { 'relative/file/path.lua' }\n-- can be used when installed globally (-g) as `path`\n-- can be used when installed locally as `./bin/path\n\n-- adding a named executable in `bin` directory\nbin { 'relative/file/path.lua', 'fancy_name' }\n-- can be used when installed globally (-g) as `fancy_name`\n-- can be used when installed locally as `./bin/fancy_name\n```\n\n```lua\n-- example: test.lua\n-- after running `lcm install` in the directory with the `chunkfile.lua`\n-- above your project needs to require the 'loader' (located\n-- in the `lib` directory, alongside the requirements).\n-- After that, all requirements can be used.\n-- (checkout 'tpl/load.lua' for details)\n\nrequire('lib.load') -- mandatory\nlocal repo = require('user.repo')\nlocal other = require('other_name')\n\n...\n```\n\n## Install\n\nTo simply install the toolkit on your machine run following command\n(requires `wget` and `bash`):\n\n```bash\nwget -O - https://raw.githubusercontent.com/troublete/lua-chunk-manager/master/install.sh | bash\n```\n\nThis will install the toolkit into `~/.lcm` which is the default 'global'\nlocation; you can choose a new location if you like.\n(`export LCM_HOME=*your/path/of/chosing*`)\n\nThe `LCM_HOME` contains all system wide available scripts and libraries that\nwere installed 'globally' (see flag `--global`), including LCM itself.\n\nAfter installing it you shoud be able to run `lcm --help` and see the help\nscreen.\n\n## Uninstall\n\nTo uninstall the toolkit run `rm -rf $LCM_HOME` and remove the lines below the\n`# lcm-config` in `/etc/profile` (the instructions to load `sh-config`).\n\n## Usage\n\nIf you want to only use locally and globally installed dependencies you need\nto require the loader (`require('lib.load')`) in your entrypoint before\nrequiring any library. (see `lcm init` for info how to create a\n`lib/load.lua`)\n\nThere are several commands available to be run. Below a quick overview with\nsome common use-cases. For more info about flags etc. read through the\n`lcm --help` contents.\n\nAll commands can be applied on the `LCM_HOME` (in global scope) when run with\nflag `--global` or `-g`.\n\n### `lcm init`\n\nThe `init` command initializes a new chunk. It runs idempotent. Without flags\nit creates following structure.\n\n```\n.\n├── chunkfile.lua # the chunk config, contains requirements and exports\n└── lib\n    ├── load.lua # the loader, must be required before requiring anyting else; allows the usage of locally and globally installed dependencies\n    └── map.lua # a helper map, which contains module load information after `lcm install`\n```\n\nIf you only want to depend on globally installed libs you can run `lcm\ninit --loader` and only create `/lib/load.lua`.\n\nIf you only want to create a chunk without a specific export file you do not\nneed to run init at all, as long as there is a `init.lua` your chunk will be\nrequire-able.\n\nIf you want to create a custom default or named export and don't have\ndependencies, you can run `lcm init --chunkfile` and only create the\nchunkfile so you can setup the exports.\n\n### `lcm add`\n\nThe `add` command adds a new instruction to the `chunkfile.lua`. This can be\nused to add a new requirement to the chunkfile.\n\n`lua add github:user/handle --namespace=some_lib` adds for example a\n`github { 'user/handle', namespace='some_lib' }` instruction.\n\nYou can add as many instructions as you like with one call. So `lua add\ngithub:user/handle github:user/other_handle\nsymlink:name,/Path/to/lib --user=user:some_api_token` will create\n\n```\ngithub { 'user/handle', user = 'user:some_api_token' }\ngithub { 'user/other_handle', user = 'user:some_api_token' }\nsymlink { 'name', '/Path/to/lib', user = 'user:some_api_token' }\n```\n\nTo register a local lib as globally available lib you can run\n`lcm add -g symlink:name,$PWD` when in project root.\n\nThis command runs `lcm install` after adding instructions, if not wanted run\nwith `--no-install`.\n\nThere is no `lcm remove` command. If you want to remove a dependency, just\nremove it from the `chunkfile.lua` (and run `lcm fix --lib` to clean the lib\ndirectory).\n\n### `lcm install`\n\nRuns idempotent.\n\nInstalls requirements and requirements' requirements in `lib`.\nWrites executables to `bin`.\n\nRun with `--no-post-install` to avoid running any `post_install` scripts.\n\n### `lcm clean`\n\nRemoves everything (dependencies, bins, config files, ...) when run without\nflags (in global scope the `/lib` and `/bin` directories can not be removed\nthat way to assure the integrity of the tooling). \n\nWhen you want to remove only the installed libs run with `--lib` flag.\n\nWhen you want to remove only the created executables run with `--bin` flag.\n\n### `lcm fix`\n\nThis command is a utility tool to fix your chunk setup. \n\nIf run without flags it does nothing, so there is no default fix. \n\nIf run with `--lib` flag, it cleans up `lib` directory and the `lib/map.lua`\nfile. It removes any library that is not listed in the `chunkfile.lua`\nanymore. And rebuilds the `lib/map.lua` to include only available libraries.\n\n### `lcm list`\n\nList all installed modules. \n\nIf you want to display all additional exports (also called load statements)\nrun with `--with-load`.\n\nIf you only want to display additional exports run with `--only-load`.\n\n## Chunkfiles\n\nAs stated multiple times the `chunkfile.lua` is your obilgatory chunk config.\n\nEvery `chunkfile.lua` is execute in a sandbox-ed environment; and only the\nexposed LCM functionality is available. So there should be little\nsecurity problems.\n\nIt is quite tolerant though if there is any instruction added that the LCM\nsandbox doesn't know it just ignores it. So it can be used as container for\nmore than just LCM config. \n\n## On exports\n\nA lib can export one or multiple exports via the `chunkfile.lua`.\n\nEvery lib that should be requireable must have at least one default export.\n\nNo `chunkfile.lua` is needed when an `init.lua` is available, which will then\nserve as default export.\n\nProvided `export` instructions must use a relative path.\n\nMultiple exports must be defined via naming (hence named exports).\nThe name to load them is then the module namespace followed by `.export_name`.\n\ne.g. `some_lib.export_name`\n\nSingle/default exports are for libs that have a single entrypoint other than\n`init.lua`. They are require-able by using the lib namespace. \n\ne.g. `export { 'file/other/than/init' }`\n\nNamed exports are for libs that want to expose several files like monorepos\nwith multiple utils in several files.\n\nIt is possible to require any file of a module by using the fully qualified\nmodule name (usually in the form of `lib.some_dependency.path.to.file`).\n\n## On executables\n\nExecutables can be exposed by any lib, but are only created when the lib is\ninstalled. Locally (during development) it is assumed that the lua file can\nbe called via `lua file.lua`.\n\nYou can either use the `bin { ... }` or the `exec { ... }` instruction to\nexpose an executable.\n\n## Tips \u0026 Troubleshooting\n\n- LCM does not create a `.gitignore` by default, but it might in some cases be\n  a good idea to create one to not push `lib` and `bin` to the remote\n  repository\n\n- If your module or some exports of it are not requireable, try running `lcm\n  install` again; this will (again) add required loads to the mapfile, which\n  sometimes fixes an 'non-loadable' issue\n\n- If you want to 'update' your `lib/load.lua`; remove it an run `lcm\n  init --loader`, this will create a new one from the current version in your\n  LCM install\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroublete%2Flua-chunk-manager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftroublete%2Flua-chunk-manager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftroublete%2Flua-chunk-manager/lists"}