{"id":15595143,"url":"https://github.com/simonneutert/git-hire","last_synced_at":"2025-04-10T13:41:42.595Z","repository":{"id":41163811,"uuid":"508259463","full_name":"simonneutert/git-hire","owner":"simonneutert","description":"This app helps you keep track of GitHub users in cities, saving the data as .edn to disk. So you can easily `grep` by language or keyword. Interact with the GitHub API using Clojure/babashka","archived":false,"fork":false,"pushed_at":"2025-02-07T16:55:31.000Z","size":58,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-06T10:02:34.704Z","etag":null,"topics":["babashka","cli-app","clojure","github-api"],"latest_commit_sha":null,"homepage":"","language":"Clojure","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/simonneutert.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":"2022-06-28T10:50:12.000Z","updated_at":"2025-02-07T16:55:33.000Z","dependencies_parsed_at":"2023-12-22T07:32:46.287Z","dependency_job_id":"8741d0c8-7749-45d9-91f9-0061bd726daf","html_url":"https://github.com/simonneutert/git-hire","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/simonneutert%2Fgit-hire","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fgit-hire/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fgit-hire/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonneutert%2Fgit-hire/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simonneutert","download_url":"https://codeload.github.com/simonneutert/git-hire/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248226071,"owners_count":21068122,"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":["babashka","cli-app","clojure","github-api"],"created_at":"2024-10-03T00:43:23.476Z","updated_at":"2025-04-10T13:41:42.587Z","avatar_url":"https://github.com/simonneutert.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git hire! hire on 🔥!\u003c!-- omit from toc --\u003e\n\nEver wondered who is coding what in your city and how to keep track of it, maybe `grep` projects by keyword?\n\nThis is your tool! (babashka \u003e= 1.0.171 mandatory)\n\n## What is .edn? \u003c!-- omit from toc --\u003e\n\nEDN is a data format, like JSON, but more like Clojure's native data format.\n\nA result can look like this:\n\n```clojure\n{:name \"Simon Neutert\"\n :hireable true\n :languages [\"HTML\"]\n :bio \"I'm an HTML hacker.\"\n :location \"Area 50++\"\n :public-repos 123\n :repos-url \"https://api.github.com/users/simonneutert/repos\"\n :type \"User\"}\n```\n\n### Need JSON? \u003c!-- omit from toc --\u003e\n\nI can highly suggest [jet](https://github.com/borkdude/jet) for that.\n\n---\n\n![this is fine dog](https://i.kym-cdn.com/entries/icons/mobile/000/018/012/this_is_fine.jpg)  \nhttps://knowyourmeme.com/memes/this-is-fine\n\n---\n\n- [Features](#features)\n- [planned features](#planned-features)\n- [Prerequisities](#prerequisities)\n- [Run](#run)\n  - [Configuration](#configuration)\n    - [Sleep time](#sleep-time)\n  - [Run in Docker](#run-in-docker)\n  - [Run locally](#run-locally)\n    - [examples](#examples)\n  - [Search in result files (saved profiles)](#search-in-result-files-saved-profiles)\n    - [examples](#examples-1)\n  - [Inspect Profiles (with examples! 🤯)](#inspect-profiles-with-examples-)\n  - [Find juniors/new-joiners](#find-juniorsnew-joiners)\n- [FAQ](#faq)\n  - [Errors](#errors)\n  - [CookBook Babashka](#cookbook-babashka)\n  - [How to Clojure in VS Code](#how-to-clojure-in-vs-code)\n  - [\"github-username.edn\" what am I supposed to do with that? JSON would be much nicer!](#github-usernameedn-what-am-i-supposed-to-do-with-that-json-would-be-much-nicer)\n    - [transform to JSON](#transform-to-json)\n\n\n## Features\n\n- [x] up to 1000 users per city + language combination (sorted by \"users' public repositories count\")\n- [x] if less than 1000 users in a city total, you can download by location only\n- [x] concurrency built-in 🚀\n\n## planned features\n\n- [ ] get all users (not just 1000)\n  - implement automatic bucketing, sliding through the limits\n  - PROBLEM: GitHub sets the limit here 🥴\n- [ ] tests?! 🧌\n- [ ] sort by active last week? OR created in year?\n- [x] speed isn't crucial, but utilizing some of `clojure.core.async` magic could speed things up 10x maybe :thinking: `pmap` ftw 🎉\n\n## Prerequisities\n\n- [babashka](https://www.babashka.org) **latest supported version for this code is currently 1.0.171**\n- GitHub API Token ([Personal Access Tokens](https://docs.github.com/en/rest/guides/getting-started-with-the-rest-api#using-personal-access-tokens))\n- Java doesn't hurt, too\n\nmake sure your ENV has the `GITHUB_HIRE_TOKEN` at hand.  \nI do it like this:  \nin a terminal enter `$ export GITHUB_HIRE_TOKEN=\"\u003cmy-token-here\u003e\"`  \nthen, from that terminal open your IDE of choice, like  \n`$ code .`\n\nor have it in your `.zshrc` 🤗 or whatever your shell loads at start\n\n🥳 happy times in the REPL\n\n## Run\n\nHere's what you need to get the thing running.\n\n- [babashka](https://www.babashka.org) or Docker/Podman\n- Project Configuration (optional)\n\n### Configuration\n\nCurrently, the only configuration you can do is setting sleep time between request cycles.\n\n#### Sleep time\n\n**DEFAULT** sleep time is 30 seconds.\n\nIncrease the sleep time to avoid hitting the GitHub API rate limit.\n\nYou can customise the sleep time between cycles by setting the `SLEEP_TIME_SECONDS` environment variable.\n\n```bash\n$ SLEEP_TIME_SECONDS=15 bb scrape \u003clocation-like-city-or-country\u003e \u003clanguage\u003e\n```\n\n### Run in Docker\n\nAll of the following should work in Docker, too.\n\nThe simplest way for you is to use the given Dockerfile.\n\n```bash\n$ docker build --build-arg github_hire_token=${GITHUB_HIRE_TOKEN} -t git-hire .\n$ docker run -it --rm git-hire\n```\n\nIf you need to store the profiles, you can mount a docker volume, but this goes beyond the scope of this README.\n\n### Run locally\n\n```bash\n$ bb scrape \u003clocation-like-city-or-country\u003e\n```\n\nWill save the github profiles as `.edn` into the `profiles` directory,  \n**but** as GitHub support let me know:  \n\u003e When using the language qualifier when searching for users, it will only return users where the majority of their repositories use the specified language. (please, see [documentation](https://docs.github.com/en/search-github/searching-on-github/searching-users#search-by-repository-language))\n\nSpecify further adding a language:\n\n```bash\n$ bb scrape \u003clocation-like-city-or-country\u003e \u003clanguage\u003e\n```\n\n**Be warned!** This might not find a PHP dev who switched to Rust recently, as described by GitHub's Support.\n\nOr if the city is too crowded, try loading mainstream languages for a given city.  \n**Watch your rate limits ⚠️**\n\nAfter having built a pool of profiles, use  \n`$ bb search-keyword \"rust\"` and/or see examples given below.\n\n#### examples\n\n`$ bb scrape mainz`  \n`$ bb scrape \"Bad Kreuznach\"`  \n`$ bb scrape wiesbaden java`  \n`$ bb scrape wiesbaden php`  \n`$ bb scrape mainz javascript`\n\n### Search in result files (saved profiles)\n\n`$ bb search-keyword \u003csearch term skill framework else\u003e`\n\n#### examples\n\n`$ bb search-keyword android`  \n`$ bb search-keyword \"ruby on rails\"`  \n`$ bb search-keyword nuxt`\n\nyou might go further, by piping to bb again, unimaginable possibilities...\n\n```bash\n$ mkdir rails; cp $(grep -Zril rails profiles) rails\n```\n\nand then:\n\n```bash\n$ bb search-keyword \"ios\" | bb -e '(map #(str/upper-case %) *input*)'\n```\n\n### Inspect Profiles (with examples! 🤯)\n\n```bash\n$ bb read-profile.clj simonneutert\n```\n\ngo further, by piping:\n\n```bash\n$ bb read-profile.clj simonneutert | bb -e '(:languages *input*)'\n```\n\nthen read many profiles\n\n```bash\n$ bb search-keyword ruby | bb -e '(mapv #(edn/read-string (slurp %)) *input*)'\n```\n\nmap out `name` and `bio`, where `bio` is provided\n\n```\n$ bb search-keyword ruby |\\\n    bb -e '(mapv #(edn/read-string (slurp %)) *input*)' |\\\n    bb -e '(mapv #(select-keys % [:name :bio]) *input*)' |\\\n    bb -e '(remove #(nil? (:bio %)) *input*)'\n```\n\nmap out `name` and `bio`, where `bio` is provided, filter by bio containing \"apple\"\n\n\n```bash\n$ bb search-keyword ruby |\\\n    bb -e '(mapv #(edn/read-string (slurp %)) *input*)' |\\\n    bb -e '(mapv #(select-keys % [:name :bio]) *input*)' |\\\n    bb -e '(remove #(nil? (:bio %)) *input*)' |\\\n    bb -e '(filter #(clojure.string/includes? (clojure.string/lower-case (:bio %)) \"apple\") *input*)' |\\\n    bb -e '(clojure.pprint/pprint *input*)'\n```\n\nwhat you came here for 🔥 find all hireable\n\n*search-keyword git* is sort of a hack returning all profiles you downloaded at this point\n\n```bash\n$ bb search-keyword git |\\\n    bb -e '(mapv #(edn/read-string (slurp %)) *input*)' |\\\n    bb -e '(remove #(nil? (:hireable %)) *input*)'\n```\n\n### Find juniors/new-joiners\n\n```bash\n# using httpie\nGITHUB_HIRE_SINCE_YEAR=2019;\nGITHUB_HIRE_LOCATION=wiesbaden;\nhttps -A bearer -a ${GITHUB_HIRE_TOKEN} \\\n  \"https://api.github.com/search/users?q=created%3A%3E${GITHUB_HIRE_SINCE_YEAR}-01-01+location%3A${GITHUB_HIRE_LOCATION}+repos%3A%3E1\u0026type=Users\" \\\n  \"Accept\":\"application/vnd.github.v3+json\"\n```\n\n```bash\n# using httpie and jq\nGITHUB_HIRE_SINCE_YEAR=2019;\nGITHUB_HIRE_LOCATION=wiesbaden;\nhttps -A bearer -a ${GITHUB_HIRE_TOKEN} \\\n  \"https://api.github.com/search/users?q=created%3A%3E${GITHUB_HIRE_SINCE_YEAR}-01-01+location%3A${GITHUB_HIRE_LOCATION}+repos%3A%3E1\u0026type=Users\" \\\n  \"Accept\":\"application/vnd.github.v3+json\" |\\\n  jq '.items | map(select(.type == \"User\")) | .[] |.repos_url'\n```\n\n\n## FAQ\n\nSome stuff you would want to know/read as a beginner.\n\n### Errors\n\n- REPL fails and outputs  \n  `; : Can't set!: *current-length* from non-binding thread user `\n\n`pmap` and `curl` don't play well with each other in the shell (I guess).  \nDon't worry, run the tool from the shell:  \n`bb scrape berlin ruby`  \nit will fire up some threads 🔥\n\n### CookBook Babashka\n\nhttps://book.babashka.org/\n\n### How to Clojure in VS Code\n\nhttps://clojure.org/guides/editors#_vs_code_rapidly_evolving_beginner_friendly\n\n### \"github-username.edn\" what am I supposed to do with that? JSON would be much nicer!\n\nCLI to transform between JSON, EDN and Transit, powered with a minimal query language.\n\nhttps://github.com/borkdude/jet\n\n#### transform to JSON\n\n```bash \n$ bb search-keyword ruby |\\\n    bb -e '(mapv #(edn/read-string (slurp %)) *input*)' |\\\n    jet --to json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonneutert%2Fgit-hire","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonneutert%2Fgit-hire","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonneutert%2Fgit-hire/lists"}