/ README.adoc
README.adoc
1 // SPDX-License-Identifier: AGPL-3.0-or-later 2 = bitfuckit 3 :toc: macro 4 :toclevels: 3 5 :icons: font 6 :source-highlighter: rouge 7 8 *Fire-and-Fuck-GET (and more)* with Bitbucket. 9 10 Bitbucket CLI tool written in Ada. They didn't make it...so I did! 11 12 Bitbucket's answer to GitHub's `gh`, GitLab's `glab`, or Codeberg's `tea`. 13 14 image:https://img.shields.io/badge/language-Ada-blue[Ada] 15 image:https://img.shields.io/badge/SPARK-verified-green[SPARK] 16 image:https://img.shields.io/badge/GraphQL-API-e10098[GraphQL] 17 image:https://img.shields.io/badge/license-AGPL--3.0--or--later-blue[License] 18 19 toc::[] 20 21 == Overview 22 23 `bitfuckit` fills the gap Atlassian left: a proper command-line interface for Bitbucket. 24 While GitHub has `gh`, GitLab has `glab`, and Codeberg has `tea`, Bitbucket users have been left without an official CLI tool. 25 26 This project provides: 27 28 * Full Bitbucket repository management from the terminal 29 * Ada/SPARK implementation for reliability and correctness 30 * Interactive TUI mode with vim-style navigation 31 * **GraphQL API server** - everything the CLI can do, exposed as GraphQL 32 * Integration with forge-mirror for multi-forge workflows 33 34 == Features 35 36 === Authentication 37 * `auth login` - Authenticate with Bitbucket app password 38 * `auth status` - Show authentication status 39 40 === Repository Operations 41 * `repo create` - Create a new repository (public or private) 42 * `repo list` - List all repositories in workspace 43 * `repo delete` - Delete a repository (with confirmation) 44 * `repo exists` - Check if repository exists 45 46 === Mirroring 47 * `mirror` - Mirror a repository from GitHub to Bitbucket 48 49 === Interactive TUI 50 * Launch with no arguments or `bitfuckit tui` 51 * Vim-style navigation (j/k or arrows) 52 * Color-coded interface with box drawing 53 54 == Installation 55 56 === Prerequisites 57 58 [cols="1,3"] 59 |=== 60 |Component |Installation 61 62 |GNAT (Ada compiler) 63 |`sudo dnf install gcc-gnat` (Fedora) + 64 `sudo apt install gnat` (Debian/Ubuntu) 65 66 |GPRbuild 67 |`sudo dnf install gprbuild` (Fedora) + 68 `sudo apt install gprbuild` (Debian/Ubuntu) 69 70 |curl 71 |Usually pre-installed 72 |=== 73 74 === Build from Source 75 76 [source,bash] 77 ---- 78 git clone https://github.com/hyperpolymath/bitfuckit.git 79 cd bitfuckit 80 gprbuild -P bitfuckit.gpr 81 ---- 82 83 The binary will be in `bin/bitfuckit`. 84 85 === Install 86 87 [source,bash] 88 ---- 89 # User install 90 cp bin/bitfuckit ~/.local/bin/ 91 92 # System install 93 sudo cp bin/bitfuckit /usr/local/bin/ 94 ---- 95 96 === Packages 97 98 [cols="1,2,1"] 99 |=== 100 |Format |Command |Status 101 102 |Fedora/RHEL 103 |`sudo dnf install bitfuckit` 104 |Planned 105 106 |Debian/Ubuntu 107 |`sudo apt install bitfuckit` 108 |Planned 109 110 |Arch 111 |`yay -S bitfuckit` 112 |Planned 113 114 |Nix 115 |`nix-env -iA nixpkgs.bitfuckit` 116 |Planned 117 118 |Homebrew 119 |`brew install bitfuckit` 120 |Planned 121 |=== 122 123 == Usage 124 125 === Authentication 126 127 . Get an app password from https://bitbucket.org/account/settings/app-passwords/ 128 . Required permissions: 129 ** `repository:read` 130 ** `repository:write` 131 ** `repository:delete` 132 . Authenticate: 133 134 [source,bash] 135 ---- 136 bitfuckit auth login 137 # Enter username, app password, and workspace 138 ---- 139 140 === Repository Operations 141 142 [source,bash] 143 ---- 144 # Create repositories 145 bitfuckit repo create my-new-repo 146 bitfuckit repo create my-private-repo --private 147 bitfuckit repo create my-repo --description "My awesome project" 148 149 # List repositories 150 bitfuckit repo list 151 152 # Check if repository exists 153 bitfuckit repo exists my-repo 154 155 # Delete repository (requires confirmation) 156 bitfuckit repo delete my-repo 157 ---- 158 159 === Mirroring from GitHub 160 161 [source,bash] 162 ---- 163 # From within a git repository 164 cd my-github-repo 165 bitfuckit mirror my-repo 166 # Creates repo on Bitbucket if needed, pushes all branches 167 ---- 168 169 === Interactive TUI 170 171 [source,bash] 172 ---- 173 # Launch TUI 174 bitfuckit 175 # or 176 bitfuckit tui 177 ---- 178 179 TUI Controls: 180 181 * `j` / `↓` - Move down 182 * `k` / `↑` - Move up 183 * `Enter` - Select 184 * `q` / `Esc` - Quit 185 * Single-letter shortcuts (shown in brackets) 186 187 == Configuration 188 189 Credentials are stored in `~/.config/bitfuckit/config` 190 191 [source] 192 ---- 193 [credentials] 194 username=your-username 195 app_password=your-app-password 196 workspace=your-workspace 197 ---- 198 199 == Architecture 200 201 [source] 202 ---- 203 bitfuckit/ 204 ├── src/ 205 │ ├── bitfuckit.adb # Main CLI entry point 206 │ ├── config.ads/adb # Configuration & credential storage 207 │ ├── bitbucket_api.ads/adb # REST API client 208 │ ├── tui.ads/adb # Terminal UI (SPARK verified spec) 209 │ └── graphql_server.ads/adb # GraphQL API server 210 ├── graphql/ 211 │ └── schema.graphql # Full GraphQL schema 212 ├── bitfuckit.gpr # GPRbuild project file 213 └── bin/ # Build output 214 ---- 215 216 === SPARK Verification 217 218 The TUI specification (`tui.ads`) uses SPARK Mode for formal verification: 219 220 [source,ada] 221 ---- 222 package TUI 223 with SPARK_Mode => On 224 is 225 -- Formally verified interface 226 end TUI; 227 ---- 228 229 == GraphQL API 230 231 *Fire-and-Fuck-GET (and more)* - everything the CLI can do, the GraphQL API can do too. 232 233 === Starting the GraphQL Server 234 235 [source,bash] 236 ---- 237 # Start GraphQL server on default port 4000 238 bitfuckit graphql serve 239 240 # Custom port 241 bitfuckit graphql serve --port 8080 242 243 # With playground enabled 244 bitfuckit graphql serve --playground 245 ---- 246 247 === Example Queries 248 249 [source,graphql] 250 ---- 251 # List repositories 252 query { 253 repositories { 254 nodes { 255 slug 256 name 257 isPrivate 258 links { html } 259 } 260 } 261 } 262 263 # Create a repository 264 mutation { 265 createRepository(input: { 266 name: "my-new-repo" 267 isPrivate: true 268 description: "Created via GraphQL" 269 }) { 270 success 271 repository { 272 slug 273 links { html } 274 } 275 } 276 } 277 278 # Mirror from GitHub 279 mutation { 280 mirror(input: { 281 source: "https://github.com/user/repo" 282 targetName: "repo-mirror" 283 allBranches: true 284 }) { 285 success 286 branchesPushed 287 } 288 } 289 ---- 290 291 === CLI ↔ GraphQL Parity 292 293 Every CLI command has a GraphQL equivalent: 294 295 [cols="1,2"] 296 |=== 297 |CLI Command |GraphQL Operation 298 299 |`auth login` 300 |`mutation { login(...) }` 301 302 |`auth status` 303 |`query { authStatus }` 304 305 |`repo create` 306 |`mutation { createRepository(...) }` 307 308 |`repo list` 309 |`query { repositories }` 310 311 |`repo delete` 312 |`mutation { deleteRepository(...) }` 313 314 |`repo exists` 315 |`query { repositoryExists(...) }` 316 317 |`mirror` 318 |`mutation { mirror(...) }` 319 |=== 320 321 The full schema is in `graphql/schema.graphql`. 322 323 == Integration with forge-mirror 324 325 `bitfuckit` works seamlessly with the `forge-mirror` script for multi-forge workflows: 326 327 [source,bash] 328 ---- 329 # Check status of all forges 330 forge-mirror status 331 332 # Push to all forges including Bitbucket 333 forge-mirror push my-repo --forges github,gitlab,bitbucket,codeberg,radicle 334 ---- 335 336 == API Reference 337 338 === Bitbucket API v2.0 339 340 `bitfuckit` uses the Bitbucket REST API v2.0: 341 342 * Base URL: `https://api.bitbucket.org/2.0` 343 * Authentication: Basic Auth with app password 344 * Endpoints: 345 ** `GET /repositories/{workspace}` - List repos 346 ** `POST /repositories/{workspace}/{repo}` - Create repo 347 ** `DELETE /repositories/{workspace}/{repo}` - Delete repo 348 ** `GET /repositories/{workspace}/{repo}` - Get repo details 349 350 == Roadmap 351 352 === v0.1.0 (Current) 353 * [x] Authentication (login/status) 354 * [x] Repository CRUD operations 355 * [x] GitHub mirror 356 * [x] Interactive TUI 357 358 === v0.2.0 (Planned) 359 * [ ] Pull request management 360 * [ ] Issue tracking 361 * [ ] Pipeline status 362 * [ ] Webhook management 363 364 === v0.3.0 (Planned) 365 * [ ] Team management 366 * [ ] Branch permissions 367 * [ ] Deploy keys 368 * [ ] SSH key management 369 370 == Contributing 371 372 Contributions welcome! Please: 373 374 . Fork the repository 375 . Create a feature branch 376 . Ensure code compiles with GNAT 377 . Submit a pull request 378 379 == License 380 381 SPDX-License-Identifier: AGPL-3.0-or-later 382 383 Copyright (C) 2025 hyperpolymath 384 385 This program is free software: you can redistribute it and/or modify 386 it under the terms of the GNU Affero General Public License as published 387 by the Free Software Foundation, either version 3 of the License, or 388 (at your option) any later version. 389 390 == See Also 391 392 * https://bitbucket.org/account/settings/app-passwords/[Bitbucket App Passwords] 393 * https://developer.atlassian.com/cloud/bitbucket/rest/intro/[Bitbucket REST API] 394 * https://github.com/hyperpolymath/forge-mirror[forge-mirror] - Universal git forge mirror script