crush ===== **crush** - The uncomplicated LÖVE external module system. **crush** is a minimalistic dependency-less package system for the LÖVE engine. It provides a structured approach to retrieve external libraries for your game project. ## Why? Lua knows some excellent dependency management system, like [LuaRocks](https://luarocks.org). Though, they are inconvenient for a game project, where: * External libraries should be packed along with the game for distribution. * Libraries are often small, and their code should be readily hackable by developers (library versions are not tremendously important). * Depending on a complex package manager is undesireable. LÖVE games have limited ways to manage external libraries: 1. Manually, directly copying external libraries in the game source tree. * Pulling latest changes in the library requires more copy-pasting. * Harder to use libraries if they depend on other libraries themselves. 2. Using a package manager during development, and carefully pack external libraries with the game manually upon distribution. * Introduce additional step to distribution phase. * Many existing LÖVE libraries have no package manager support. **crush** provides an alternative approach, offering the following features: * Fetch external libraries directly from their source code repository, ensuring the ability to pull, or even push, the latest changes from your project. * Automatically pack external libraries inside the project source tree, inside a well-known `lib` folder. * Resolves dependencies recursively, making possible for libraries that depend on other libraries, saving the developer all the manual dependency tracking. * Works automatically with most existing LÖVE libraries, since it directly uses `git` to clone their sources. * Does not require any complex package manager or native code, just a single Lua source file. * Does not require any centralized package repository to publish or fetch libraries. ## How to use it? To use **crush** follow these steps: 1. Copy the latest `crush.lua` into your project's root folder. 2. Create a `.lovedeps` file in the same directory, here you will list every dependency (more in the next section). 3. Once you have `crush.lua` and `.lovedeps` in place, you can populate or refresh project dependencies by running: ```sh lua crush.lua ``` **crush** fetches the project's dependencies recursively, cloning them inside a `lib` subdirectory. Hence, you may use them comfortably in your code with the usual `require()`, like this: ```lua local serialize = require 'lib.serialize' ``` **crush** flattens every dependency in the `lib` folder. This implies that libraries common to different packages must be named and accessed consistently in the source code. A reasonable limitation given **crush** use-case. ## The .lovedeps file The `.lovedeps` file is a regular Lua text file, containing a table where every entry specifies a dependency: ```lua ['dependency-name'] = "git-url" ``` The following example shows a `.lovedeps` file depending on three external libraries, named `df-serialize`, `gear` and `yui`, every dependency has a corresponding `git` repository URL. There dependency name is not required to match the actual repository name, but names **should** be consistent within the entire project, otherwise the same repository may be cloned several times under different names. ```lua { -- Fetch lib/df-serialize from https://git.doublefourteen.io/lua/df-serialize -- needs ['quote'] syntax due to '-' ['df-serialize'] = "https://git.doublefourteen.io/lua/df-serialize", -- Fetch lib/gear from https://git.doublefourteen.io/lua/gear gear = "https://git.doublefourteen.io/lua/gear", -- Fetch lib/yui from https://git.doublefourteen.io/lua/yui yui = "https://git.doublefourteen.io/lua/yui" -- NOTE: Any dependency may also pull additional subdependencies, -- these will also be cloned within lib/ } ``` ## Philosophy **crush** is somehow opinionated and tied to its intended use-case. It obeys the following rules: `MUST`: * Be self-contained, only a single Lua file: `crush.lua`. * Must only depend on Lua, LÖVE and `git`, expected to be available on any LÖVE developer machine. * Do one thing: fetch the dependencies listed in the `.lovedeps` file. * Be simple and predictable, integrating **crush** into a LÖVE game must be as intuitive as possible. * Be hackable, its code must be reasonably trivial, understandable and adaptable. * Enforce one way to do things, encouraging consistency. `MUST NOT`: * Give in to feature creep. * Provide a centralized repository. * Be completely general, its scope is limited to the average LÖVE game or library. * Be entirely safe, there is no demand for checksum or strict versioning in **crush** use case. `SHOULD NOT`: * Break compatibility with older `.lovedeps` files. If this does not meet your requirements, code should still be sufficiently hackable to provide some room for customization. ## Similar projects * [LÖVERocks](https://github.com/Alloyed/loverocks) is a more involved project with the ambition to bring LuaRocks features to LÖVE. ## License MIT, see [LICENSE](LICENSE) for details.