{"id":22300327,"url":"https://github.com/dropseed/p","last_synced_at":"2025-07-29T02:31:35.529Z","repository":{"id":43113432,"uuid":"154613153","full_name":"dropseed/p","owner":"dropseed","description":"P is for project. As in, \"How the hell do I work on this project.\"","archived":false,"fork":false,"pushed_at":"2024-09-20T20:22:49.000Z","size":190,"stargazers_count":19,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-29T01:41:07.706Z","etag":null,"topics":["command-line-tool","developer-experience","dx","personal-utility","scripts","standardization"],"latest_commit_sha":null,"homepage":"https://www.dropseed.dev/p/","language":"Python","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/dropseed.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":"2018-10-25T05:07:37.000Z","updated_at":"2025-07-18T22:59:03.000Z","dependencies_parsed_at":"2022-09-05T23:41:17.861Z","dependency_job_id":null,"html_url":"https://github.com/dropseed/p","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/dropseed/p","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropseed%2Fp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropseed%2Fp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropseed%2Fp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropseed%2Fp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dropseed","download_url":"https://codeload.github.com/dropseed/p/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dropseed%2Fp/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267616991,"owners_count":24116190,"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-07-28T02:00:09.689Z","response_time":68,"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":["command-line-tool","developer-experience","dx","personal-utility","scripts","standardization"],"created_at":"2024-12-03T18:10:31.759Z","updated_at":"2025-07-29T02:31:35.280Z","avatar_url":"https://github.com/dropseed.png","language":"Python","readme":"# p\n\nP makes it easier to jump between projects and get work done.\nIt gathers up all of the available commands/scripts in a repo,\nand aliases them to `p \u003cname\u003e`.\n\n**P is not a project requirement or dependency -- it is a personal\ntool.** Nothing in your project should depend on p, but rather conform\nto p-friendly standards which are usable with or without p itself.\nThis means that if you use p,\nyou get the best experience possible.\nAnd for the contributors who don't use p,\nat least they get a well-documented and well-maintained developer experience.\n\nIf you *personally* start using it,\nyou'll probably find that `p` is the first thing you run after `cd \u003cproject\u003e` to get your bearings and start doing work.\n\n[But... why?](#why)\n\n## Install or update\n\nDon't add it to a project. Add it to your machine, system-wide or user-wide.\n\n```sh\n# System-wide or user-wide, not per project\n$ pip3 install -U p\n```\n\n## What it looks like\n\n```text\n$ cd project\n$ p\n  Usage: p [OPTIONS] COMMAND [ARGS]...\n\n  Options:\n  --version\n  --help     Show this message and exit.\n\n  Commands:\n  compile-assets  Using: npm run compile-assets\n  install         Using: ./scripts/install\n  load-fixtures   Using: ./scripts/load-fixtures\n  pre-commit      Using: ./scripts/pre-commit\n  test            Using: ./scripts/test\n```\n\n## Supported tools and workflows\n\nNote that p really only supports stuff that we use at [Dropseed](https://www.dropseed.dev/).\n**So this list is intentionally short.**\nIf you use p day-to-day and would like to see support for something not listed here,\n[just let us know](https://github.com/dropseed/p/issues)!\n\n### Executable scripts\n\nP will automatically find executable scripts in `./scripts` or `./bin`.\n\nThey should have no extension (don't need \".sh\") and should be executable (`chmod +x ./scripts/thing`).\n\nThe filename will be added as a command so that they can simply be run by doing `p {script-name}`.\n\n\nFor example, this structure:\n\n```text\n$ tree scripts/\nscripts/\n├── compile-assets\n├── load-fixtures\n├── pre-commit\n├── setup\n├── start-postgres\n├── test\n└── work\n```\n\nWill result in:\n\n```text\n$ p\n  Usage: p [OPTIONS] COMMAND [ARGS]...\n\n  Options:\n    --version\n    --help     Show this message and exit.\n\n  Commands:\n    compile-assets  Using: ./scripts/compile-assets\n    load-fixtures   Using: ./scripts/load-fixtures\n    pre-commit      Using: ./scripts/pre-commit\n    setup           Using: ./scripts/setup\n    start-postgres  Using: ./scripts/start-postgres\n    test            Using: ./scripts/test\n    work            Using: ./scripts/work\n```\n\n### Makefile\n\nIf there is a `Makefile` in your project,\np will automatically parse `.PHONY` and make those commands available via p.\nSo if you have `make test`,\nit will also be available to p users via `p test`.\n\n### package.json scripts\n\nEntries in your `package.json` \"scripts\" will automatically be mapped to p commands.\n\nFor example:\n\n```js\n{\n  \"scripts\": {\n    \"start\": \"react-scripts start\"\n  }\n}\n```\n\nWould result in:\n\n```text\nUsage: p [OPTIONS] COMMAND [ARGS]...\n\nOptions:\n  --version\n  --help     Show this message and exit.\n\nCommands:\n  start    Using: npm run start\n```\n\n## Git hooks\n\nP also provides automatic installation of [git hooks](#using-git-hooks).\n\nFor example, if you have a command named `pre-commit`, running `p\ninstall` or `p {git-hook-name}` will prompt you to install\nit into your local `.githooks` for the repo.\n\nThen when you run `git commit`,\nyour `p pre-commit` will be run automatically.\n\nAn example of a `pre-commit` script:\n```sh\n#!/bin/sh -e\nblack pullapprove --check --exclude migrations\n```\n\n## Grouping (advanced)\n\nTo make the p help more user friendly you can group and hide commands from the top-level.\nThis works automatically by using a `:` in your command name.\n\nFor example, if you have commands like `db:load` and `db:reset`, you'll get a `db` group.\nYou can run `p db` to see the subcommands in db, and run `p db load` to run a subcommand.\n\n```text\n$ p\n  Usage: p [OPTIONS] COMMAND [ARGS]...\n\n  Options:\n    --version\n    --help     Show this message and exit.\n\n  Commands:\n    db\n\n$ p db load\n```\n\n(You can also invoke the grouped commands directly as `p db:load`.)\n\n---\n\n## Why\n\n### Context switching sucks\n\nIt can often take several minutes just to figure out how to *start* working on\nsomething.\n\nEvery project is different, but damn near every project comes with a set of\ndevelopment commands or scripts to run common actions. And if it doesn’t, then\nit probably should.\nDifferent languages, people, and tools accomplish this in different ways. Some\nprojects use the good ol’ `Makefile`, while others use `package.json` “scripts”,\nbash scripts, `rake`, `fabric`, and so on and so on…\n\nP was built to make it easier to jump between projects,\nand to save some keystrokes in the meantime.\n\n### Improving developer experience\n\nIdeally, p will “just work”.\nBut if not,\nit is often in your project’s best interest to design a developer experience that *would* work if someone were using p.\nThat is – script out some of the most commonly used actions for your project (`install`, `test`, `deploy`, etc.),\nand put them in a uniform place where contributors can easily figure out how to use them.\nNow even the people who don't use p at least have a shot at getting up and running on their own.\n\n### The search for a universal experience\n\nFor a long time I've been in search of the perfect development task manager to use on every project.\nBut that proved to be difficult as the repos got smaller,\nmore self-contained,\nand spread across languages and dependency systems.\n\nUsing a Makefile is the closest thing to what I'm looking for.\nMost people have `make`.\nBut there's a lot of things I just can't stand about it\n(it's just ugly, and I can't help but think that it feels like some kind of *hack*).\n\nI've settled on the idea of using a \"scripts\" folder with one-off files for each task.\nUsually just bash scripts,\nbut can easily be a small Python script or something else.\nThese work basically everywhere,\nand it's not hard to tell someone to do `./scripts/test`.\n\nBut even the \"scripts\" pattern doesn't make sense *on every project*.\nSome frameworks/projects already come with a solution,\nlike pre-existing `package.json` \"scripts\".\nDo we really want to create make `scripts/test` that just runs `npm run test`?\nSeems dumb.\n\"I guess we'll use npm scripts on this project...\"\n\nSo, every project inevitably ends up being a little bit different.\nBut for those of us that have to constantly jump around between those projects,\np smooths out the rough edges in our day-to-day,\nand enables us to make per-project decisions about the developer experience\n(and reminds us to even be thinking about that in the first place).\n\n### Bonus: git hooks\n\nGit hooks can be a super useful,\nbut confusing process to use.\nThe [gist](https://www.atlassian.com/git/tutorials/git-hooks#local-hooks) is that they generally aren't shared or set up for each user of a project automatically.\nThere are some tools like [pre-commit](https://pre-commit.com/) or [husky](https://github.com/typicode/husky) that really go the extra mile in creating a system for git hooks,\nbut a lot of our projects don't really warrant that and,\nagain,\nit felt strange to now have a project dependency in that process...\nDo we install that thing per-project even if the project doesn't use that language otherwise?\nIf we install it on our machines outside the project,\nis that now a requirement that can't be required?\nIs it even possible to run the hook/linter/formatter without that tool?\n\nAnyway, p embraces git's (implied) attitude about hooks: they're optional.\n\nIf a user has p,\nthen we'll take an extra step to install the git hook for them and put things in place.\nIt's a nice-to-have.\n\nIf you don't have p, then at least you can still run your linters/formatters manually if you want (i.e. `npm run pre-commit`).\n\nAnd if you need to *require* that those checks are run,\nno matter who (or what) commits to the project?\nThen set them up in CI.\nYou don't need anything special to do this --\njust run your script/command as a step like a non-p user would.\n\nIt's not fancy,\nand it works for us.\n\n## Inspired by\n- [Dropseed’s](https://github.com/dropseed) project-cli (private)\n- [Flint Hills Design’s](https://github.com/flinthillsdesign) fhd-cli (private)\n- [https://github.com/github/scripts-to-rule-them-all](https://github.com/github/scripts-to-rule-them-all)\n- [https://github.com/bkeepers/strappydoo](https://github.com/bkeepers/strappydoo)\n- having too many projects\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdropseed%2Fp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdropseed%2Fp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdropseed%2Fp/lists"}