{"id":21346859,"url":"https://github.com/queer/peckish","last_synced_at":"2025-08-21T09:04:32.144Z","repository":{"id":154212171,"uuid":"610550866","full_name":"queer/peckish","owner":"queer","description":"peckish (case-sensitive) is a CLI tool/Rust library for (re)packaging Linux software artifacts.","archived":false,"fork":false,"pushed_at":"2024-10-23T12:39:23.000Z","size":1037,"stargazers_count":52,"open_issues_count":10,"forks_count":0,"subscribers_count":3,"default_branch":"mistress","last_synced_at":"2025-08-19T04:56:53.656Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/queer.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-07T01:56:41.000Z","updated_at":"2025-07-29T14:20:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"5ea94469-a4c6-428a-85d4-fd1f60961a84","html_url":"https://github.com/queer/peckish","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/queer/peckish","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fpeckish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fpeckish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fpeckish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fpeckish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/queer","download_url":"https://codeload.github.com/queer/peckish/tar.gz/refs/heads/mistress","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queer%2Fpeckish/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271454825,"owners_count":24762698,"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","status":"online","status_checked_at":"2025-08-21T02:00:08.990Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-22T02:11:47.753Z","updated_at":"2025-08-21T09:04:32.125Z","avatar_url":"https://github.com/queer.png","language":"Rust","funding_links":["https://patreon.com/amyware"],"categories":[],"sub_categories":[],"readme":"# peckish\n\npeckish (case-sensitive) is a tool for repackaging Linux software artifacts.\n\nFor example, suppose you're an application developer. You just made something\ncool and want to distribute it. However, packaging is _hard_. Different package\nformats do things differently -- ex. Arch has `x86_64` and `any` as\narchitectures, but Debian has over a dozen and calls \"`x86_64`\" \"`amd64`\" --\nand it's hard to remember all the specifics. This is compounded by having to\nfigure out the appropriate CLI flags for each package format. How many people\ncan write a [valid `tar` command](https://xkcd.com/1168/) on the first try? :P\n\nThis problem is fairly common:\n\n\u003e It seems more and more common, at least in the self-hosted community, to\n\u003e provide two methods of installations: Docker or a shell script installer. It\n\u003e seems that many new projects don’t even bother with a native package manager,\n\u003e such as dpkg or rpm, which makes me reluctant to use them.\n\u003e\n\u003e https://yotam.net/posts/the-audacity-of-piping-curl-to-bash/\n\n\u003e It's easier to compile the linux kernel from scratch than it is to build a\n\u003e debian package from scratch.\n\u003e\n\u003e It's mind-blowing how complicated it is; at the end of the day it's just an\n\u003e archive. I hate having to do it.\n\u003e\n\u003e https://news.ycombinator.com/item?id=34787228\n\n\u003e The impact of having frictionless package building cannot be understated. I'm\n\u003e publishing Arch Linux packages for all my applications because it takes just\n\u003e a few minutes to write up a PKGBUILD. Then one time, I tried providing a\n\u003e Debian package as well, but I gave up after several hours of trying to get\n\u003e through all the bureaucracy of the tooling.\n\u003e\n\u003e https://news.ycombinator.com/item?id=34923960\n\n\u003e [...] I've created my own RPM and DEB packages in the past as well; but, at\n\u003e least when I did it years ago, it wasn't as effective as a PKGBUILD on arch.\n\u003e\n\u003e https://news.ycombinator.com/item?id=35014171\n\n\u003e Official documentation is a problem. It is aimed at Debian maintainers\n\u003e building a fully policy compliant package that could be accepted to the\n\u003e official repository. You don't need any of that crap for making a .deb\n\u003e package. It puts off people from creating Debian packages for their own\n\u003e programs or private use.\n\u003e\n\u003e https://news.ycombinator.com/item?id=34788350\n\n\u003e \u003e If my package manager had an Oh My Zsh package\n\u003e\n\u003e This is the author missing the point. The reason `curl | bash` is common is\n\u003e because devs don't like packaging for every distro under the sun, and MacOS,\n\u003e and FreeBSD, and... If you really think `curl | bash` is the problem, then\n\u003e you should be lining up to package the stuff you use for your distro.\n\u003e Instead, it is always someone else's problem.\n\u003e\n\u003e Package managers are great... for the user. For everyone else, a polyglot\n\u003e system, with arcane technical policies, and even more arcane human policies\n\u003e is... not ideal.\n\u003e\n\u003e https://news.ycombinator.com/item?id=33832401\n\npeckish aims to solve this. Instead of mangling your files with various arcane\ntools, spinning up Docker containers or VMs to try to build packages and make\nsure they install or are even valid, and all the other pains, you can just\nwrite a basic YAML file, and you're done! peckish does the rest, _without_\nshelling out to distro-specific tools!\n\nAdditionally, peckish makes repackaging software easier. You can take a DEB and\nconvert it into an RPM, or a Docker image to flat files on the filesystem, or\nturn a tarball into an installable package for DEB-based, RPM-based, or\nArch-based distros.\n\npeckish lets you convert back and forth between all of these formats:\n\n- flat files on the filesystem\n- a tarball\n- an installable Debian package\n- an installable Arch Linux package\n- a runnable Docker image\n- an installable RPM package\n- an ext4 image (wip)\n\npeckish is based around the concept of \"artifacts\" and \"producers.\" An artifact\nis some metadata about a package that exists on your system, and a producer is\nsomething that takes in an artifact and produces a new artifact. For example,\ntaking a tarball and producing a DEB or RPM package.\n\n- [peckish concepts](#concepts)\n- [artifact and producer docs](https://github.com/queer/peckish/tree/mistress/docs)\n\n## features\n\n- convert between package formats\n  - flat files\n  - tarballs\n  - `.deb` packages\n  - Arch Linux packages\n  - Docker images\n  - `.rpm` packages\n  - ext4 filesystem images\n- [GitHub Actions support](#github-actions)\n- [library support](#library)\n- (WIP) [reproducible builds support](#reproducible-builds)\n- statically-linked release binaries\n\n## caveats\n\n- peckish is `0.x.y`! Treat it accordingly. Maybe don't run it in prod.\n- Documentation is hard, and I am not the best at it. Some questions may only\n  be able to be answered by reading the source or opening an issue. Reporting\n  missing and/or broken docs helps everyone!\n- peckish is **not** a build system or a package manager. It doesn't care about\n  how your code is built or installed, just about getting it from one package\n  format to another.\n- peckish **does not** guarantee that files are placed in the correct locations\n  in the package, just that the package is valid. For example, if you convert a\n  DEB to an RPM, you'll need to make sure that the files in the RPM are\n  installed to the correct locations.\n- peckish **cannot** guarantee all dependencies are placed into the package\n  correctly. It's up to you to make sure your package is statically linked, or\n  that all dependencies are included in the package.\n- peckish is primarily tested for my use-cases. Please please please please\n  report bugs!\n- **Packages produced with peckish almost certainly are not of sufficient\n  quality to be accepted into a distro's official repositories**. PLEASE don't\n  waste the time of distro maintainers by submitting a bunch of\n  peckish-generated packages.\n\n## community\n\npeckish is a part of the [amyware discord server](https://discord.gg/7WgSTwh).\n\nIf you like what I make, consider supporting me on Patreon:\n\n[\u003cimg src=\"https://i.imgur.com/YFjoCd1.png\" width=\"162\" height=\"38\" /\u003e](https://patreon.com/amyware)\n\n## usage\n\nCreate a `peckish.yaml` file in the root of your project.\n\n```yaml\n# whether to chain outputs, ie each artifact output is the input to the next\n# producer. defaults to `false` if not specified.\nchain: false\n\n# metadata about the package. required, even if you're only producing a file or\n# a tarball. this is because it's just easier than trying to play the \"is there\n# enough metadata to build the package\" game.\nmetadata:\n  name: \"my-cool-pkg\"\n  # many distros want versions that end in -#, which is a revision number for\n  # the package. this is required if you are producing an Arch/Deb/RPM/similar\n  # package.\n  version: \"0.1.0-1\"\n  description: \"a package\"\n  # suggested format: \"me \u003cme@example.com\u003e\"\n  author: \"me\"\n  # the architecture of the system the package is built for. this is usually\n  # the same as the architecture of the system you're building on. will be\n  # automatically set to the correct value for the target package format, ex.\n  # x86_64 -\u003e amd64 for debian.\n  arch: \"amd64\"\n  license: \"Apache-2.0\"\n\n# the artifact being used as input to the pipeline.\ninput:\n  name: \"some file\"\n  type: \"file\"\n  paths:\n    - \"./path/to/file\"\n\n# the producers being used as outputs. see `docs/` for more info about each\n# producer.\noutput:\n  - name: \"tarball\"\n    type: \"tarball\"\n    path: \"./whatever.tar\"\n\n  - name: \"debian package\"\n    type: \"deb\"\n    path: \"./whatever.deb\"\n    # a list of changes to inject into the filesystem. this lets you move,\n    # copy, symlink, etc. files and directories within the artifact before it's\n    # written to disk. see `docs/injections.md` for more info.\n    injections:\n      - \"move-file\"\n      - \"cleanup\"\n\n# the actual injections that are applied to output artifacts. these are\n# specified in their own group to allow for reuse between multiple producers.\ninjections:\n  move-file:\n    type: \"move\"\n    src: \"/path/to/file\"\n    dest: \"/new/path/to/file\"\n  cleanup:\n    type: \"delete\"\n    path: \"/path\"\n```\n\n### suggested use-cases\n\n- Package your software for more distros with less pain\n- Extract packages without having to memorise arcane CLI flags\n- Create Docker images without a `Dockerfile`\n- Make a package for one distro installable on others, without having to\n  repackage by hand\n- Programmatically create/manipulate packages in Rust\n\n### library\n\n**crates.io:** https://crates.io/crates/peckish\n\nMSRV 1.74.\n\n```rust\n// artifacts\nuse peckish::prelude::builder::*;\nuse peckish::prelude::*;\n\nlet file_artifact = FileArtifactBuilder::new(\"example file artifact\".into())\n    .add_path(\"./examples/a\".into())\n    .build()?;\n\nlet tarball_producer = TarballProducerBuilder::new(\"example tarball producer\".into())\n    .path(\"test.tar.gz\".into())\n    .build()?;\n\nlet tarball_artifact = tarball_producer.produce(\u0026file_artifact).await?;\n\n// pipelines\nuse peckish::prelude::pipeline::*;\nuse peckish::prelude::*;\n\nlet file_artifact = ...;\n\nlet tarball_producer = ...;\n\nlet debian_producer = ...;\n\nlet config = PeckishConfig {\n    input: ConfiguredArtifact::File(file_artifact),\n    output: vec![\n        ConfiguredProducer::Tarball(tarball_producer),\n        ConfiguredProducer::Deb(debian_producer),\n    ],\n    chain: false,\n};\n\nlet pipeline = Pipeline::new();\nlet out = pipeline.run(config).await?;\nprintln!(\"produced {} artifacts\", out.len());\n```\n\n### GitHub Actions\n\nGitHub Actions for peckish can be found at [queer/actions](https://github.com/queer/actions).\n\n```yaml\n- name: \"install peckish!\"\n  uses: \"queer/actions/peckish_install@mistress\"\n  with:\n    token: \"${{ secrets.GITHUB_TOKEN }}\"\n- name: \"run peckish!\"\n  uses: \"queer/actions/peckish_run@mistress\"\n```\n\n### reproducible builds\n\npeckish tries to respect [`SOURCE_DATE_EPOCH`](https://reproducible-builds.org/docs/source-date-epoch/).\nPlease open issues or PRs if you find places where it doesn't!\n\n## roadmap\n\n### package/artifact formats\n\nThe goal/hope is to be able to support all of these. Formats not listed may end\nup on the list in the future. Formats that are not currently supported may\nnever be supported.\n\n- [x] flat files `\"file\"`\n- [x] arch package `\"arch\"`\n- [x] tarball `\"tarball\"`\n- [x] debian package `\"deb\"`\n- [x] docker image `\"docker\"`\n- [x] rpm package `\"rpm\"`\n- [x] Filesystem and VM images `\"ext4\"`\n  - WIP\n- [x] OCI images `\"oci\"`\n  - WIP\n- [ ] appimage `\"appimage\"`\n  - squashfs: https://crates.io/crates/backhand\n  - unpacker: ???\n- [ ] Flatpak?\n  - More research needed\n\n### other\n\n- [x] compression handled transparently\n- [ ] [WIP] `SOURCE_DATE_EPOCH` support for reproducible builds\n- [ ] better docs\n- [x] GitHub Actions support for ease-of-use\n  - https://github.com/queer/actions\n- [ ] better error messages\n- [ ] maybe someday hit 1.0.0?\n\n## concepts\n\npeckish is built around the concepts of _artifacts_ and _producers_.\n\nArtifacts are some sort of data that exists on your system that can be\npackaged; artifacts themselves do not contain any of that data, just metadata.\nFor example, a `FileArtifact` is a list of paths to files on your system. A\n`TarballArtifact` is a path to a tarball. A `DebArtifact` is a path to a\n`.deb` file. So on and so forth.\n\nProducers are a bit more interesting. Producers are the things that actually\ndo the packaging: they take an artifact as input and produce a new artifact\nas output. For example, a `TarballProducer` may take a `FileArtifact` as input\nand produce a `TarballArtifact` as output, a `DebProducer` may take a\n`TarballArtifact` as input and produce a `DebArtifact` as output, and so on.\n\npeckish artifacts and producers are centred around the idea of an in-memory\nfilesystem. Rather than having to mangle things on the disk, peckish moves\neverything into memory, manipulates it, then flushes it back to disk. This\nallows for trivial manipulation of software artifacts, as changing them is\nsimply injecting some changes into the in-memory filesystem and repackaging\nwith the metadata in the producer. No knowledge of the previous artifact is\nneeded beyond its in-memory filesystem representation.\n\n## misc\n\n### why is it called peckish?\n\nIf you pretend really hard, \"peckish\" sounds kinda sorta a bit like \"package.\"\n\n### related libraries\n\n- [`floppy-disk`](https://github.com/queer/floppy-disk): async filesystem facade\n- [`disk-drive`](https://github.com/queer/disk-drive): multi-`floppy-disk` utils\n- [`flop`](https://github.com/queer/flop): `floppy-disk` archive facade\n- [`smoosh`](https://github.com/queer/smoosh): automagic async (re)compression\n- [`nyoom`](https://github.com/queer/nyoom): filesystem walker for `floppy-disk`\n- [`flail`](https://github.com/queer/flail): `floppy-disk` facade for ext4\n\n### license\n\nCopyright 2023-present amy null\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueer%2Fpeckish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqueer%2Fpeckish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueer%2Fpeckish/lists"}