├── .ggConf.example.yaml ├── .github └── workflows │ └── label.yml ├── .gitignore ├── .travis.yml ├── Cargo.lock ├── Cargo.toml ├── Contributing.md ├── LICENSE ├── README.md ├── gifs ├── ggClone.cast ├── ggClone.gif ├── ggCreate.cast ├── ggCreate.gif ├── ggFetch.cast ├── ggFetch.gif ├── ggHelp.gif ├── ggStatus.cast ├── ggStatus.gif ├── gghelp.cast └── mgitstatus vs gg status.mp4 └── src ├── branches.rs ├── clone.rs ├── conf.rs ├── config.rs ├── create.rs ├── dir.rs ├── fetch.rs ├── git.rs ├── input_args.rs ├── main.rs ├── progress.rs └── status.rs /.ggConf.example.yaml: -------------------------------------------------------------------------------- 1 | # Rename this file to .ggConf.yaml 2 | 3 | # This will skip the directories while traversing 4 | #skipDirectories: 5 | # - ignore 6 | 7 | # This will clone the repos from the given URL's into the given local paths 8 | #cloneRepos: 9 | # - remoteURL: https://github.com/golang/net.git 10 | # localPath: here/net 11 | # - remoteURL: https://github.com/golang/net.git 12 | # localPath: there/net 13 | # 14 | 15 | # This configures the ssh config used to access repositories. Use `ssh_agent: true` to let git agent take care of config. 16 | # ssh: 17 | # privateKey: '/home/ninan/.ssh/gg' 18 | # username: 'git' 19 | # ssh_agent: false 20 | -------------------------------------------------------------------------------- /.github/workflows/label.yml: -------------------------------------------------------------------------------- 1 | # This workflow will triage pull requests and apply a label based on the 2 | # paths that are modified in the pull request. 3 | # 4 | # To use this workflow, you will need to set up a .github/labeler.yml 5 | # file with configuration. For more information, see: 6 | # https://github.com/actions/labeler/blob/master/README.md 7 | 8 | name: Labeler 9 | on: [pull_request] 10 | 11 | jobs: 12 | label: 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/labeler@v2 18 | with: 19 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target 3 | **/*.rs.bk 4 | 5 | .idea/ 6 | *.iml 7 | *.tar.gz 8 | gg 9 | 10 | .talismanrc 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: required 3 | env: 4 | global: 5 | - PROJECT_NAME=gg 6 | matrix: 7 | fast_finish: true 8 | include: 9 | - os: linux 10 | rust: nightly 11 | env: TARGET=x86_64-linux 12 | - os: osx 13 | rust: nightly 14 | env: TARGET=x86_64-darwin 15 | script: 16 | - date 17 | - cargo test 18 | before_deploy: 19 | - git clean -fdx . 20 | - cargo build --release 21 | - mv ./target/release/gg . 22 | - tar cvfz $PROJECT_NAME-$TRAVIS_TAG-$TARGET.tar.gz ./gg 23 | - PREVIOUS_TAG=$(git tag | tail -2 | head -1) 24 | - echo 'Changelog:' 25 | - git log ${PREVIOUS_TAG}..${TRAVIS_TAG} --oneline 26 | - export GITHUB_RELEASE_NAME="v${TRAVIS_TAG}" 27 | deploy: 28 | - provider: releases 29 | api_key: 30 | secure: bYV0M05yNa9+mIKJUcruPE1uLVkXVIDOce/Aid7kHI/U8mokgXEa/aSnZvX0nlDfUCAUKYt8Idp+eojvGkt3zXDg8OC+K0EvcxMgLBx2NDW+gx/eaPbNmGkYf0pFR32crpBcdfkAdWChtdwVifiZmehavSoz7hij+I5jAowaAN4iuvZyJ8tOw/TQf8oGTA7nBW1FEtnrcqU14rXzs3aGDlU2j8F6kR++P83uwEf8Fzagi6Y66RhjKcD25j6PZI16hKqJeVh6qt9ugD3pDn0V/rTxs15uy5ISlvtadvp/GwiQOrAsiZ7q7sb0EfPbnqBxZCXeqTzFaNtvLLeUHXBbz2vnMk5IBPGdUraLqrtlhJRQUJcNkkdDYd5n1yeof2/x1SRyZqiekbG6v3bYaXxpTWIuOnovyqyNwngGkv5DdzbWwS1xhzCufryeQqDMNjacLeUMAyyxXUHIWHYfwgV31b4O0FyfLr0IIL8duxMsPY2hdzPjooNZ6kOs+x9D9XEaNlxiHtPyjhnOqWAQ590t8gFz0nqseJTV19tkkous37JfmjEwzaLOsbG5neamZKKtQJ62VCKSSTnEB0M152F833gb28G/gARV/40hN50TMGodT35KTZmGUDsAFBhkyd9jqlR/1RJbDZgaOe+YdEmb/IxHh0sSEwA3uqOidZQwmak= 31 | file: "$PROJECT_NAME-$TRAVIS_TAG-$TARGET.tar.gz" 32 | skip_cleanup: true 33 | on: 34 | tags: true 35 | repo: thecasualcoder/gg 36 | condition: $TRAVIS_RUST_VERSION = stable && $TARGET != "" 37 | - provider: cargo 38 | token: 39 | secure: I2EkMJeIMaMm9MpgYK1h4Bv0qFQb2MgAEdEo4YyPmqM8SolPv1/wk/RTFmBGbYzIdh+yQC5p2p+ap2cVVmuBaDoP1r50Jo+28m2vbo2+NnHntM7EsTSkyJHJG//NsMqaIyyR9+o8VyYb8JgAXErP8aLCqrIhurwbf2Qq8O/NSD3axgSGB6y63htOQ2iQmXwiRd5+A52Nyyg5cD/qLl9sQzjHdey1UTi6NsLWz2FmTmIzI/Rj4/KOODPZ1xR6ONFER+pmMl2iIM0I4t8vTmVGWJBtcU2keEfm+Q7TRbBtHQKBg2K2t7xNciK5hrDD2bfSw21YIBzNC+Pg46HKWqMN0q9JbbZL20NzzArqql2PLsFer9WX6oLKHV4RE1NWp5chUMSixefqH0Kg6UdmNPGmBJfWliQN+cCiQvBzJ164Zs/1w5D1hKjOrYxZeIbk3Jk8/g6GED6eUwBeWMeuyGVJUdSUQ2low37si5RN1t3RcgZuL5ij9woLK2lgBL2D2mQS8ZB0fo5G/UigTYs9112gFOdAfUAOEOcmIkIb46/NOv890Bi1Jj1ejOqFNYlTuKs0Xw0+kyepi+1VatuMLZK5Fu2+RTXeZGjl+6SOM6Y2oM22Txb4sxdkIKkTFUGce4w3xesVRGCCKT1O9uEFCZQ7HCVlK6qbcxXP8ghKDGeuj0A= 40 | skip_cleanup: true 41 | on: 42 | tags: true 43 | repo: thecasualcoder/gg 44 | condition: $TRAVIS_RUST_VERSION = stable && $TARGET != "" -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "adler32" 5 | version = "1.0.4" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | 8 | [[package]] 9 | name = "aho-corasick" 10 | version = "0.7.10" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | dependencies = [ 13 | "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 14 | ] 15 | 16 | [[package]] 17 | name = "ansi_term" 18 | version = "0.11.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | dependencies = [ 21 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 22 | ] 23 | 24 | [[package]] 25 | name = "atty" 26 | version = "0.2.14" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | dependencies = [ 29 | "hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 30 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 31 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 32 | ] 33 | 34 | [[package]] 35 | name = "autocfg" 36 | version = "0.1.7" 37 | source = "registry+https://github.com/rust-lang/crates.io-index" 38 | 39 | [[package]] 40 | name = "autocfg" 41 | version = "1.0.0" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | 44 | [[package]] 45 | name = "backtrace" 46 | version = "0.3.46" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | dependencies = [ 49 | "backtrace-sys 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", 50 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 51 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 52 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 53 | ] 54 | 55 | [[package]] 56 | name = "backtrace-sys" 57 | version = "0.1.37" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | dependencies = [ 60 | "cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 61 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 62 | ] 63 | 64 | [[package]] 65 | name = "base64" 66 | version = "0.10.1" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | dependencies = [ 69 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 70 | ] 71 | 72 | [[package]] 73 | name = "bitflags" 74 | version = "1.2.1" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | 77 | [[package]] 78 | name = "byteorder" 79 | version = "1.3.4" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | 82 | [[package]] 83 | name = "bytes" 84 | version = "0.4.12" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | dependencies = [ 87 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 90 | ] 91 | 92 | [[package]] 93 | name = "cc" 94 | version = "1.0.52" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | dependencies = [ 97 | "jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 98 | ] 99 | 100 | [[package]] 101 | name = "cfg-if" 102 | version = "0.1.10" 103 | source = "registry+https://github.com/rust-lang/crates.io-index" 104 | 105 | [[package]] 106 | name = "clap" 107 | version = "2.33.0" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | dependencies = [ 110 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 111 | "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 112 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 114 | "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 115 | "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 116 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 117 | ] 118 | 119 | [[package]] 120 | name = "cloudabi" 121 | version = "0.0.3" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | dependencies = [ 124 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 125 | ] 126 | 127 | [[package]] 128 | name = "colored" 129 | version = "1.9.3" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | dependencies = [ 132 | "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", 133 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 134 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 135 | ] 136 | 137 | [[package]] 138 | name = "console" 139 | version = "0.11.2" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | dependencies = [ 142 | "encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 143 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 145 | "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 146 | "terminal_size 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 147 | "termios 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 148 | "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 149 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 150 | "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 151 | ] 152 | 153 | [[package]] 154 | name = "cookie" 155 | version = "0.12.0" 156 | source = "registry+https://github.com/rust-lang/crates.io-index" 157 | dependencies = [ 158 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 159 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 160 | ] 161 | 162 | [[package]] 163 | name = "cookie_store" 164 | version = "0.7.0" 165 | source = "registry+https://github.com/rust-lang/crates.io-index" 166 | dependencies = [ 167 | "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 168 | "failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 169 | "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 171 | "publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 172 | "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 173 | "serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 174 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 175 | "try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 176 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 177 | ] 178 | 179 | [[package]] 180 | name = "core-foundation" 181 | version = "0.7.0" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | dependencies = [ 184 | "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 185 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 186 | ] 187 | 188 | [[package]] 189 | name = "core-foundation-sys" 190 | version = "0.7.0" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | 193 | [[package]] 194 | name = "crc32fast" 195 | version = "1.2.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | dependencies = [ 198 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 199 | ] 200 | 201 | [[package]] 202 | name = "crossbeam-deque" 203 | version = "0.7.3" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | dependencies = [ 206 | "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 207 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 208 | "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 209 | ] 210 | 211 | [[package]] 212 | name = "crossbeam-epoch" 213 | version = "0.8.2" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | dependencies = [ 216 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 217 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 218 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 219 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 220 | "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 221 | "memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 222 | "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 223 | ] 224 | 225 | [[package]] 226 | name = "crossbeam-queue" 227 | version = "0.2.1" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | dependencies = [ 230 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 231 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 232 | ] 233 | 234 | [[package]] 235 | name = "crossbeam-utils" 236 | version = "0.7.2" 237 | source = "registry+https://github.com/rust-lang/crates.io-index" 238 | dependencies = [ 239 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 240 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 241 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 242 | ] 243 | 244 | [[package]] 245 | name = "dtoa" 246 | version = "0.4.5" 247 | source = "registry+https://github.com/rust-lang/crates.io-index" 248 | 249 | [[package]] 250 | name = "either" 251 | version = "1.5.3" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | 254 | [[package]] 255 | name = "encode_unicode" 256 | version = "0.3.6" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | 259 | [[package]] 260 | name = "encoding_rs" 261 | version = "0.8.22" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | dependencies = [ 264 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 265 | ] 266 | 267 | [[package]] 268 | name = "error-chain" 269 | version = "0.12.2" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | dependencies = [ 272 | "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 273 | ] 274 | 275 | [[package]] 276 | name = "failure" 277 | version = "0.1.8" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | dependencies = [ 280 | "backtrace 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)", 281 | "failure_derive 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 282 | ] 283 | 284 | [[package]] 285 | name = "failure_derive" 286 | version = "0.1.8" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | dependencies = [ 289 | "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 290 | "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 291 | "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", 292 | "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 293 | ] 294 | 295 | [[package]] 296 | name = "flate2" 297 | version = "1.0.14" 298 | source = "registry+https://github.com/rust-lang/crates.io-index" 299 | dependencies = [ 300 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 301 | "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 302 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 303 | "miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 304 | ] 305 | 306 | [[package]] 307 | name = "fnv" 308 | version = "1.0.6" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | 311 | [[package]] 312 | name = "foreign-types" 313 | version = "0.3.2" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | dependencies = [ 316 | "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 317 | ] 318 | 319 | [[package]] 320 | name = "foreign-types-shared" 321 | version = "0.1.1" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | 324 | [[package]] 325 | name = "fuchsia-cprng" 326 | version = "0.1.1" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | 329 | [[package]] 330 | name = "fuchsia-zircon" 331 | version = "0.3.3" 332 | source = "registry+https://github.com/rust-lang/crates.io-index" 333 | dependencies = [ 334 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 335 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 336 | ] 337 | 338 | [[package]] 339 | name = "fuchsia-zircon-sys" 340 | version = "0.3.3" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | 343 | [[package]] 344 | name = "futures" 345 | version = "0.1.29" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | 348 | [[package]] 349 | name = "futures-cpupool" 350 | version = "0.1.8" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | dependencies = [ 353 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 354 | "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 355 | ] 356 | 357 | [[package]] 358 | name = "getrandom" 359 | version = "0.1.14" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | dependencies = [ 362 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 363 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 364 | "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)", 365 | ] 366 | 367 | [[package]] 368 | name = "git-governance" 369 | version = "0.3.2" 370 | dependencies = [ 371 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", 374 | "indicatif 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", 375 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 376 | "mockers 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", 377 | "mockers_derive 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", 378 | "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 380 | "reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 382 | "serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 385 | ] 386 | 387 | [[package]] 388 | name = "git2" 389 | version = "0.10.2" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | dependencies = [ 392 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 393 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 394 | "libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", 395 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 396 | "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 397 | "openssl-sys 0.9.55 (registry+https://github.com/rust-lang/crates.io-index)", 398 | "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 399 | ] 400 | 401 | [[package]] 402 | name = "h2" 403 | version = "0.1.26" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | dependencies = [ 406 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 407 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 408 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 409 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 410 | "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 411 | "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 412 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 413 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 415 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 416 | ] 417 | 418 | [[package]] 419 | name = "hermit-abi" 420 | version = "0.1.12" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | dependencies = [ 423 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 424 | ] 425 | 426 | [[package]] 427 | name = "http" 428 | version = "0.1.21" 429 | source = "registry+https://github.com/rust-lang/crates.io-index" 430 | dependencies = [ 431 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 432 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 433 | "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 434 | ] 435 | 436 | [[package]] 437 | name = "http-body" 438 | version = "0.1.0" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | dependencies = [ 441 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 442 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 443 | "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 444 | "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 445 | ] 446 | 447 | [[package]] 448 | name = "httparse" 449 | version = "1.3.4" 450 | source = "registry+https://github.com/rust-lang/crates.io-index" 451 | 452 | [[package]] 453 | name = "hyper" 454 | version = "0.12.35" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | dependencies = [ 457 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 458 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 459 | "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 460 | "h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", 461 | "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 462 | "http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 463 | "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 464 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 465 | "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 466 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 467 | "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", 468 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 469 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 470 | "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", 471 | "tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 472 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 473 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 474 | "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 475 | "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 476 | "tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 477 | "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 478 | "want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 479 | ] 480 | 481 | [[package]] 482 | name = "hyper-tls" 483 | version = "0.3.2" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | dependencies = [ 486 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 487 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 488 | "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", 489 | "native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 490 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 491 | ] 492 | 493 | [[package]] 494 | name = "idna" 495 | version = "0.1.5" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | dependencies = [ 498 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 499 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 500 | "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 501 | ] 502 | 503 | [[package]] 504 | name = "idna" 505 | version = "0.2.0" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | dependencies = [ 508 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 509 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 510 | "unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 511 | ] 512 | 513 | [[package]] 514 | name = "indexmap" 515 | version = "1.3.2" 516 | source = "registry+https://github.com/rust-lang/crates.io-index" 517 | dependencies = [ 518 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 519 | ] 520 | 521 | [[package]] 522 | name = "indicatif" 523 | version = "0.14.0" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | dependencies = [ 526 | "console 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)", 527 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 528 | "number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 529 | "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 530 | ] 531 | 532 | [[package]] 533 | name = "indoc" 534 | version = "0.3.5" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | dependencies = [ 537 | "indoc-impl 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 538 | "proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)", 539 | ] 540 | 541 | [[package]] 542 | name = "indoc-impl" 543 | version = "0.3.5" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | dependencies = [ 546 | "proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)", 547 | "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 548 | "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 549 | "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", 550 | "unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 551 | ] 552 | 553 | [[package]] 554 | name = "iovec" 555 | version = "0.1.4" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | dependencies = [ 558 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 559 | ] 560 | 561 | [[package]] 562 | name = "itertools" 563 | version = "0.4.19" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | 566 | [[package]] 567 | name = "itertools" 568 | version = "0.8.2" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | dependencies = [ 571 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 572 | ] 573 | 574 | [[package]] 575 | name = "itoa" 576 | version = "0.4.5" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | 579 | [[package]] 580 | name = "jobserver" 581 | version = "0.1.21" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | dependencies = [ 584 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 585 | ] 586 | 587 | [[package]] 588 | name = "kernel32-sys" 589 | version = "0.2.2" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | dependencies = [ 592 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 593 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 594 | ] 595 | 596 | [[package]] 597 | name = "lazy_static" 598 | version = "0.2.11" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | 601 | [[package]] 602 | name = "lazy_static" 603 | version = "1.4.0" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | 606 | [[package]] 607 | name = "libc" 608 | version = "0.2.69" 609 | source = "registry+https://github.com/rust-lang/crates.io-index" 610 | 611 | [[package]] 612 | name = "libgit2-sys" 613 | version = "0.9.2" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | dependencies = [ 616 | "cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 617 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 618 | "libssh2-sys 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", 619 | "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 620 | "openssl-sys 0.9.55 (registry+https://github.com/rust-lang/crates.io-index)", 621 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 622 | ] 623 | 624 | [[package]] 625 | name = "libssh2-sys" 626 | version = "0.2.17" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | dependencies = [ 629 | "cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 630 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 631 | "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 632 | "openssl-sys 0.9.55 (registry+https://github.com/rust-lang/crates.io-index)", 633 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 634 | "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 635 | ] 636 | 637 | [[package]] 638 | name = "libz-sys" 639 | version = "1.0.25" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | dependencies = [ 642 | "cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 643 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 644 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 645 | "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 646 | ] 647 | 648 | [[package]] 649 | name = "linked-hash-map" 650 | version = "0.5.2" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | 653 | [[package]] 654 | name = "lock_api" 655 | version = "0.3.4" 656 | source = "registry+https://github.com/rust-lang/crates.io-index" 657 | dependencies = [ 658 | "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 659 | ] 660 | 661 | [[package]] 662 | name = "log" 663 | version = "0.4.8" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | dependencies = [ 666 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 667 | ] 668 | 669 | [[package]] 670 | name = "matches" 671 | version = "0.1.8" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | 674 | [[package]] 675 | name = "maybe-uninit" 676 | version = "2.0.0" 677 | source = "registry+https://github.com/rust-lang/crates.io-index" 678 | 679 | [[package]] 680 | name = "memchr" 681 | version = "2.3.3" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | 684 | [[package]] 685 | name = "memoffset" 686 | version = "0.5.4" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | dependencies = [ 689 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 690 | ] 691 | 692 | [[package]] 693 | name = "mime" 694 | version = "0.3.16" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | 697 | [[package]] 698 | name = "mime_guess" 699 | version = "2.0.3" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | dependencies = [ 702 | "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 703 | "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 704 | ] 705 | 706 | [[package]] 707 | name = "miniz_oxide" 708 | version = "0.3.6" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | dependencies = [ 711 | "adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 712 | ] 713 | 714 | [[package]] 715 | name = "mio" 716 | version = "0.6.22" 717 | source = "registry+https://github.com/rust-lang/crates.io-index" 718 | dependencies = [ 719 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 720 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 721 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 722 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 723 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 724 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 725 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 726 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 727 | "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", 728 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 729 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 730 | ] 731 | 732 | [[package]] 733 | name = "miow" 734 | version = "0.2.1" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | dependencies = [ 737 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 738 | "net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", 739 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 740 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 741 | ] 742 | 743 | [[package]] 744 | name = "mockers" 745 | version = "0.21.0" 746 | source = "registry+https://github.com/rust-lang/crates.io-index" 747 | dependencies = [ 748 | "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 749 | "select-rustc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 750 | ] 751 | 752 | [[package]] 753 | name = "mockers_derive" 754 | version = "0.21.0" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | dependencies = [ 757 | "indoc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 758 | "itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)", 759 | "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 760 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 761 | "proc-quote 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 762 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 763 | ] 764 | 765 | [[package]] 766 | name = "native-tls" 767 | version = "0.2.4" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | dependencies = [ 770 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 771 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 772 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 773 | "openssl 0.10.29 (registry+https://github.com/rust-lang/crates.io-index)", 774 | "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 775 | "openssl-sys 0.9.55 (registry+https://github.com/rust-lang/crates.io-index)", 776 | "schannel 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 777 | "security-framework 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 778 | "security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 779 | "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 780 | ] 781 | 782 | [[package]] 783 | name = "net2" 784 | version = "0.2.34" 785 | source = "registry+https://github.com/rust-lang/crates.io-index" 786 | dependencies = [ 787 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 788 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 789 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 790 | ] 791 | 792 | [[package]] 793 | name = "num_cpus" 794 | version = "1.13.0" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | dependencies = [ 797 | "hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 798 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 799 | ] 800 | 801 | [[package]] 802 | name = "number_prefix" 803 | version = "0.3.0" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | 806 | [[package]] 807 | name = "openssl" 808 | version = "0.10.29" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | dependencies = [ 811 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 812 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 813 | "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 814 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 815 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 816 | "openssl-sys 0.9.55 (registry+https://github.com/rust-lang/crates.io-index)", 817 | ] 818 | 819 | [[package]] 820 | name = "openssl-probe" 821 | version = "0.1.2" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | 824 | [[package]] 825 | name = "openssl-sys" 826 | version = "0.9.55" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | dependencies = [ 829 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 830 | "cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 831 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 832 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 833 | "vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 834 | ] 835 | 836 | [[package]] 837 | name = "parking_lot" 838 | version = "0.9.0" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | dependencies = [ 841 | "lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 842 | "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 843 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 844 | ] 845 | 846 | [[package]] 847 | name = "parking_lot_core" 848 | version = "0.6.2" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | dependencies = [ 851 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 852 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 853 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 854 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 855 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 856 | "smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 857 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 858 | ] 859 | 860 | [[package]] 861 | name = "percent-encoding" 862 | version = "1.0.1" 863 | source = "registry+https://github.com/rust-lang/crates.io-index" 864 | 865 | [[package]] 866 | name = "percent-encoding" 867 | version = "2.1.0" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | 870 | [[package]] 871 | name = "pkg-config" 872 | version = "0.3.17" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | 875 | [[package]] 876 | name = "ppv-lite86" 877 | version = "0.2.6" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | 880 | [[package]] 881 | name = "proc-macro-hack" 882 | version = "0.5.15" 883 | source = "registry+https://github.com/rust-lang/crates.io-index" 884 | 885 | [[package]] 886 | name = "proc-macro2" 887 | version = "0.4.30" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | dependencies = [ 890 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 891 | ] 892 | 893 | [[package]] 894 | name = "proc-macro2" 895 | version = "1.0.12" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | dependencies = [ 898 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 899 | ] 900 | 901 | [[package]] 902 | name = "proc-quote" 903 | version = "0.2.2" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | dependencies = [ 906 | "proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)", 907 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 908 | "proc-quote-impl 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 909 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 910 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 911 | ] 912 | 913 | [[package]] 914 | name = "proc-quote-impl" 915 | version = "0.2.2" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | dependencies = [ 918 | "proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)", 919 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 920 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 921 | ] 922 | 923 | [[package]] 924 | name = "publicsuffix" 925 | version = "1.5.4" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | dependencies = [ 928 | "error-chain 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", 929 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 930 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 931 | "regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 932 | "url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 933 | ] 934 | 935 | [[package]] 936 | name = "quote" 937 | version = "0.6.13" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | dependencies = [ 940 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 941 | ] 942 | 943 | [[package]] 944 | name = "quote" 945 | version = "1.0.4" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | dependencies = [ 948 | "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 949 | ] 950 | 951 | [[package]] 952 | name = "rand" 953 | version = "0.6.5" 954 | source = "registry+https://github.com/rust-lang/crates.io-index" 955 | dependencies = [ 956 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 957 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 958 | "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 959 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 960 | "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 961 | "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 962 | "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 963 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 964 | "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 965 | "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 966 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 967 | ] 968 | 969 | [[package]] 970 | name = "rand" 971 | version = "0.7.3" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | dependencies = [ 974 | "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 975 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 976 | "rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 977 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 978 | "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 979 | ] 980 | 981 | [[package]] 982 | name = "rand_chacha" 983 | version = "0.1.1" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | dependencies = [ 986 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 987 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 988 | ] 989 | 990 | [[package]] 991 | name = "rand_chacha" 992 | version = "0.2.2" 993 | source = "registry+https://github.com/rust-lang/crates.io-index" 994 | dependencies = [ 995 | "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 996 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 997 | ] 998 | 999 | [[package]] 1000 | name = "rand_core" 1001 | version = "0.3.1" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | dependencies = [ 1004 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1005 | ] 1006 | 1007 | [[package]] 1008 | name = "rand_core" 1009 | version = "0.4.2" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | 1012 | [[package]] 1013 | name = "rand_core" 1014 | version = "0.5.1" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | dependencies = [ 1017 | "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "rand_hc" 1022 | version = "0.1.0" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | dependencies = [ 1025 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1026 | ] 1027 | 1028 | [[package]] 1029 | name = "rand_hc" 1030 | version = "0.2.0" 1031 | source = "registry+https://github.com/rust-lang/crates.io-index" 1032 | dependencies = [ 1033 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "rand_isaac" 1038 | version = "0.1.1" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | dependencies = [ 1041 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "rand_jitter" 1046 | version = "0.1.4" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | dependencies = [ 1049 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1050 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1051 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1052 | ] 1053 | 1054 | [[package]] 1055 | name = "rand_os" 1056 | version = "0.1.3" 1057 | source = "registry+https://github.com/rust-lang/crates.io-index" 1058 | dependencies = [ 1059 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 1060 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1061 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1062 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1063 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1064 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "rand_pcg" 1069 | version = "0.1.2" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | dependencies = [ 1072 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1073 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "rand_xorshift" 1078 | version = "0.1.1" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | dependencies = [ 1081 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "rayon" 1086 | version = "1.3.0" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | dependencies = [ 1089 | "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1090 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1091 | "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1092 | ] 1093 | 1094 | [[package]] 1095 | name = "rayon-core" 1096 | version = "1.7.0" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | dependencies = [ 1099 | "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1100 | "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1101 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1102 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1103 | "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "rdrand" 1108 | version = "0.4.0" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | dependencies = [ 1111 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "redox_syscall" 1116 | version = "0.1.56" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | 1119 | [[package]] 1120 | name = "regex" 1121 | version = "1.3.7" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | dependencies = [ 1124 | "aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)", 1125 | "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 1126 | "regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)", 1127 | "thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "regex-syntax" 1132 | version = "0.6.17" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | 1135 | [[package]] 1136 | name = "remove_dir_all" 1137 | version = "0.5.2" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | dependencies = [ 1140 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1141 | ] 1142 | 1143 | [[package]] 1144 | name = "reqwest" 1145 | version = "0.9.24" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | dependencies = [ 1148 | "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1149 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1150 | "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 1151 | "cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1152 | "encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)", 1153 | "flate2 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)", 1154 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1155 | "http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)", 1156 | "hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)", 1157 | "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1158 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1159 | "mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 1160 | "mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 1161 | "native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 1162 | "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 1163 | "serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)", 1164 | "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", 1165 | "time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 1166 | "tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)", 1167 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1168 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1169 | "tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 1170 | "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 1171 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1172 | "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", 1173 | "winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", 1174 | ] 1175 | 1176 | [[package]] 1177 | name = "rustc-demangle" 1178 | version = "0.1.16" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | 1181 | [[package]] 1182 | name = "rustc_version" 1183 | version = "0.2.3" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | dependencies = [ 1186 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1187 | ] 1188 | 1189 | [[package]] 1190 | name = "ryu" 1191 | version = "1.0.4" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | 1194 | [[package]] 1195 | name = "same-file" 1196 | version = "1.0.6" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | dependencies = [ 1199 | "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1200 | ] 1201 | 1202 | [[package]] 1203 | name = "schannel" 1204 | version = "0.1.18" 1205 | source = "registry+https://github.com/rust-lang/crates.io-index" 1206 | dependencies = [ 1207 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1208 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "scopeguard" 1213 | version = "1.1.0" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | 1216 | [[package]] 1217 | name = "security-framework" 1218 | version = "0.4.3" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | dependencies = [ 1221 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1222 | "core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1223 | "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1224 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1225 | "security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1226 | ] 1227 | 1228 | [[package]] 1229 | name = "security-framework-sys" 1230 | version = "0.4.3" 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" 1232 | dependencies = [ 1233 | "core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1234 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "select-rustc" 1239 | version = "0.1.2" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | dependencies = [ 1242 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1243 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1244 | "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "semver" 1249 | version = "0.9.0" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | dependencies = [ 1252 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1253 | ] 1254 | 1255 | [[package]] 1256 | name = "semver-parser" 1257 | version = "0.7.0" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | 1260 | [[package]] 1261 | name = "serde" 1262 | version = "1.0.106" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | dependencies = [ 1265 | "serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "serde_derive" 1270 | version = "1.0.106" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | dependencies = [ 1273 | "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 1274 | "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1275 | "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", 1276 | ] 1277 | 1278 | [[package]] 1279 | name = "serde_json" 1280 | version = "1.0.52" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | dependencies = [ 1283 | "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 1284 | "ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1285 | "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 1286 | ] 1287 | 1288 | [[package]] 1289 | name = "serde_urlencoded" 1290 | version = "0.5.5" 1291 | source = "registry+https://github.com/rust-lang/crates.io-index" 1292 | dependencies = [ 1293 | "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 1294 | "itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 1295 | "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 1296 | "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1297 | ] 1298 | 1299 | [[package]] 1300 | name = "serde_yaml" 1301 | version = "0.8.11" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | dependencies = [ 1304 | "dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", 1305 | "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1306 | "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)", 1307 | "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "slab" 1312 | version = "0.4.2" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | 1315 | [[package]] 1316 | name = "smallvec" 1317 | version = "0.6.13" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | dependencies = [ 1320 | "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "smallvec" 1325 | version = "1.4.0" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | 1328 | [[package]] 1329 | name = "string" 1330 | version = "0.2.1" 1331 | source = "registry+https://github.com/rust-lang/crates.io-index" 1332 | dependencies = [ 1333 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "strsim" 1338 | version = "0.8.0" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | 1341 | [[package]] 1342 | name = "syn" 1343 | version = "0.15.44" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | dependencies = [ 1346 | "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", 1347 | "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", 1348 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1349 | ] 1350 | 1351 | [[package]] 1352 | name = "syn" 1353 | version = "1.0.18" 1354 | source = "registry+https://github.com/rust-lang/crates.io-index" 1355 | dependencies = [ 1356 | "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 1357 | "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1358 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1359 | ] 1360 | 1361 | [[package]] 1362 | name = "synstructure" 1363 | version = "0.12.3" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | dependencies = [ 1366 | "proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 1367 | "quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 1368 | "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", 1369 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1370 | ] 1371 | 1372 | [[package]] 1373 | name = "tempfile" 1374 | version = "3.1.0" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | dependencies = [ 1377 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1378 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1379 | "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1380 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1381 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1382 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1383 | ] 1384 | 1385 | [[package]] 1386 | name = "terminal_size" 1387 | version = "0.1.12" 1388 | source = "registry+https://github.com/rust-lang/crates.io-index" 1389 | dependencies = [ 1390 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1391 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1392 | ] 1393 | 1394 | [[package]] 1395 | name = "termios" 1396 | version = "0.3.2" 1397 | source = "registry+https://github.com/rust-lang/crates.io-index" 1398 | dependencies = [ 1399 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1400 | ] 1401 | 1402 | [[package]] 1403 | name = "textwrap" 1404 | version = "0.11.0" 1405 | source = "registry+https://github.com/rust-lang/crates.io-index" 1406 | dependencies = [ 1407 | "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1408 | ] 1409 | 1410 | [[package]] 1411 | name = "thread_local" 1412 | version = "1.0.1" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | dependencies = [ 1415 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1416 | ] 1417 | 1418 | [[package]] 1419 | name = "time" 1420 | version = "0.1.43" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | dependencies = [ 1423 | "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", 1424 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "tokio" 1429 | version = "0.1.22" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | dependencies = [ 1432 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1433 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1434 | "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", 1435 | "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 1436 | "tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1437 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1438 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1439 | "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1440 | "tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1441 | "tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", 1442 | "tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 1443 | ] 1444 | 1445 | [[package]] 1446 | name = "tokio-buf" 1447 | version = "0.1.1" 1448 | source = "registry+https://github.com/rust-lang/crates.io-index" 1449 | dependencies = [ 1450 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1451 | "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1452 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1453 | ] 1454 | 1455 | [[package]] 1456 | name = "tokio-current-thread" 1457 | version = "0.1.7" 1458 | source = "registry+https://github.com/rust-lang/crates.io-index" 1459 | dependencies = [ 1460 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1461 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "tokio-executor" 1466 | version = "0.1.10" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | dependencies = [ 1469 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1470 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "tokio-io" 1475 | version = "0.1.13" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | dependencies = [ 1478 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1479 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1480 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1481 | ] 1482 | 1483 | [[package]] 1484 | name = "tokio-reactor" 1485 | version = "0.1.12" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | dependencies = [ 1488 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1489 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1490 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1491 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1492 | "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", 1493 | "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 1494 | "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1495 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1496 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1497 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1498 | "tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1499 | ] 1500 | 1501 | [[package]] 1502 | name = "tokio-sync" 1503 | version = "0.1.8" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | dependencies = [ 1506 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1507 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1508 | ] 1509 | 1510 | [[package]] 1511 | name = "tokio-tcp" 1512 | version = "0.1.4" 1513 | source = "registry+https://github.com/rust-lang/crates.io-index" 1514 | dependencies = [ 1515 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1516 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1517 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1518 | "mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)", 1519 | "tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1520 | "tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 1521 | ] 1522 | 1523 | [[package]] 1524 | name = "tokio-threadpool" 1525 | version = "0.1.18" 1526 | source = "registry+https://github.com/rust-lang/crates.io-index" 1527 | dependencies = [ 1528 | "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1529 | "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1530 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1531 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1532 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1533 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1534 | "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 1535 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1536 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1537 | ] 1538 | 1539 | [[package]] 1540 | name = "tokio-timer" 1541 | version = "0.2.13" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | dependencies = [ 1544 | "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1545 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1546 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1547 | "tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "try-lock" 1552 | version = "0.2.2" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | 1555 | [[package]] 1556 | name = "try_from" 1557 | version = "0.3.2" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | dependencies = [ 1560 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1561 | ] 1562 | 1563 | [[package]] 1564 | name = "unicase" 1565 | version = "2.6.0" 1566 | source = "registry+https://github.com/rust-lang/crates.io-index" 1567 | dependencies = [ 1568 | "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 1569 | ] 1570 | 1571 | [[package]] 1572 | name = "unicode-bidi" 1573 | version = "0.3.4" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | dependencies = [ 1576 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "unicode-normalization" 1581 | version = "0.1.12" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | dependencies = [ 1584 | "smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1585 | ] 1586 | 1587 | [[package]] 1588 | name = "unicode-width" 1589 | version = "0.1.7" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | 1592 | [[package]] 1593 | name = "unicode-xid" 1594 | version = "0.1.0" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | 1597 | [[package]] 1598 | name = "unicode-xid" 1599 | version = "0.2.0" 1600 | source = "registry+https://github.com/rust-lang/crates.io-index" 1601 | 1602 | [[package]] 1603 | name = "unindent" 1604 | version = "0.1.5" 1605 | source = "registry+https://github.com/rust-lang/crates.io-index" 1606 | 1607 | [[package]] 1608 | name = "url" 1609 | version = "1.7.2" 1610 | source = "registry+https://github.com/rust-lang/crates.io-index" 1611 | dependencies = [ 1612 | "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1613 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1614 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1615 | ] 1616 | 1617 | [[package]] 1618 | name = "url" 1619 | version = "2.1.1" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | dependencies = [ 1622 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1623 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1624 | "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1625 | ] 1626 | 1627 | [[package]] 1628 | name = "uuid" 1629 | version = "0.7.4" 1630 | source = "registry+https://github.com/rust-lang/crates.io-index" 1631 | dependencies = [ 1632 | "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 1633 | ] 1634 | 1635 | [[package]] 1636 | name = "vcpkg" 1637 | version = "0.2.8" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | 1640 | [[package]] 1641 | name = "vec_map" 1642 | version = "0.8.1" 1643 | source = "registry+https://github.com/rust-lang/crates.io-index" 1644 | 1645 | [[package]] 1646 | name = "version_check" 1647 | version = "0.9.1" 1648 | source = "registry+https://github.com/rust-lang/crates.io-index" 1649 | 1650 | [[package]] 1651 | name = "walkdir" 1652 | version = "2.3.1" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | dependencies = [ 1655 | "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1656 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1657 | "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 1658 | ] 1659 | 1660 | [[package]] 1661 | name = "want" 1662 | version = "0.2.0" 1663 | source = "registry+https://github.com/rust-lang/crates.io-index" 1664 | dependencies = [ 1665 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1666 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1667 | "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 1668 | ] 1669 | 1670 | [[package]] 1671 | name = "wasi" 1672 | version = "0.9.0+wasi-snapshot-preview1" 1673 | source = "registry+https://github.com/rust-lang/crates.io-index" 1674 | 1675 | [[package]] 1676 | name = "winapi" 1677 | version = "0.2.8" 1678 | source = "registry+https://github.com/rust-lang/crates.io-index" 1679 | 1680 | [[package]] 1681 | name = "winapi" 1682 | version = "0.3.8" 1683 | source = "registry+https://github.com/rust-lang/crates.io-index" 1684 | dependencies = [ 1685 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1686 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1687 | ] 1688 | 1689 | [[package]] 1690 | name = "winapi-build" 1691 | version = "0.1.1" 1692 | source = "registry+https://github.com/rust-lang/crates.io-index" 1693 | 1694 | [[package]] 1695 | name = "winapi-i686-pc-windows-gnu" 1696 | version = "0.4.0" 1697 | source = "registry+https://github.com/rust-lang/crates.io-index" 1698 | 1699 | [[package]] 1700 | name = "winapi-util" 1701 | version = "0.1.5" 1702 | source = "registry+https://github.com/rust-lang/crates.io-index" 1703 | dependencies = [ 1704 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1705 | ] 1706 | 1707 | [[package]] 1708 | name = "winapi-x86_64-pc-windows-gnu" 1709 | version = "0.4.0" 1710 | source = "registry+https://github.com/rust-lang/crates.io-index" 1711 | 1712 | [[package]] 1713 | name = "winreg" 1714 | version = "0.6.2" 1715 | source = "registry+https://github.com/rust-lang/crates.io-index" 1716 | dependencies = [ 1717 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "ws2_32-sys" 1722 | version = "0.2.1" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | dependencies = [ 1725 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1726 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "yaml-rust" 1731 | version = "0.4.3" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | dependencies = [ 1734 | "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1735 | ] 1736 | 1737 | [metadata] 1738 | "checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" 1739 | "checksum aho-corasick 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)" = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada" 1740 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 1741 | "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 1742 | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 1743 | "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 1744 | "checksum backtrace 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)" = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e" 1745 | "checksum backtrace-sys 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "18fbebbe1c9d1f383a9cc7e8ccdb471b91c8d024ee9c2ca5b5346121fe8b4399" 1746 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 1747 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 1748 | "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" 1749 | "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 1750 | "checksum cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d" 1751 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 1752 | "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" 1753 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1754 | "checksum colored 1.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" 1755 | "checksum console 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dea0f3e2e8d7dba335e913b97f9e1992c86c4399d54f8be1d31c8727d0652064" 1756 | "checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" 1757 | "checksum cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" 1758 | "checksum core-foundation 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" 1759 | "checksum core-foundation-sys 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" 1760 | "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 1761 | "checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" 1762 | "checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" 1763 | "checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" 1764 | "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 1765 | "checksum dtoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" 1766 | "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" 1767 | "checksum encode_unicode 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 1768 | "checksum encoding_rs 0.8.22 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" 1769 | "checksum error-chain 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd" 1770 | "checksum failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" 1771 | "checksum failure_derive 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" 1772 | "checksum flate2 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 1773 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 1774 | "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 1775 | "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 1776 | "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 1777 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1778 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1779 | "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" 1780 | "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" 1781 | "checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 1782 | "checksum git2 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c1af51ea8a906616af45a4ce78eacf25860f7a13ae7bf8a814693f0f4037a26" 1783 | "checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" 1784 | "checksum hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" 1785 | "checksum http 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" 1786 | "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" 1787 | "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 1788 | "checksum hyper 0.12.35 (registry+https://github.com/rust-lang/crates.io-index)" = "9dbe6ed1438e1f8ad955a4701e9a944938e9519f6888d12d8558b645e247d5f6" 1789 | "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" 1790 | "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" 1791 | "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1792 | "checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292" 1793 | "checksum indicatif 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a68371cf417889c9d7f98235b7102ea7c54fc59bcbd22f3dea785be9d27e40" 1794 | "checksum indoc 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "79255cf29f5711995ddf9ec261b4057b1deb34e66c90656c201e41376872c544" 1795 | "checksum indoc-impl 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "54554010aa3d17754e484005ea0022f1c93839aabc627c2c55f3d7b47206134c" 1796 | "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 1797 | "checksum itertools 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c4a9b56eb56058f43dc66e58f40a214b2ccbc9f3df51861b63d51dec7b65bc3f" 1798 | "checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" 1799 | "checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" 1800 | "checksum jobserver 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" 1801 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1802 | "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" 1803 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1804 | "checksum libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" 1805 | "checksum libgit2-sys 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4870c781f6063efb83150cd22c1ddf6ecf58531419e7570cdcced46970f64a16" 1806 | "checksum libssh2-sys 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "d45f516b9b19ea6c940b9f36d36734062a153a2b4cc9ef31d82c54bb9780f525" 1807 | "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" 1808 | "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" 1809 | "checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" 1810 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1811 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1812 | "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 1813 | "checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 1814 | "checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" 1815 | "checksum mime 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 1816 | "checksum mime_guess 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" 1817 | "checksum miniz_oxide 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5" 1818 | "checksum mio 0.6.22 (registry+https://github.com/rust-lang/crates.io-index)" = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" 1819 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1820 | "checksum mockers 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf36d14570661eebd299640fff1fae157c6d7da34bcbf4e4eba1c3b47b46ec9" 1821 | "checksum mockers_derive 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a53c3de46bf8e9cbe2b80e5086bbc8659bdf508c3719d50c2f366c9368d5726c" 1822 | "checksum native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" 1823 | "checksum net2 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" 1824 | "checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 1825 | "checksum number_prefix 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b02fc0ff9a9e4b35b3342880f48e896ebf69f2967921fe8646bf5b7125956a" 1826 | "checksum openssl 0.10.29 (registry+https://github.com/rust-lang/crates.io-index)" = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd" 1827 | "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1828 | "checksum openssl-sys 0.9.55 (registry+https://github.com/rust-lang/crates.io-index)" = "7717097d810a0f2e2323f9e5d11e71608355e24828410b55b9d4f18aa5f9a5d8" 1829 | "checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" 1830 | "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" 1831 | "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1832 | "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1833 | "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 1834 | "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" 1835 | "checksum proc-macro-hack 0.5.15 (registry+https://github.com/rust-lang/crates.io-index)" = "0d659fe7c6d27f25e9d80a1a094c223f5246f6a6596453e09d7229bf42750b63" 1836 | "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" 1837 | "checksum proc-macro2 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" 1838 | "checksum proc-quote 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fa612543f23fda013e1e6ce30b5285a9d313c6e582e57b4ceca74eb5b85685b5" 1839 | "checksum proc-quote-impl 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f785f0f8cd00b7945efc3f3bdf8205eb06af5aacec598d83e67f41dc8d101fda" 1840 | "checksum publicsuffix 1.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b" 1841 | "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" 1842 | "checksum quote 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" 1843 | "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1844 | "checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1845 | "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" 1846 | "checksum rand_chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1847 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1848 | "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1849 | "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1850 | "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" 1851 | "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1852 | "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" 1853 | "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" 1854 | "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1855 | "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" 1856 | "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" 1857 | "checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" 1858 | "checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" 1859 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1860 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1861 | "checksum regex 1.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692" 1862 | "checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae" 1863 | "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 1864 | "checksum reqwest 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" 1865 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1866 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1867 | "checksum ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" 1868 | "checksum same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1869 | "checksum schannel 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19" 1870 | "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1871 | "checksum security-framework 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3f331b9025654145cd425b9ded0caf8f5ae0df80d418b326e2dc1c3dc5eb0620" 1872 | "checksum security-framework-sys 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" 1873 | "checksum select-rustc 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fdb2e15b35a72de428af0da95ba4c990a336602576906f537923c5aa4d695835" 1874 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1875 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1876 | "checksum serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" 1877 | "checksum serde_derive 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)" = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" 1878 | "checksum serde_json 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "a7894c8ed05b7a3a279aeb79025fdec1d3158080b75b98a08faf2806bb799edd" 1879 | "checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" 1880 | "checksum serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" 1881 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1882 | "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6" 1883 | "checksum smallvec 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4" 1884 | "checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" 1885 | "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1886 | "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" 1887 | "checksum syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" 1888 | "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" 1889 | "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1890 | "checksum terminal_size 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8038f95fc7a6f351163f4b964af631bd26c9e828f7db085f2a84aca56f70d13b" 1891 | "checksum termios 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2" 1892 | "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1893 | "checksum thread_local 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" 1894 | "checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 1895 | "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" 1896 | "checksum tokio-buf 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" 1897 | "checksum tokio-current-thread 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" 1898 | "checksum tokio-executor 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" 1899 | "checksum tokio-io 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" 1900 | "checksum tokio-reactor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" 1901 | "checksum tokio-sync 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" 1902 | "checksum tokio-tcp 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" 1903 | "checksum tokio-threadpool 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)" = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" 1904 | "checksum tokio-timer 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" 1905 | "checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" 1906 | "checksum try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" 1907 | "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1908 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1909 | "checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" 1910 | "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" 1911 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" 1912 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1913 | "checksum unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "63f18aa3b0e35fed5a0048f029558b1518095ffe2a0a31fb87c93dece93a4993" 1914 | "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" 1915 | "checksum url 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" 1916 | "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" 1917 | "checksum vcpkg 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168" 1918 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 1919 | "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" 1920 | "checksum walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1921 | "checksum want 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" 1922 | "checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1923 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1924 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1925 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1926 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1927 | "checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1928 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1929 | "checksum winreg 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" 1930 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1931 | "checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" 1932 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "git-governance" 3 | version = "0.3.2" 4 | authors = ["Ninan John ", "Dinesh B"] 5 | edition = "2018" 6 | description="A tool to manage multiple git repositories" 7 | license = "MIT" 8 | homepage = "https://github.com/thecasualcoder/gg" 9 | keywords = ["git", "gg", "multi", "goverance"] 10 | readme = "README.md" 11 | repository = "https://github.com/thecasualcoder/gg" 12 | categories = ["command-line-utilities"] 13 | 14 | [[bin]] 15 | name="gg" 16 | path = "src/main.rs" 17 | 18 | [badges] 19 | travis-ci = { repository = "thecasualcoder/gg" } 20 | 21 | [dependencies] 22 | walkdir = "2.2.9" 23 | git2 = "0.10" 24 | colored = "1.8.0" 25 | clap = "2" 26 | indicatif = "0.14" 27 | rayon = "1.1" 28 | regex = "1" 29 | reqwest = "0.9.19" 30 | serde = { version = "1.0", features = ["derive"] } 31 | serde_json = "1.0" 32 | serde_yaml = "0.8.11" 33 | lazy_static = "1.4.0" 34 | 35 | [dev-dependencies] 36 | mockers = "0.21.0" 37 | mockers_derive = "0.21.0" -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | Currently the only requirement is 2 | 3 | - Please make all changes on a branch and raise a PR. 4 | - This rule is applicable also for the original authors. 5 | - Lets try and keep the master branch pristine and always in a working state. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 J P Ninan John 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### Git Governance 2 | [![Build Status](https://travis-ci.org/thecasualcoder/gg.svg?branch=master)](https://travis-ci.org/thecasualcoder/gg) 3 | 4 | A tool to manage multiple git repositories. 5 | This does not aim to replace git in any way but tries to reduce the work in managing multiple git repositories at once. 6 | To know about the story behind this tool, take a look at this blog -> https://medium.com/@jpninanjohn/we-built-a-tool-in-rust-9c1bcb9b655e 7 | 8 | #### Installation 9 | 10 | Using Brew: 11 | 12 | ```bash 13 | brew tap thecasualcoder/stable 14 | brew install gg 15 | ``` 16 | 17 | Installing from source: 18 | ```bash 19 | git clone https://github.com/thecasualcoder/gg.git 20 | cd gg 21 | cargo install --path . 22 | ``` 23 | 24 | > Note: Recommaded rustc/cargo version: 1.36.0 and above or 1.37.0-nightly and above 25 | 26 | 27 | #### Usage: 28 | 29 | ##### Help: 30 | ```bash 31 | $ gg --help 32 | ``` 33 | ![Help](/gifs/ggHelp.gif) 34 | 35 | ##### Status: 36 | Shows status of all git repos from current directory. Traverses inside directories also. 37 | To traverse through hidden directories use the `-i` flag. By default hidden directories will not be traversed. 38 | 39 | ```bash 40 | $ gg status 41 | ``` 42 | ![Status](/gifs/ggStatus.gif) 43 | 44 | ##### Create: 45 | Creates a remote repository and clones it to the local path specified. Remote repository is created based on the GITHUB_TOKEN provided. 46 | GITHUB_TOKEN can be passed as an env variable or can be given as an argument through the `-t` flag 47 | ```bash 48 | $ gg create -r -l 49 | ``` 50 | ![Create](/gifs/ggCreate.gif) 51 | 52 | ##### Fetch: 53 | Fetches from all git repositories starting from current directory. Traverses inside directories also. 54 | Currently Fetch only uses the private key `id_rsa` to authenticate and will fail to fetch if it is not enough. Failure to fetch one repo will not fail others 55 | To traverse through hidden directories use the `-i` flag. By default hidden directories will not be traversed. 56 | ```bash 57 | $ gg fetch 58 | ``` 59 | ![Fetch](/gifs/ggFetch.gif) 60 | 61 | ##### Clone: 62 | Clones repositories based on the flags passed and the configuration given in the `.ggConf.yaml` file. 63 | ```bash 64 | $ gg clone -r -r -l 65 | ``` 66 | ![Clone](/gifs/ggClone.gif) 67 | 68 | ##### Config file: 69 | 70 | The config file can be specified via the `-c` flag. By default it tries to find `.ggConf.yaml`. 71 | Example config file: 72 | 73 | ```yaml 74 | skipDirectories: 75 | - ignore 76 | cloneRepos: 77 | - remoteURL: https://github.com/golang/net.git 78 | localPath: here/net 79 | - remoteURL: https://github.com/golang/net.git 80 | localPath: there/net 81 | ssh: 82 | privateKey: '/home/ninan/.ssh/gg' 83 | username: 'git' 84 | ssh_agent: false 85 | ``` 86 | 87 | See `.ggConf.example.yaml` for more details 88 | 89 | ##### Contributing: 90 | [Please refer the github projects board](https://github.com/thecasualcoder/gg/projects/1) 91 | If you want some feature, please create an issue and if possible feel free to raise PR too. 92 | -------------------------------------------------------------------------------- /gifs/ggClone.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 159, "height": 21, "timestamp": 1579716928, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.772432, "o", "g"] 3 | [0.77485, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 4 | [0.77503, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007\u001b]1;...com/cloneDir\u0007"] 5 | [0.82251, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 6 | [0.822888, "o", "\u001b[?1h\u001b="] 7 | [0.823239, "o", "\u001b[?2004h"] 8 | [0.828841, "o", "\u001b[32mg\u001b[39m\u001b[90mg clone\u001b[39m\b\b\b\b\b\b\b"] 9 | [1.288031, "o", "\b\u001b[32mg\u001b[32mg\u001b[39m"] 10 | [1.768869, "o", "\u001b[39m \u001b[39mc\u001b[39ml\u001b[39mo\u001b[39mn\u001b[39me"] 11 | [2.278939, "o", "\u001b[?1l\u001b>"] 12 | [2.281102, "o", "\u001b[?2004l\r\r\n"] 13 | [2.282135, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg clone\u0007\u001b]1;gg\u0007"] 14 | [2.297679, "o", "\u001b[33mNo remotes were passed as arguments.\u001b[0m\r\n\u001b[33mNo remotes configured in conf file\u001b[0m\r\n\u001b[34mPlease configure conf file to clone repositories or pass the necessary values as arguments\u001b[0m\r\n"] 15 | [2.298405, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 16 | [2.298515, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007"] 17 | [2.298622, "o", "\u001b]1;...com/cloneDir\u0007"] 18 | [2.340865, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 19 | [2.341041, "o", "\u001b[?1h\u001b="] 20 | [2.341463, "o", "\u001b[?2004h"] 21 | [4.194534, "o", "\u001b[32mg\u001b[39m\u001b[90mg clone\u001b[39m\b\b\b\b\b\b\b"] 22 | [4.391647, "o", "\b\u001b[32mg\u001b[32mg\u001b[39m"] 23 | [4.814985, "o", "\u001b[39m \u001b[39mc\u001b[39ml\u001b[39mo\u001b[39mn\u001b[39me"] 24 | [5.439928, "o", "\u001b[8D\u001b[39mg\u001b[39mg\u001b[6C"] 25 | [5.445891, "o", "\u001b[8D\u001b[32mg\u001b[32mg\u001b[39m\u001b[6C \u001b[90m-r https://github.com/golang/net.git -r https://github.com/thecasualcoder/tztail -l Inside\u001b[39m\u001b[90D"] 26 | [5.736257, "o", "\u001b[39m-"] 27 | [6.21585, "o", "\u001b[39mr\u001b[39m \u001b[39mh\u001b[39mt\u001b[39mt\u001b[39mp\u001b[39ms\u001b[39m:\u001b[39m/\u001b[39m/\u001b[39mg\u001b[39mi\u001b[39mt\u001b[39mh\u001b[39mu\u001b[39mb\u001b[39m.\u001b[39mc\u001b[39mo\u001b[39mm\u001b[39m/\u001b[39mg\u001b[39mo\u001b[39ml\u001b[39ma\u001b[39mn\u001b[39mg\u001b[39m/\u001b[39mn\u001b[39me\u001b[39mt\u001b[39m.\u001b[39mg\u001b[39mi\u001b[39mt\u001b[39m \u001b[39m-\u001b[39mr\u001b[39m \u001b[39mh\u001b[39mt\u001b[39mt\u001b[39mp\u001b[39ms\u001b[39m:\u001b[39m/\u001b[39m/\u001b[39mg\u001b[39mi\u001b[39mt\u001b[39mh\u001b[39mu\u001b[39mb\u001b[39m.\u001b[39mc\u001b[39mo\u001b[39mm\u001b[39m/\u001b[39mt\u001b[39mh\u001b[39me\u001b[39mc\u001b[39ma\u001b[39ms\u001b[39mu\u001b[39ma\u001b[39ml\u001b[39mc\u001b[39mo\u001b[39md\u001b[39me\u001b[39mr\u001b[39m/\u001b[39mt\u001b[39mz\u001b[39mt\u001b[39ma\u001b[39mi\u001b[39ml\u001b[39m \u001b[39m-\u001b[39ml\u001b[39m \u001b[39mI\u001b[39mn\u001b[39ms\u001b[39mi\u001b[39md\u001b[39me"] 28 | [7.512107, "o", "\u001b[?1l\u001b>"] 29 | [7.520886, "o", "\u001b[?2004l\r\r\n"] 30 | [7.521576, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg clone -r -r -l Inside\u0007\u001b]1;gg\u0007"] 31 | [7.53669, "o", "\u001b[34mCloning remotes passed as arguments\u001b[0m\r\n\u001b[33mNo remotes configured in conf file\u001b[0m\r\n"] 32 | [12.738046, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/golang/net.git\u001b[0m \u001b[32mcloned locally at\u001b[0m \"Inside/net\"\r\n"] 33 | [15.881857, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/thecasualcoder/tztail\u001b[0m \u001b[32mcloned locally at\u001b[0m \"Inside/tztail\"\r\n"] 34 | [15.885249, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 35 | [15.885556, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007\u001b]1;...com/cloneDir\u0007"] 36 | [15.939672, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \u001b[1;33mtook 8s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 37 | [15.939894, "o", "\u001b[?1h\u001b="] 38 | [15.940373, "o", "\u001b[?2004h"] 39 | [16.91712, "o", "\u001b[1m\u001b[31mt\u001b[0m\u001b[39m"] 40 | [16.920939, "o", "\b\u001b[0m\u001b[32mt\u001b[32mr\u001b[39m\u001b[90mee -L 2 .\u001b[39m\u001b[9D"] 41 | [17.343513, "o", "\b\b\u001b[32mt\u001b[32mr\u001b[32me\u001b[32me\u001b[39m\u001b[39m \u001b[39m-\u001b[39mL\u001b[39m \u001b[39m2\u001b[39m \u001b[39m\u001b[4m.\u001b[24m"] 42 | [17.621146, "o", "\u001b[?1l\u001b>"] 43 | [17.624093, "o", "\u001b[?2004l\r\r\n"] 44 | [17.624801, "o", "\u001b]2;tree -C -L 2 .\u0007\u001b]1;tree\u0007"] 45 | [17.631954, "o", "\u001b[01;34m.\u001b[00m\r\n"] 46 | [17.632076, "o", "└── \u001b[01;34mInside\u001b[00m\r\n ├── \u001b[01;34mnet\u001b[00m\r\n └── \u001b[01;34mtztail\u001b[00m\r\n\r\n3 directories, 0 files\r\n"] 47 | [17.632301, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 48 | [17.632398, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007"] 49 | [17.632485, "o", "\u001b]1;...com/cloneDir\u0007"] 50 | [17.671067, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 51 | [17.671253, "o", "\u001b[?1h\u001b="] 52 | [17.671764, "o", "\u001b[?2004h"] 53 | [20.089131, "o", "\u001b[32mv\u001b[39m\u001b[90mi .ggconf.yaml\u001b[39m\u001b[14D"] 54 | [20.221546, "o", "\b\u001b[32mv\u001b[32mi\u001b[39m"] 55 | [20.694852, "o", "\u001b[39m \u001b[39m.\u001b[39mg\u001b[39mg\u001b[39mc\u001b[39mo\u001b[39mn\u001b[39mf\u001b[39m.\u001b[39my\u001b[39ma\u001b[39mm\u001b[39ml"] 56 | [21.053039, "o", "\u001b[?1l\u001b>"] 57 | [21.055471, "o", "\u001b[?2004l\r\r\n"] 58 | [21.056367, "o", "\u001b]2;vi .ggconf.yaml\u0007\u001b]1;vi\u0007"] 59 | [21.388593, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1049h\u001b[?1h\u001b=\u001b[?2004h"] 60 | [21.393799, "o", "\u001b[1;21r\u001b[?12h\u001b[?12l\u001b[27m\u001b[29m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[H\u001b[2J"] 61 | [21.394324, "o", "\u001b[?1000l\u001b[?2004l"] 62 | [21.395512, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1000l\u001b[?2004l"] 63 | [21.398073, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1000l\u001b[?2004l"] 64 | [21.401497, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1000l\u001b[?2004l"] 65 | [21.406827, "o", "\u001b[?1000h\u001b[?2004h\u001b[?2004h"] 66 | [21.417092, "o", "\u001b[?1000l\u001b[?2004l"] 67 | [21.418169, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1000l\u001b[?2004l"] 68 | [21.420506, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1000l\u001b[?2004l"] 69 | [21.423845, "o", "\u001b[?1000h\u001b[?2004h"] 70 | [21.423967, "o", "\u001b[?1000l\u001b[?2004l"] 71 | [21.427971, "o", "\u001b[?1000h\u001b[?2004h\u001b[?1000l\u001b[?2004l"] 72 | [21.433193, "o", "\u001b[?1000h\u001b[?2004h"] 73 | [21.43323, "o", "\u001b[?2004h"] 74 | [21.453574, "o", "\u001b[2;1H▽\u001b[6n\u001b[2;1H \u001b[1;1H\u001b[>c\u001b]11;?\u0007"] 75 | [21.509066, "o", "\u001b[1;1H\u001b[38;5;235m\u001b[48;5;246m 1 .ggconf.yaml \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;246m\u001b[48;5;239m\u001b[1;18H \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[1;151H\u001b[38;5;235m\u001b[48;5;246m Buffers \u001b[?25l\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[2;1H\u001b[38;5;214m\u001b[48;5;237m1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[48;5;237m \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[3;1H\u001b[38;5;235m\u001b[48;5;235m~ \u001b[4;1H~ \u001b[5;1H~ "] 76 | [21.509248, "o", " \u001b[6;1H~ \u001b[7;1H~ \u001b[8;1H~ \u001b[9;1H~ \u001b[10;1H~ \u001b[11;1H~ "] 77 | [21.515251, "o", " \u001b[12;1H~ \u001b[13;1H~ \u001b[14;1H~ \u001b[15;1H~ \u001b[16;1H~ \u001b[17;1H~ "] 78 | [21.515381, "o", " \u001b[18;1H~ \u001b[19;1H~ \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;1H\u001b[1m\u001b[38;5;235m\u001b[48;5;246m 1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;246m\u001b[48;5;239m\u001b[20;5H - .ggconf.yaml \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;239m\u001b[48;5;237m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;22H\u001b[38;5;246m\u001b[48;5;237m yaml \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;237m\u001b[48;5;239m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;29H\u001b[38;5;246m\u001b[48;5;239m ❖ ⓢ\u001b[20;33H \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;239m\u001b[48;5;241m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;36H\u001b[38;5;237m\u001b[48;5;241m \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;239m\u001b[48;5;241m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;137H\u001b[38;5;246m"] 79 | [21.516389, "o", "\u001b[48;5;239m \u001b[20;139H | utf-8 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;237m\u001b[48;5;239m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;149H\u001b[38;5;246m\u001b[48;5;237m 0:0 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;239m\u001b[48;5;237m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;155H\u001b[38;5;246m\u001b[48;5;239m All \u001b[2;5H\u001b[?25h"] 80 | [21.516517, "o", "\u001b[?1000l\u001b[?1002h\u001b[?12$p"] 81 | [21.815495, "o", "\u001b[?25l\u001b[?25h"] 82 | [22.213715, "o", "\u001b[?1002l\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[1;1H\u001b[38;5;235m\u001b[48;5;109m 1 .ggconf.yaml \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;109m\u001b[48;5;239m\u001b[1;18H \u001b[?25l\u001b[m\u001b[38;5;223m\u001b[48;5;235m\r\n\u001b[38;5;243m 1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;109mcloneRepos\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;208m:\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[2;16H\u001b[K\u001b[3;1H\u001b[38;5;214m\u001b[48;5;237m2 \u001b[m\u001b[38;5;223m\u001b[48;5;235m \u001b[38;5;167m- \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;109mremoteURL\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;208m:\u001b[m\u001b[38;5;223m\u001b[48;5;235m https://github.com/gol\u001b[3;42H\u001b[K\u001b[20;1H\u001b[1m\u001b[38;5;235m\u001b[48;5;109m 1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;109m\u001b[48;5;239m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;6H\u001b[38;5;246m\u001b[48;5;239m*\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[128C\u001b[38;5;239m\u001b[48;5;241m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;136H\u001b[38;5;246m\u001b[48;5;239m \u001b[20;138H | utf-8 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;237m\u001b[48;5;239m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;148H\u001b[38;5;246m\u001b[48;5;237"] 83 | [22.213804, "o", "m 2:38\u001b[3;42H\u001b[?25h"] 84 | [22.215011, "o", "\u001b[?25l\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[2;3H\u001b[38;5;243m3\r\n 2 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[37Cang/net.git\r\n\u001b[38;5;243m 1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m \u001b[38;5;109mlocalPath\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;208m:\u001b[m\u001b[38;5;223m\u001b[48;5;235m this/net\u001b[4;28H\u001b[K\u001b[5;1H\u001b[38;5;214m\u001b[48;5;237m4 \u001b[m\u001b[38;5;223m\u001b[48;5;235m \u001b[38;5;167m- \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;109mremoteURL\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;208m:\u001b[m\u001b[38;5;223m\u001b[48;5;235m https:/\u001b[5;27H\u001b[K\u001b[5;27H\u001b[?25h"] 85 | [22.216739, "o", "\u001b[?1002h"] 86 | [22.225212, "o", "\u001b[?25l\u001b[2;3H\u001b[38;5;243m4\r\n 3\r\n 2\r\n 1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[22C/github.com/golang/net.git\r\n\u001b[38;5;214m\u001b[48;5;237m5 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[48;5;237m \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;109m\u001b[48;5;237mlocalPath\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;208m\u001b[48;5;237m:\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[48;5;237m that/net \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;1H\u001b[1m\u001b[38;5;235m\u001b[48;5;246m 1 \u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[38;5;246m\u001b[48;5;239m\u001b[m\u001b[38;5;223m\u001b[48;5;235m\u001b[20;149H\u001b[38;5;246m\u001b[48;5;237m5:23\u001b[6;27H\u001b[?25h"] 87 | [25.378128, "o", "\u0007"] 88 | [25.540216, "o", "\u001b[?25l\u001b[21;1H\u001b[m\u001b[38;5;223m\u001b[48;5;235m:\u001b[?1002l"] 89 | [25.54047, "o", "\u001b[?2004h\u001b[?25h"] 90 | [25.883534, "o", "w"] 91 | [25.967557, "o", "q"] 92 | [28.371672, "o", "\r"] 93 | [28.372544, "o", "\u001b[?1002h\u001b[?25l\u001b[?1002l\u001b[?2004l"] 94 | [28.373393, "o", "\".ggconf.yaml\""] 95 | [28.374597, "o", " [New] 5L, 158C written"] 96 | [28.498859, "o", "\r\r\r\n\u001b[39;49m\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[?1049l"] 97 | [28.500602, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 98 | [28.500792, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007"] 99 | [28.500895, "o", "\u001b]1;...com/cloneDir\u0007"] 100 | [28.54386, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \u001b[1;33mtook 8s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 101 | [28.544445, "o", "\u001b[?1h\u001b="] 102 | [28.54494, "o", "\u001b[?2004h"] 103 | [30.91621, "o", "\u001b[32mvi\u001b[39m \u001b[4m.ggconf.yaml\u001b[24m"] 104 | [31.815167, "o", "\u001b[15D\u001b[32mt\u001b[32mr\u001b[32me\u001b[24m\u001b[32me\u001b[39m\u001b[24m \u001b[24m-\u001b[24mL\u001b[24m \u001b[24m2\u001b[24m \u001b[4m.\u001b[24m\u001b[24m \u001b[24m \u001b[24m \u001b[24m \b\b\b\b"] 105 | [32.470736, "o", "\u001b[11D\u001b[32mg\u001b[32mg\u001b[39m\u001b[39m \u001b[39mclone -\u001b[24mr https://github.com/golang/net.git -r https://github.com/thecasualcoder/tztail -l \u001b[4mInside\u001b[24m"] 106 | [33.315782, "o", "\b\b\u001b[4md\u001b[24m\u001b[24m\u001b[90me\u001b[39m\b"] 107 | [33.570079, "o", "\b\b\u001b[4mi\u001b[24m\u001b[24m\u001b[90md\b"] 108 | [33.604442, "o", "\b\b\u001b[39m\u001b[4ms\u001b[24m\u001b[24m\u001b[90mi\b"] 109 | [33.640293, "o", "\b\b\u001b[39m\u001b[4mn\u001b[24m\u001b[24m\u001b[90ms\b"] 110 | [33.671169, "o", "\b\b\u001b[39m\u001b[4mI\u001b[24m\u001b[24m\u001b[90mn\b"] 111 | [33.713947, "o", "\b\u001b[24m\u001b[90mI\b"] 112 | [33.735471, "o", "\b\u001b[90m \b"] 113 | [33.78241, "o", "\b\u001b[90ml\b"] 114 | [34.987786, "o", "\u001b[39m\u001b[39ml"] 115 | [35.468841, "o", "\u001b[92D\u001b[39mg\u001b[39mg\u001b[90C\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \b\b\b\b\b\b\b"] 116 | [35.480335, "o", "\u001b[92D\u001b[32mg\u001b[32mg\u001b[39m\u001b[90C \u001b[90mInside\u001b[39m\b\b\b\b\b\b"] 117 | [36.294685, "o", "\u001b[39mH\u001b[90me\u001b[90mr\u001b[90me\u001b[39m\u001b[39m \u001b[39m \b\b\b\b\b"] 118 | [36.579416, "o", "\u001b[39me"] 119 | [37.132738, "o", "\u001b[39mr"] 120 | [37.227293, "o", "\u001b[39me"] 121 | [38.570707, "o", "\u001b[?1l\u001b>"] 122 | [38.578614, "o", "\u001b[?2004l\r\r\n"] 123 | [38.579581, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg clone -r -r -l Here\u0007\u001b]1;gg\u0007"] 124 | [38.59532, "o", "\u001b[34mCloning remotes passed as arguments\u001b[0m\r\n\u001b[34mCloning remotes configured in conf file\u001b[0m\r\n"] 125 | [45.438237, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/golang/net.git\u001b[0m \u001b[32mcloned locally at\u001b[0m \"Here/net\"\r\n"] 126 | [48.929614, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/thecasualcoder/tztail\u001b[0m \u001b[32mcloned locally at\u001b[0m \"Here/tztail\"\r\n"] 127 | [54.287339, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/golang/net.git\u001b[0m \u001b[32mcloned locally at\u001b[0m \"this/net\"\r\n"] 128 | [59.980457, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/golang/net.git\u001b[0m \u001b[32mcloned locally at\u001b[0m \"that/net\"\r\n"] 129 | [59.984604, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 130 | [59.98476, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007"] 131 | [59.984955, "o", "\u001b]1;...com/cloneDir\u0007"] 132 | [60.045456, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \u001b[1;33mtook 21s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 133 | [60.045738, "o", "\u001b[?1h\u001b="] 134 | [60.046251, "o", "\u001b[?2004h"] 135 | [61.559744, "o", "\u001b[4mt\u001b[24m\u001b[90mree -L 2 .\u001b[39m\u001b[10D"] 136 | [61.575783, "o", "\b\u001b[24m\u001b[32mt\u001b[32mr\u001b[39m"] 137 | [62.122292, "o", "\b\b\u001b[32mt\u001b[32mr\u001b[32me\u001b[32me\u001b[39m\u001b[39m \u001b[39m-\u001b[39mL\u001b[39m \u001b[39m2\u001b[39m \u001b[39m\u001b[4m.\u001b[24m"] 138 | [62.448131, "o", "\u001b[?1l\u001b>"] 139 | [62.450913, "o", "\u001b[?2004l\r\r\n"] 140 | [62.451742, "o", "\u001b]2;tree -C -L 2 .\u0007\u001b]1;tree\u0007"] 141 | [62.462286, "o", "\u001b[01;34m.\u001b[00m\r\n"] 142 | [62.46243, "o", "├── \u001b[01;34mHere\u001b[00m\r\n│   ├── \u001b[01;34mnet\u001b[00m\r\n│   └── \u001b[01;34mtztail\u001b[00m\r\n├── \u001b[01;34mInside\u001b[00m\r\n│   ├── \u001b[01;34mnet\u001b[00m\r\n│   └── \u001b[01;34mtztail\u001b[00m\r\n├── \u001b[01;34mthat\u001b[00m\r\n"] 143 | [62.462469, "o", "│   └── \u001b[01;34mnet\u001b[00m\r\n"] 144 | [62.462492, "o", "└── \u001b[01;34mthis\u001b[00m\r\n └── \u001b[01;34mnet\u001b[00m\r\n\r\n10 directories, 0 files\r\n"] 145 | [62.462907, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 146 | [62.463053, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/cloneDir\u0007"] 147 | [62.463159, "o", "\u001b]1;...com/cloneDir\u0007"] 148 | [62.527369, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/cloneDir\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 149 | [62.527582, "o", "\u001b[?1h\u001b="] 150 | [62.528091, "o", "\u001b[?2004h"] 151 | [65.255882, "o", "\u001b[?2004l\r\r\n"] 152 | -------------------------------------------------------------------------------- /gifs/ggClone.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecasualcoder/gg/ad613d99fdfac36c75fd70054f5eba2fb1074c46/gifs/ggClone.gif -------------------------------------------------------------------------------- /gifs/ggCreate.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 173, "height": 24, "timestamp": 1579718034, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.785739, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 3 | [0.787124, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 4 | [0.837597, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 5 | [0.837964, "o", "\u001b[?1h\u001b="] 6 | [0.83843, "o", "\u001b[?2004h"] 7 | [1.481404, "o", "\u001b[32mgg\u001b[39m create -r myRepo"] 8 | [2.662106, "o", "s"] 9 | [2.787657, "o", "i"] 10 | [3.038763, "o", "t"] 11 | [3.67749, "o", "o"] 12 | [4.314329, "o", "r"] 13 | [4.469438, "o", "y"] 14 | [4.722871, "o", "\u001b[?1l\u001b>"] 15 | [4.726043, "o", "\u001b[?2004l\r\r\n"] 16 | [4.727392, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg create -r myRepository\u0007"] 17 | [4.7276, "o", "\u001b]1;gg\u0007"] 18 | [7.766652, "o", "\u001b[32mRemote repo\u001b[0m - \u001b[34mhttps://github.com/jpninanjohn/myRepository.git\u001b[0m \u001b[32mcloned locally at\u001b[0m \"myRepository\"\r\n"] 19 | [7.7692, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 20 | [7.769484, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 21 | [7.813947, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \u001b[1;33mtook 3s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 22 | [7.814141, "o", "\u001b[?1h\u001b="] 23 | [7.814609, "o", "\u001b[?2004h"] 24 | [8.913951, "o", "\u001b[?2004l\r\r\n"] 25 | -------------------------------------------------------------------------------- /gifs/ggCreate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecasualcoder/gg/ad613d99fdfac36c75fd70054f5eba2fb1074c46/gifs/ggCreate.gif -------------------------------------------------------------------------------- /gifs/ggFetch.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 159, "height": 21, "timestamp": 1579716653, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.788991, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 3 | [0.79027, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/fetchDir\u0007\u001b]1;...com/fetchDir\u0007"] 4 | [0.837144, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/fetchDir\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 5 | [0.8373, "o", "\u001b[?1h\u001b="] 6 | [0.837967, "o", "\u001b[?2004h"] 7 | [1.776536, "o", "\u001b[32mg\u001b[39m\u001b[90mg fetch\u001b[39m\b\b\b\b\b\b\b"] 8 | [1.964591, "o", "\b\u001b[32mg\u001b[32mg\u001b[39m"] 9 | [2.574846, "o", "\u001b[39m \u001b[39mf\u001b[39me\u001b[39mt\u001b[39mc\u001b[39mh"] 10 | [2.861087, "o", "\u001b[?1l\u001b>"] 11 | [2.863241, "o", "\u001b[?2004l\r\r\n"] 12 | [2.864361, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg fetch\u0007"] 13 | [2.864487, "o", "\u001b]1;gg\u0007"] 14 | [2.896028, "o", "\u001b[34m\r\n"] 15 | [6.419436, "o", "Fetching\u001b[0m \u001b[34morigin\u001b[0m \u001b[34mfor\u001b[0m \"/Users/ninanjohn/github.com/fetchDir/fd\" -> \u001b[32mReceived\u001b[0m 0/0 \u001b[32mobjects in\u001b[0m 0 \u001b[32mbytes\u001b[0m\u001b[34m\r\n"] 16 | [7.655422, "o", "Fetching\u001b[0m \u001b[34morigin\u001b[0m \u001b[34mfor\u001b[0m \"/Users/ninanjohn/github.com/fetchDir/bat\" -> \u001b[32mReceived\u001b[0m 0/0 \u001b[32mobjects in\u001b[0m 0 \u001b[32mbytes\u001b[0m\u001b[34m\r\n"] 17 | [12.097108, "o", "Fetching\u001b[0m \u001b[34morigin\u001b[0m \u001b[34mfor\u001b[0m \"/Users/ninanjohn/github.com/fetchDir/ripgrep\" -> \u001b[32mReceived\u001b[0m 69/69 \u001b[32mobjects in\u001b[0m 0 \u001b[32m bytes (used \u001b[0m 21 \u001b[32mlocal objects)\u001b[0m"] 18 | [12.099702, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 19 | [12.099875, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com/fetchDir\u0007\u001b]1;...com/fetchDir\u0007"] 20 | [12.145674, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com/fetchDir\u001b[0m \u001b[1;33mtook 10s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 21 | [12.145966, "o", "\u001b[?1h\u001b="] 22 | [12.146656, "o", "\u001b[?2004h"] 23 | [15.415453, "o", "\u001b[?2004l\r\r\n"] 24 | -------------------------------------------------------------------------------- /gifs/ggFetch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecasualcoder/gg/ad613d99fdfac36c75fd70054f5eba2fb1074c46/gifs/ggFetch.gif -------------------------------------------------------------------------------- /gifs/ggHelp.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecasualcoder/gg/ad613d99fdfac36c75fd70054f5eba2fb1074c46/gifs/ggHelp.gif -------------------------------------------------------------------------------- /gifs/ggStatus.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 159, "height": 21, "timestamp": 1579716342, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.907662, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 3 | [0.909191, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 4 | [0.954377, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 5 | [0.954595, "o", "\u001b[?1h\u001b="] 6 | [0.955134, "o", "\u001b[?2004h"] 7 | [2.092243, "o", "\u001b[32mg\u001b[39m\u001b[90mg status\u001b[39m\u001b[8D"] 8 | [2.269384, "o", "\b\u001b[32mg\u001b[32mg\u001b[39m"] 9 | [2.966685, "o", "\u001b[39m \u001b[39ms\u001b[39mt\u001b[39ma\u001b[39mt\u001b[39mu\u001b[39ms"] 10 | [3.72489, "o", "\u001b[?1l\u001b>"] 11 | [3.727108, "o", "\u001b[?2004l\r\r\n"] 12 | [3.728328, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg status\u0007\u001b]1;gg\u0007"] 13 | [4.281712, "o", "\"/Users/ninanjohn/github.com/terraform\": \u001b[31m\u001b[33m529 behind\u001b[0m\u001b[31m, modifications\u001b[0m\r\n"] 14 | [4.363388, "o", "\"/Users/ninanjohn/github.com/docker-pi-hole\": \u001b[31m\u001b[33m27 behind\u001b[0m\u001b[31m, modifications, new files\u001b[0m\r\n"] 15 | [4.403029, "o", "\"/Users/ninanjohn/github.com/alacritty\": \u001b[31m\u001b[33m39 behind\u001b[0m\u001b[31m, \u001b[34m1 ahead\u001b[0m\u001b[31m\u001b[0m\r\n"] 16 | [4.421424, "o", "\"/Users/ninanjohn/github.com/talisman\": \u001b[31m\u001b[33m26 behind\u001b[0m\u001b[31m, \u001b[34m1 ahead\u001b[0m\u001b[31m\u001b[0m\r\n"] 17 | [4.43154, "o", "\"/Users/ninanjohn/github.com/async-compression\": \u001b[31m\u001b[33m20 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 18 | [4.445687, "o", "\"/Users/ninanjohn/github.com/FizzBuzzEnterpriseEdition\": \u001b[31mnew files\u001b[0m\r\n"] 19 | [4.6219, "o", "\"/Users/ninanjohn/github.com/thefuck\": \u001b[31mmodifications\u001b[0m\r\n"] 20 | [4.628311, "o", "\"/Users/ninanjohn/github.com/install\": \u001b[31mmodifications\u001b[0m\r\n"] 21 | [4.690851, "o", "\"/Users/ninanjohn/github.com/net\": \u001b[32mno changes\u001b[0m\r\n"] 22 | [5.416832, "o", "\"/Users/ninanjohn/github.com/go\": \u001b[31m\u001b[33m567 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 23 | [5.513562, "o", "\"/Users/ninanjohn/github.com/microservices-demo\": \u001b[31m\u001b[33m9 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 24 | [5.578397, "o", "\"/Users/ninanjohn/github.com/cloneDir/blah/blah/net\": \u001b[32mno changes\u001b[0m\r\n"] 25 | [5.75703, "o", "\"/Users/ninanjohn/github.com/cloneDir/blah/glah/net\": \u001b[32mno changes\u001b[0m\r\n"] 26 | [5.817117, "o", "\"/Users/ninanjohn/github.com/cloneDir/Here/net\": \u001b[32mno changes\u001b[0m\r\n"] 27 | [5.829242, "o", "\"/Users/ninanjohn/github.com/cloneDir/Here/tztail\": \u001b[32mno changes\u001b[0m\r\n"] 28 | [5.879332, "o", "\"/Users/ninanjohn/github.com/cloneDir/Inside/net\": \u001b[32mno changes\u001b[0m\r\n"] 29 | [5.889469, "o", "\"/Users/ninanjohn/github.com/cloneDir/Inside/tztail\": \u001b[32mno changes\u001b[0m\r\n"] 30 | [5.903869, "o", "\"/Users/ninanjohn/github.com/allDayGeekNight\": \u001b[31m\u001b[33m10 behind\u001b[0m\u001b[31m, modifications\u001b[0m\r\n"] 31 | [5.928928, "o", "\"/Users/ninanjohn/github.com/edn-to-json\": \u001b[31m\u001b[34m1 ahead\u001b[0m\u001b[31m, modifications\u001b[0m\r\n"] 32 | [5.990555, "o", "\"/Users/ninanjohn/github.com/fd\": \u001b[31m\u001b[33m61 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 33 | [5.996788, "o", "\"/Users/ninanjohn/github.com/homebrew-command-not-found\": \u001b[32mno changes\u001b[0m\r\n"] 34 | [6.454036, "o", "\"/Users/ninanjohn/github.com/charts\": \u001b[31m\u001b[33m764 behind\u001b[0m\u001b[31m, new files\u001b[0m\r\n"] 35 | [8.688272, "o", "\"/Users/ninanjohn/github.com/excaliburjs.github.io\": \u001b[31mmodifications\u001b[0m\r\n"] 36 | [8.69482, "o", "\"/Users/ninanjohn/github.com/terranova\": \u001b[32mno changes\u001b[0m\r\n"] 37 | [9.015704, "o", "\"/Users/ninanjohn/github.com/envoy\": \u001b[32mno changes\u001b[0m\r\n"] 38 | [9.082726, "o", "\"/Users/ninanjohn/github.com/bazel-gazelle\": \u001b[31m\u001b[33m2 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 39 | [9.092263, "o", "\"/Users/ninanjohn/github.com/lazy-connect\": \u001b[32mno changes\u001b[0m\r\n"] 40 | [9.129761, "o", "\"/Users/ninanjohn/github.com/nushell\": \u001b[31m\u001b[33m1125 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 41 | [9.13454, "o", "\"/Users/ninanjohn/github.com/newGitRepos\": \u001b[32mno changes\u001b[0m\r\n"] 42 | [9.136633, "o", "\"/Users/ninanjohn/github.com/newGitReposTemp\": \u001b[32mno changes\u001b[0m\r\n"] 43 | [9.141576, "o", "\"/Users/ninanjohn/github.com/asciicast2gif\": \u001b[32mno changes\u001b[0m\r\n"] 44 | [10.767951, "o", "\"/Users/ninanjohn/github.com/Excalibur/build\": \u001b[31mdeletions, modifications, new files\u001b[0m\r\n"] 45 | [10.794694, "o", "\"/Users/ninanjohn/github.com/Excalibur\": \u001b[31mmodifications\u001b[0m\r\n"] 46 | [10.812363, "o", "\"/Users/ninanjohn/github.com/go-plugin\": \u001b[31m\u001b[33m5 behind\u001b[0m\u001b[31m, modifications\u001b[0m\r\n"] 47 | [11.661075, "o", "\"/Users/ninanjohn/github.com/bazel\": \u001b[31m\u001b[33m1299 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 48 | [11.758479, "o", "\"/Users/ninanjohn/github.com/kbsecret\": \u001b[32mno changes\u001b[0m\r\n"] 49 | [11.933539, "o", "\"/Users/ninanjohn/github.com/homebrew-stable\": \u001b[32mno changes\u001b[0m\r\n"] 50 | [12.5555, "o", "\"/Users/ninanjohn/github.com/emsdk\": \u001b[32mno changes\u001b[0m\r\n"] 51 | [12.572318, "o", "\"/Users/ninanjohn/github.com/forked/talisman\": \u001b[31mmodifications, new files\u001b[0m\r\n"] 52 | [12.6385, "o", "\"/Users/ninanjohn/github.com/forked/install\": \u001b[32mno changes\u001b[0m\r\n"] 53 | [12.64907, "o", "\"/Users/ninanjohn/github.com/forked/allDayGeekNight\": \u001b[32mno changes\u001b[0m\r\n"] 54 | [12.678378, "o", "\"/Users/ninanjohn/github.com/forked/etcd-operator\": \u001b[32mno changes\u001b[0m\r\n"] 55 | [13.048773, "o", "\"/Users/ninanjohn/github.com/forked/brew\": \u001b[32mno changes\u001b[0m\r\n"] 56 | [13.054652, "o", "\"/Users/ninanjohn/github.com/forked/lazy-connect\": \u001b[32mno changes\u001b[0m\r\n"] 57 | [13.081022, "o", "\"/Users/ninanjohn/github.com/forked/goreleaser\": \u001b[31mnew files\u001b[0m\r\n"] 58 | [14.995409, "o", "\"/Users/ninanjohn/github.com/forked/Excalibur/build\": \u001b[31mdeletions, modifications, new files\u001b[0m\r\n"] 59 | [15.029826, "o", "\"/Users/ninanjohn/github.com/forked/Excalibur\": \u001b[31m\u001b[33m2 behind\u001b[0m\u001b[31m\u001b[0m\r\n"] 60 | [15.460076, "o", "\"/Users/ninanjohn/github.com/forked/consul\": \u001b[32mno changes\u001b[0m\r\n"] 61 | [15.684553, "o", "\"/Users/ninanjohn/github.com/forked/stolon\": \u001b[32mno changes\u001b[0m\r\n"] 62 | [15.7646, "o", "\"/Users/ninanjohn/github.com/forked/ripgrep\": \u001b[32mno changes\u001b[0m\r\n"] 63 | [15.866091, "o", "\"/Users/ninanjohn/github.com/forked/helm\": \u001b[32mno changes\u001b[0m\r\n"] 64 | [16.160661, "o", "\"/Users/ninanjohn/github.com/forked/git\": \u001b[32mno changes\u001b[0m\r\n"] 65 | [16.208421, "o", "\"/Users/ninanjohn/github.com/bat\": \u001b[31m\u001b[33m126 behind\u001b[0m\u001b[31m, modifications\u001b[0m\r\n"] 66 | [16.415725, "o", "\"/Users/ninanjohn/github.com/stolon\": \u001b[31m\u001b[33m9 behind\u001b[0m\u001b[31m, modifications, new files\u001b[0m\r\n"] 67 | [16.528712, "o", "\"/Users/ninanjohn/github.com/rustfmt\": \u001b[31m\u001b[33m121 behind\u001b[0m\u001b[31m, modifications\u001b[0m\r\n"] 68 | [17.982194, "o", "\"/Users/ninanjohn/github.com/kubernetes\": \u001b[31mdeletions, modifications, new files\u001b[0m\r\n"] 69 | [18.349127, "o", "\"/Users/ninanjohn/github.com/consul_exporter\": \u001b[32mno changes\u001b[0m\r\n"] 70 | [18.373237, "o", "\"/Users/ninanjohn/github.com/ripgrep\": \u001b[32mno changes\u001b[0m\r\n"] 71 | [18.61355, "o", "\"/Users/ninanjohn/github.com/git\": \u001b[31mmodifications\u001b[0m\r\n"] 72 | [18.619759, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 73 | [18.619938, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 74 | [18.711638, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \u001b[1;33mtook 15s\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 75 | [18.711815, "o", "\u001b[?1h\u001b="] 76 | [18.712269, "o", "\u001b[?2004h"] 77 | [22.37622, "o", "\u001b[?2004l\r\r\n"] 78 | -------------------------------------------------------------------------------- /gifs/ggStatus.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecasualcoder/gg/ad613d99fdfac36c75fd70054f5eba2fb1074c46/gifs/ggStatus.gif -------------------------------------------------------------------------------- /gifs/gghelp.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 159, "height": 21, "timestamp": 1579716167, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.770862, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 3 | [0.772254, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 4 | [0.821115, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 5 | [0.821443, "o", "\u001b[?1h\u001b="] 6 | [0.821983, "o", "\u001b[?2004h"] 7 | [2.354616, "o", "\u001b[32mg\u001b[39m\u001b[90mg --help\u001b[39m\u001b[8D"] 8 | [2.542881, "o", "\b\u001b[32mg\u001b[32mg\u001b[39m"] 9 | [3.277721, "o", "\u001b[39m \u001b[39m-\u001b[39m-\u001b[39mh\u001b[39me\u001b[39ml\u001b[39mp"] 10 | [3.830201, "o", "\u001b[?1l\u001b>"] 11 | [3.832273, "o", "\u001b[?2004l\r\r\n"] 12 | [3.834253, "o", "\u001b]2;/Users/ninanjohn/Trials/gg/target/release/gg --help\u0007\u001b]1;gg\u0007"] 13 | [3.848649, "o", "Git Governance 0.2.1\r\n\r\nUSAGE:\r\n gg [OPTIONS] [SUBCOMMAND]\r\n\r\nFLAGS:\r\n -h, --help Prints help information\r\n -V, --version Prints version information\r\n\r\nOPTIONS:\r\n -c config file to use. Defaults to .ggConf\r\n\r\nSUBCOMMANDS:\r\n clone \r\n create \r\n fetch \r\n help Prints this message or the help of the given subcommand(s)\r\n status \r\n"] 14 | [3.849406, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 15 | [3.849594, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 16 | [3.900338, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \r\n\u001b[1;32m❯\u001b[0m \u001b[K"] 17 | [3.900618, "o", "\u001b[?1h\u001b="] 18 | [3.901087, "o", "\u001b[?2004h"] 19 | [6.201053, "o", "\u001b[?2004l\r\r\n"] 20 | [6.201872, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m \r \r"] 21 | [6.202015, "o", "\u001b]2;ninanjohn@Ninan-2: ~/github.com\u0007\u001b]1;~/github.com\u0007"] 22 | [6.238572, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\r\n\u001b[1;36m~/github.com\u001b[0m \r\n\u001b[1;31m❯\u001b[0m \u001b[K"] 23 | [6.238701, "o", "\u001b[?1h\u001b="] 24 | [6.239147, "o", "\u001b[?2004h"] 25 | [7.468792, "o", "\u001b[?2004l\r\r\n"] 26 | -------------------------------------------------------------------------------- /gifs/mgitstatus vs gg status.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thecasualcoder/gg/ad613d99fdfac36c75fd70054f5eba2fb1074c46/gifs/mgitstatus vs gg status.mp4 -------------------------------------------------------------------------------- /src/branches.rs: -------------------------------------------------------------------------------- 1 | use clap::{App, Arg, SubCommand}; 2 | use colored::*; 3 | use git2::{Error as GitError, Repository}; 4 | use git2::BranchType::Local; 5 | 6 | use crate::input_args::InputArgs; 7 | use std::process; 8 | 9 | pub fn sub_command<'a, 'b>() -> App<'a, 'b> { 10 | SubCommand::with_name("branches") 11 | .arg( 12 | Arg::with_name("repo_path") 13 | .short("r") 14 | .default_value(".") 15 | .takes_value(true) 16 | .help("path of the repo where branches are to be compared. Defaults to '.'"), 17 | ) 18 | .arg( 19 | Arg::with_name("main_branch") 20 | .short("b") 21 | .default_value("origin/master") 22 | .takes_value(true) 23 | .help("the main branch against which other local branches are to be compared. Defaults to 'origin/master'"), 24 | ) 25 | } 26 | 27 | pub fn branches(args: InputArgs) { 28 | let root_path = args.get_root_path("repo_path"); 29 | let matches = args.get_matches(); 30 | let main_branch = matches.value_of("main_branch").unwrap(); 31 | let repo = Repository::open(root_path).expect("Failed to open git repo"); 32 | 33 | let mut git_branches = GitBranches { 34 | repo: repo, 35 | main_branch: String::from(main_branch), 36 | }; 37 | 38 | let branches = git_branches.get_branches().unwrap_or_else(|err| { 39 | println!("{} {}", "Failed to get local branches. Err:".red(), err); 40 | process::exit(1); 41 | }); 42 | 43 | branches 44 | .into_iter() 45 | .for_each(|branch| { 46 | if branch == "master" { 47 | return; 48 | } 49 | git_branches.compare_to_main_branch(branch.as_str()) 50 | }) 51 | } 52 | 53 | pub struct GitBranches { 54 | repo: Repository, 55 | main_branch: String, 56 | } 57 | 58 | impl GitBranches { 59 | fn get_branches(&mut self) -> Result, GitError> { 60 | let local_branches = self.repo.branches(Some(Local))?; 61 | let mut branch_vec = vec![]; 62 | local_branches.for_each(|br| { 63 | let branch_ref = br.expect("Failed to get branch"); 64 | let branch_name = branch_ref.0.name().expect("Failed to get valid name of branch") 65 | .expect("Failed to convert branch name to string"); 66 | branch_vec.push(branch_name.to_string()) 67 | }); 68 | Ok(branch_vec) 69 | } 70 | 71 | fn compare_to_main_branch(&mut self, branch: &str) { 72 | let mut branch_status = vec![]; 73 | self.repo.revparse_single(branch).map_or_else(|_err| { 74 | print!("{} {} {}", "No such branch".red(), branch.red(), "found".red()); 75 | }, |reference|{ 76 | let head_ref = reference.id(); 77 | let (is_ahead, is_behind) = self.repo 78 | .revparse_ext(self.main_branch.as_str()) 79 | .ok() 80 | .and_then(|(upstream, _)| self.repo.graph_ahead_behind(head_ref, upstream.id()).ok()) 81 | .unwrap_or((0, 0)); 82 | 83 | if is_ahead > 0 { 84 | let ahead = format!("{} ahead", is_ahead); 85 | let ahead_string_colored = format!("{}", ahead.green()); 86 | branch_status.push(ahead_string_colored); 87 | } 88 | 89 | if is_behind > 0 { 90 | let behind = format!("{} behind", is_behind); 91 | let behind_string_colored = format!("{}", behind.yellow()); 92 | branch_status.push(behind_string_colored); 93 | } 94 | println!("{} {}: {}", "Branch".blue(), branch.blue(), branch_status.join(", ")); 95 | }); 96 | } 97 | } -------------------------------------------------------------------------------- /src/clone.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use clap::{App, Arg, SubCommand}; 4 | use colored::*; 5 | use git2::build::RepoBuilder; 6 | use git2::{Error as GitError, FetchOptions, RemoteCallbacks}; 7 | use serde::{Deserialize, Serialize}; 8 | 9 | use crate::conf; 10 | use crate::git::GitAction; 11 | use crate::input_args::InputArgs; 12 | use crate::progress::{ProgressReporter, ProgressTracker}; 13 | 14 | #[derive(Debug, Serialize, Deserialize)] 15 | pub struct GitRepo { 16 | #[serde(alias = "remoteURL")] 17 | #[serde(rename = "remoteURL")] 18 | pub remote_url: String, 19 | #[serde(alias = "localPath")] 20 | #[serde(rename = "localPath")] 21 | pub local_path: String, 22 | } 23 | 24 | pub fn sub_command<'a, 'b>() -> App<'a, 'b> { 25 | SubCommand::with_name("clone") 26 | .arg( 27 | Arg::with_name("local_path") 28 | .short("l") 29 | .takes_value(true) 30 | .default_value(".") 31 | .help("path at which to create the local repo. Defaults to '.'"), 32 | ) 33 | .arg( 34 | Arg::with_name("repo_url") 35 | .short("r") 36 | .takes_value(true) 37 | .multiple(true) 38 | .help("the remote git repo url"), 39 | ) 40 | } 41 | 42 | // gg clone -r url1 -r url2 -l local_root_path 43 | // In addition to arguments passed, also check conf file. If 2 entries conflict from file and passed entry, use the passed entry to resolve the conflict. 44 | // Arguments can have only one local path at which to clone. If user wishes multiple paths, they have to use a config file. 45 | // Todo: test conflicting entries from arguments and file. 46 | pub fn clone(args: InputArgs, mut clone_repos: Vec) { 47 | let matches = args.get_matches(); 48 | 49 | let remotes = matches.values_of("repo_url"); 50 | let mut remote_urls: Vec<&str> = vec![]; 51 | if remotes.is_some() { 52 | remote_urls = remotes 53 | .expect("failed parsing remote_urls from user") 54 | .collect(); 55 | println!("{}", "Cloning remotes passed as arguments".blue()); 56 | } else { 57 | println!("{}", "No remotes were passed as arguments.".yellow()) 58 | } 59 | let local_path = matches 60 | .value_of("local_path") 61 | .expect("failed parsing local path from arguments"); 62 | 63 | let mut remotes_from_args: Vec = vec![]; 64 | for remote in remote_urls { 65 | let remote_url_string = remote.to_string(); 66 | let splits = remote_url_string 67 | .split("/") 68 | .map(|s| s.to_string()) 69 | .collect::>() 70 | .last() 71 | .expect("Failed to get repo name from remote URL") 72 | .split(".") 73 | .map(|s| s.to_string()) 74 | .collect::>(); 75 | 76 | let repo = GitRepo { 77 | remote_url: remote_url_string, 78 | local_path: format!("{}/{}", local_path.to_string(), splits[0]), 79 | }; 80 | remotes_from_args.push(repo); 81 | } 82 | 83 | if clone_repos.is_empty() { 84 | println!("{}", "No remotes configured in conf file".yellow()) 85 | } else { 86 | println!("{}", "Cloning remotes configured in conf file".blue()); 87 | remotes_from_args.append(&mut clone_repos); 88 | } 89 | 90 | if remotes_from_args.is_empty() { 91 | println!("{}", "Please configure conf file to clone repositories or pass the necessary values as arguments".blue()) 92 | } 93 | 94 | let multi_bars = ProgressTracker::new(matches.value_of("jobs").and_then(|e| e.parse().ok())); 95 | remotes_from_args 96 | .into_iter() 97 | .map(|remote| GitClone { 98 | use_ssh: remote.remote_url.contains("git@"), 99 | remote_url: remote.remote_url, 100 | local_path: remote.local_path.into(), 101 | }) 102 | .for_each(|clone| multi_bars.start_task(clone)); 103 | 104 | multi_bars.join().unwrap(); 105 | } 106 | 107 | pub struct GitClone { 108 | pub remote_url: String, 109 | pub local_path: PathBuf, 110 | pub use_ssh: bool, 111 | } 112 | 113 | impl GitAction for GitClone { 114 | fn get_name(&self) -> String { 115 | self.remote_url.clone() 116 | } 117 | 118 | fn git_action(&mut self, prog: &ProgressReporter) -> Result { 119 | let mut builder = RepoBuilder::new(); 120 | 121 | let mut fetch_options = FetchOptions::new(); 122 | let mut callback = RemoteCallbacks::new(); 123 | 124 | if self.use_ssh { 125 | callback.credentials(conf::ssh_auth_callback); 126 | } 127 | 128 | callback.transfer_progress(prog.get_callback()); 129 | 130 | fetch_options.remote_callbacks(callback); 131 | builder.fetch_options(fetch_options); 132 | 133 | builder.clone(&self.remote_url, &self.local_path)?; 134 | 135 | Ok(format!( 136 | "{} {} {:#?}", 137 | "Remote repo".green(), 138 | "cloned locally at".green(), 139 | self.local_path.as_os_str() 140 | )) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/conf.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::fs; 3 | use std::path::Path; 4 | 5 | use colored::Colorize; 6 | use git2::{Cred, CredentialType, Error as GitError}; 7 | use regex::Regex; 8 | use crate::SSH_CONF; 9 | use serde::{Deserialize, Serialize}; 10 | 11 | use crate::clone::GitRepo; 12 | 13 | // Todo: This will never be serialized. Try removing Serialize. 14 | #[derive(Debug, Serialize, Deserialize)] 15 | pub struct GGConf { 16 | #[serde(alias = "skipDirectories")] 17 | #[serde(rename = "skipDirectories")] 18 | #[serde(default)] 19 | pub filter_list: Vec, 20 | 21 | #[serde(skip)] 22 | pub filter_list_regex: Vec, 23 | 24 | #[serde(alias = "cloneRepos")] 25 | #[serde(rename = "cloneRepos")] 26 | #[serde(default)] 27 | // Todo: Add validations on this field. It should not allow empty key/values. 28 | pub clone_repos: Vec, 29 | 30 | #[serde(alias = "ssh")] 31 | #[serde(rename = "ssh")] 32 | #[serde(default)] 33 | pub ssh_config: Option, 34 | } 35 | 36 | impl GGConf { 37 | pub fn default() -> GGConf { 38 | GGConf { 39 | filter_list: vec![], 40 | filter_list_regex: vec![], 41 | clone_repos: vec![], 42 | ssh_config: None, 43 | } 44 | } 45 | } 46 | 47 | pub fn read_conf_file(conf_file: &str) -> Result> { 48 | if Path::new(conf_file).exists() { 49 | let file = fs::File::open(conf_file)?; 50 | let mut config: GGConf = serde_yaml::from_reader(file)?; 51 | update_conf_file(&mut config)?; 52 | return Ok(config); 53 | } 54 | let mut default = GGConf::default(); 55 | update_conf_file(&mut default)?; 56 | Ok(default) 57 | } 58 | 59 | fn update_conf_file<'a>(conf: &mut GGConf) -> Result<(), Box> { 60 | create_filter_list(conf)?; 61 | Ok(()) 62 | } 63 | 64 | fn create_filter_list<'a>(conf: &mut GGConf) -> Result<(), Box> { 65 | let mut filter_list = Vec::new(); 66 | let mut filters = conf.filter_list.clone(); 67 | let defaults: Vec = [".idea", ".DS_Store"].iter().map(|&s| s.into()).collect(); 68 | defaults.iter().for_each(|def| { 69 | filters.push(def.to_owned()); 70 | }); 71 | 72 | filters.iter().for_each(|ignore| { 73 | let re = 74 | Regex::new(format!(r".*/{}?*", ignore).as_str()).expect("failed to construct regex"); 75 | filter_list.push(re); 76 | }); 77 | 78 | conf.filter_list = filters; 79 | conf.filter_list_regex = filter_list; 80 | Ok(()) 81 | } 82 | 83 | #[derive(Debug, Serialize, Deserialize, Default)] 84 | pub struct SSHConfig { 85 | #[serde(alias = "privateKey")] 86 | #[serde(rename = "privateKey")] 87 | pub private_key: String, 88 | 89 | pub username: String, 90 | 91 | #[serde(alias = "sshAgent")] 92 | #[serde(rename = "sshAgent")] 93 | #[serde(default)] 94 | pub ssh_agent: bool, 95 | } 96 | 97 | pub fn ssh_auth_callback(_user: &str, _user_from_url: Option<&str>, _cred: CredentialType) -> Result { 98 | let ssh_conf = SSH_CONF.lock().unwrap(); 99 | 100 | if ssh_conf.private_key.is_empty() { 101 | println!("{}", "Please set the private key to be used to authenticate".red()); 102 | } 103 | 104 | if ssh_conf.username.is_empty() { 105 | println!("{}", "Please set the username to be used to authenticate".red()); 106 | } 107 | 108 | if ssh_conf.ssh_agent { 109 | return Cred::ssh_key_from_agent(ssh_conf.username.as_str()); 110 | } 111 | 112 | Cred::ssh_key(ssh_conf.username.as_str(), 113 | None, 114 | Path::new(&ssh_conf.private_key), 115 | None) 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::Write; 3 | 4 | use clap::{App, Arg, SubCommand}; 5 | use colored::*; 6 | use git2::{Repository}; 7 | use regex::Regex; 8 | 9 | use crate::clone::GitRepo; 10 | use crate::conf::{GGConf, SSHConfig}; 11 | use crate::dir::DirectoryTreeOptions; 12 | use crate::input_args::InputArgs; 13 | use crate::SSH_CONF; 14 | 15 | pub fn sub_command<'a, 'b>() -> App<'a, 'b> { 16 | SubCommand::with_name("config") 17 | .arg( 18 | Arg::with_name("root_path") 19 | .short("r") 20 | .default_value(".") 21 | .takes_value(true) 22 | .help("path of the repo where branches are to be compared. Defaults to '.'"), 23 | ).arg( 24 | Arg::with_name("traverse-hidden") 25 | .short("i") 26 | .help("traverse through hidden directories also"), 27 | ) 28 | } 29 | 30 | pub fn config(args: InputArgs, filter_list_regex: Vec, filter_list: Vec, 31 | mut existing_clone_repos: Vec) { 32 | let root_path = args.get_root_path("root_path"); 33 | let root = root_path 34 | .to_str() 35 | .expect(format!("{}", "Error in converting directory to string".red()).as_str()); 36 | let matches = args.get_matches(); 37 | let filter_hidden = matches.is_present("traverse-hidden"); 38 | 39 | let dir_tree_with_options = DirectoryTreeOptions { 40 | filter_list: filter_list_regex.clone(), 41 | filter_hidden, 42 | }; 43 | 44 | let mut git_repos: Vec = Vec::new(); 45 | dir_tree_with_options 46 | .process_directories(root) 47 | .flat_map(|dir| { 48 | dir.ok().and_then(|d| { 49 | if d.file_name().eq(".git") { 50 | d.path().parent().map(|e| e.to_path_buf()) 51 | } else { 52 | None 53 | } 54 | }) 55 | }) 56 | .map(|dir| { 57 | let local_path = dir.clone().to_str().expect("Failed to extract string from path").to_string(); 58 | let repo = Repository::open(dir).expect("Failed to open git repo"); 59 | let remote = repo.find_remote("origin").expect("Failed to get remote with name origin in the repo"); 60 | let remote_url = remote.url(); 61 | 62 | GitRepo { 63 | remote_url: remote_url.expect("Failed to get remote url as string").to_string(), 64 | local_path: local_path, 65 | } 66 | }).for_each(|repo| git_repos.push(repo)); 67 | 68 | git_repos.append(&mut existing_clone_repos); 69 | 70 | let ssh_conf = SSH_CONF.lock().unwrap(); 71 | 72 | let config = SSHConfig { 73 | private_key: ssh_conf.private_key.clone(), 74 | username: ssh_conf.username.clone(), 75 | ssh_agent: ssh_conf.ssh_agent, 76 | }; 77 | 78 | let new_conf = GGConf { 79 | filter_list: filter_list, 80 | filter_list_regex: filter_list_regex, 81 | clone_repos: git_repos, 82 | ssh_config: Some(config), 83 | }; 84 | 85 | let yaml_string = serde_yaml::to_string(&new_conf).expect("Failed to parse yaml string from conf object"); 86 | println!("{}", yaml_string); 87 | let new_path = format!("{}/.ggConf.new.yaml", root); 88 | let mut file = File::create(new_path.clone()).expect("Failed to create new conf file"); 89 | file.write_all(yaml_string.as_bytes()).expect("failed to write ggConf content to new conf file"); 90 | println!("{} {}", "Yaml saved at:".green(), new_path.blue()) 91 | } -------------------------------------------------------------------------------- /src/create.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::error::Error; 3 | use std::{env, process}; 4 | 5 | use clap::{App, Arg, SubCommand}; 6 | use colored::*; 7 | use reqwest::{Client, RequestBuilder}; 8 | 9 | use crate::clone::GitClone; 10 | use crate::input_args::InputArgs; 11 | use crate::progress::ProgressTracker; 12 | 13 | pub fn sub_command<'a, 'b>() -> App<'a, 'b> { 14 | SubCommand::with_name("create") 15 | .arg( 16 | Arg::with_name("repo_path") 17 | .short("r") 18 | .required(true) 19 | .takes_value(true) 20 | .help("path at which to create the local repo. Defaults to '.'"), 21 | ) 22 | .arg( 23 | Arg::with_name("platform") 24 | .short("p") 25 | .default_value("github") 26 | .takes_value(true) 27 | .help("the remote platform for the git repo. Defaults to github"), 28 | ) 29 | .arg( 30 | Arg::with_name("token") 31 | .short("t") 32 | .help("the access token to create the repo remotely"), 33 | ) 34 | } 35 | 36 | pub fn create(args: InputArgs) { 37 | let matches = args.get_matches(); 38 | let root_path = args.get_root_path("repo_path"); 39 | let repo_name = root_path 40 | .to_str() 41 | .expect(format!("{}", "Error in converting directory to string".red()).as_str()); 42 | 43 | let mut token = String::from(matches.value_of("token").unwrap_or("")); 44 | if token == "" { 45 | if env::var("GITHUB_TOKEN").is_err() { 46 | println!( 47 | "{}", 48 | "GITHUB_TOKEN is missing. Set this as a flag using -t or as an env variable".red() 49 | ); 50 | process::exit(1) 51 | } else { 52 | token = env::var("GITHUB_TOKEN").unwrap() 53 | } 54 | } 55 | 56 | let platform = matches.value_of("platform").unwrap(); 57 | 58 | let remote_url = create_remote(token, platform, repo_name).unwrap_or_else(|err| { 59 | println!("{} {}", "Failed creating a remote repo:".red(), err); 60 | process::exit(1); 61 | }); 62 | 63 | let clone = GitClone { 64 | remote_url, 65 | local_path: root_path, 66 | use_ssh: false, 67 | }; 68 | 69 | let multi_bars = ProgressTracker::new(matches.value_of("jobs").and_then(|e| e.parse().ok())); 70 | multi_bars.start_task(clone); 71 | multi_bars.join().unwrap(); 72 | } 73 | 74 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 75 | enum GitPlatform { 76 | Github, 77 | } 78 | 79 | impl GitPlatform { 80 | fn from_str(platform: &str) -> GitPlatform { 81 | match platform { 82 | "github" => GitPlatform::Github, 83 | _ => panic!("{}", "Unsupported platform".red()), 84 | } 85 | } 86 | 87 | fn create_api(&self, client: Client, repo_name: String, token: String) -> RequestBuilder { 88 | match *self { 89 | GitPlatform::Github => { 90 | let mut data = HashMap::new(); 91 | data.insert("name", repo_name); 92 | client 93 | .post("https:/api.github.com/user/repos") 94 | .header("Authorization", format!("token {}", token)) 95 | .header("Accept", "application/vnd.github.v3+json") 96 | .header("Content-Type", "application/json") 97 | .json(&data) 98 | } 99 | } 100 | } 101 | } 102 | 103 | struct GitRemoteRepo { 104 | platform: GitPlatform, 105 | token: String, 106 | repo_name: String, 107 | } 108 | 109 | impl GitRemoteRepo { 110 | fn create(self) -> Result> { 111 | let client = reqwest::Client::new(); 112 | let request_builder = self.platform.create_api(client, self.repo_name, self.token); 113 | let mut response = request_builder.send()?; 114 | let returned_json: serde_json::Value = response.json()?; 115 | let errors = returned_json["errors"] 116 | .as_array() 117 | .unwrap_or(&Vec::new()) 118 | .to_owned(); 119 | if errors.len() > 0 { 120 | let message = errors[0] 121 | .get("message") 122 | .expect("Failed to get error message") 123 | .to_owned(); 124 | println!("{} {:#?}", "Error message:".red(), message.to_string()); 125 | process::exit(1) 126 | } 127 | let url = returned_json["clone_url"] 128 | .as_str() 129 | .expect("Failed to get remote url from response"); 130 | Ok(url.to_owned()) 131 | } 132 | } 133 | 134 | fn create_remote(token: String, platform: &str, repo_name: &str) -> Result> { 135 | let remote_repo = GitRemoteRepo { 136 | platform: GitPlatform::from_str(platform), 137 | token, 138 | repo_name: String::from(repo_name), 139 | }; 140 | remote_repo.create() 141 | } 142 | -------------------------------------------------------------------------------- /src/dir.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | 3 | use regex::Regex; 4 | use walkdir::{DirEntry, WalkDir}; 5 | 6 | pub struct DirectoryTreeOptions { 7 | pub filter_list: Vec, 8 | pub filter_hidden: bool, 9 | } 10 | 11 | impl DirectoryTreeOptions { 12 | fn is_not_hidden(&self, entry: &DirEntry) -> bool { 13 | entry 14 | .file_name() 15 | .to_str() 16 | .map(|file| entry.depth() == 0 || !file.starts_with(".")) 17 | .unwrap_or(false) 18 | } 19 | 20 | pub fn process_directories(self, path: &str) -> impl Iterator> { 21 | WalkDir::new(path) 22 | .follow_links(false) 23 | .contents_first(false) 24 | .same_file_system(true) 25 | .into_iter() 26 | .filter_entry(move |e| { 27 | self.should_filter(e) 28 | .expect(format!("failed to filter for entry {:#?}", e).as_str()) 29 | }) 30 | } 31 | 32 | fn should_filter(&self, entry: &DirEntry) -> Result> { 33 | let path_string = entry 34 | .path() 35 | .to_str() 36 | .expect("could not get path from the entry") 37 | .trim_start_matches("./"); 38 | 39 | if self.filter_hidden { 40 | return Ok(self.is_not_hidden(entry)); 41 | } 42 | 43 | if !entry.path().is_dir() { 44 | return Ok(false); 45 | } 46 | 47 | for ignore in self.filter_list.iter() { 48 | if ignore.is_match(path_string) { 49 | return Ok(false); 50 | } 51 | } 52 | 53 | return Ok(true); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/fetch.rs: -------------------------------------------------------------------------------- 1 | use clap::{App, Arg, SubCommand}; 2 | use colored::*; 3 | use git2::{ 4 | AutotagOption, Error as GitError, FetchOptions, RemoteCallbacks, 5 | Repository, 6 | }; 7 | use regex::Regex; 8 | use std::path::PathBuf; 9 | 10 | use crate::dir::DirectoryTreeOptions; 11 | use crate::git::GitAction; 12 | use crate::input_args::InputArgs; 13 | use crate::progress::{ProgressReporter, ProgressTracker}; 14 | use crate::conf::*; 15 | 16 | pub fn sub_command<'a, 'b>() -> App<'a, 'b> { 17 | SubCommand::with_name("fetch") 18 | .arg(Arg::with_name("PATH") 19 | .short("f") 20 | .takes_value(true) 21 | .help("path at which to fetch the git repos")) 22 | .arg(Arg::with_name("traverse-hidden") 23 | .short("i") 24 | .help("traverse through hidden directories also") 25 | ) 26 | } 27 | 28 | pub fn fetch(args: InputArgs, filter_list: Vec) { 29 | let matches = args.get_matches(); 30 | let filter_hidden = matches.is_present("traverse-hidden"); 31 | 32 | let dir_tree_with_options = DirectoryTreeOptions { 33 | filter_list: filter_list, 34 | filter_hidden: filter_hidden, 35 | }; 36 | 37 | let root_path = args.get_root_path("PATH"); 38 | let root = root_path 39 | .to_str() 40 | .expect(format!("{}", "Error in converting directory to string".red()).as_str()); 41 | 42 | let multi_bars = ProgressTracker::new(matches.value_of("jobs").and_then(|e| e.parse().ok())); 43 | dir_tree_with_options 44 | .process_directories(root) 45 | .flat_map(|dir| { 46 | dir.ok().and_then(|d| { 47 | if d.file_name().eq(".git") { 48 | d.path().parent().map(|e| e.to_path_buf()) 49 | } else { 50 | None 51 | } 52 | }) 53 | }) 54 | .map(|dir| GitFetch { 55 | dir, 56 | remote: "origin".to_string(), 57 | }) 58 | .for_each(|clone| multi_bars.start_task(clone)); 59 | 60 | multi_bars.join().unwrap(); 61 | } 62 | 63 | pub struct GitFetch { 64 | dir: PathBuf, 65 | remote: String, 66 | } 67 | 68 | impl<'a> GitAction for GitFetch { 69 | fn get_name(&self) -> String { 70 | format!("{} from {:?}", self.remote, self.dir) 71 | } 72 | 73 | fn git_action(&mut self, prog: &ProgressReporter) -> Result { 74 | let repo = Repository::open(self.dir.clone())?; 75 | let path = self.dir.parent(); 76 | let remotes = repo.remotes()?; 77 | 78 | let mut remote = if remotes.iter().any(|remote| remote == Some(&self.remote)) { 79 | repo.find_remote(&self.remote) 80 | .or_else(|_| repo.remote_anonymous(&self.remote))? 81 | } else { 82 | // TODO Use proper error handling 83 | return Ok(format!("{} {:#?}", "remote named {} not found for".red(), path)); 84 | }; 85 | let mut cb = RemoteCallbacks::new(); 86 | cb.credentials(ssh_auth_callback); 87 | cb.transfer_progress(prog.get_callback()); 88 | 89 | let mut fetch_options = FetchOptions::new(); 90 | fetch_options.remote_callbacks(cb); 91 | Ok(match remote.download(&[], Some(&mut fetch_options)) { 92 | Err(e) => format!("{} {}", "Failed with error:".red(), e.message()), 93 | Ok(_) => { 94 | let stats = remote.stats(); 95 | let res = if stats.local_objects() > 0 { 96 | format!( 97 | "{} {}/{} {} {} {} {} {}", 98 | "Received".green(), 99 | stats.indexed_objects(), 100 | stats.total_objects(), 101 | "objects in".green(), 102 | stats.received_bytes(), 103 | " bytes (used ".green(), 104 | stats.local_objects(), 105 | "local objects)".green() 106 | ) 107 | } else { 108 | format!( 109 | "{} {}/{} {} {} {}", 110 | "Received".green(), 111 | stats.indexed_objects(), 112 | stats.total_objects(), 113 | "objects in".green(), 114 | stats.received_bytes(), 115 | "bytes".green() 116 | ) 117 | }; 118 | remote.disconnect(); 119 | remote.update_tips(None, true, AutotagOption::Unspecified, None)?; 120 | 121 | res 122 | } 123 | }) 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/git.rs: -------------------------------------------------------------------------------- 1 | use crate::progress::ProgressReporter; 2 | use git2::Error; 3 | 4 | pub trait GitAction { 5 | fn git_action(&mut self, prog: &ProgressReporter) -> Result; 6 | fn get_name(&self) -> String; 7 | 8 | fn do_git_action(&mut self, prog: ProgressReporter) { 9 | prog.start(); 10 | match self.git_action(&prog) { 11 | Ok(res) => prog.finalize(&res), 12 | Err(err) => prog.abandon(err), 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/input_args.rs: -------------------------------------------------------------------------------- 1 | use clap::ArgMatches; 2 | use colored::*; 3 | use std::env::current_dir; 4 | use std::path::{Path, PathBuf}; 5 | use std::process; 6 | 7 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 8 | pub enum InputCommand { 9 | Status, 10 | Create, 11 | Fetch, 12 | Clone, 13 | Branches, 14 | Config, 15 | Error, 16 | } 17 | 18 | impl InputCommand { 19 | fn as_str(&self) -> &'static str { 20 | match *self { 21 | InputCommand::Status => "status", 22 | InputCommand::Create => "create", 23 | InputCommand::Fetch => "fetch", 24 | InputCommand::Clone => "clone", 25 | InputCommand::Branches => "branches", 26 | InputCommand::Config => "config", 27 | _ => "unknown command", 28 | } 29 | } 30 | } 31 | 32 | pub struct InputArgs<'a> { 33 | input_command: InputCommand, 34 | arg_matches: ArgMatches<'a>, 35 | } 36 | 37 | impl<'a> InputArgs<'a> { 38 | pub fn parse_inputs(args: ArgMatches) -> InputArgs { 39 | let subcommand_name = args 40 | .subcommand_name() 41 | .expect("Could not get subcommand name"); 42 | let matches = args 43 | .subcommand_matches(subcommand_name) 44 | .expect("Failed to get arg matches"); 45 | if subcommand_name == InputCommand::Status.as_str() { 46 | InputArgs { 47 | input_command: InputCommand::Status, 48 | arg_matches: matches.to_owned(), 49 | } 50 | } else if subcommand_name == InputCommand::Create.as_str() { 51 | InputArgs { 52 | input_command: InputCommand::Create, 53 | arg_matches: matches.to_owned(), 54 | } 55 | } else if subcommand_name == InputCommand::Fetch.as_str() { 56 | InputArgs { 57 | input_command: InputCommand::Fetch, 58 | arg_matches: matches.to_owned(), 59 | } 60 | } else if subcommand_name == InputCommand::Clone.as_str() { 61 | InputArgs { 62 | input_command: InputCommand::Clone, 63 | arg_matches: matches.to_owned(), 64 | } 65 | } else if subcommand_name == InputCommand::Branches.as_str() { 66 | InputArgs { 67 | input_command: InputCommand::Branches, 68 | arg_matches: matches.to_owned(), 69 | } 70 | } else if subcommand_name == InputCommand::Config.as_str() { 71 | InputArgs { 72 | input_command: InputCommand::Config, 73 | arg_matches: matches.to_owned(), 74 | } 75 | } else { 76 | InputArgs { 77 | input_command: InputCommand::Error, 78 | arg_matches: ArgMatches::default(), 79 | } 80 | } 81 | } 82 | 83 | pub fn input_command(&self) -> InputCommand { 84 | self.input_command 85 | } 86 | 87 | pub fn get_matches(&self) -> &ArgMatches { 88 | &self.arg_matches 89 | } 90 | 91 | pub fn get_root_path(&self, arg_name: &str) -> PathBuf { 92 | match &self.arg_matches.value_of(arg_name) { 93 | Some(path) => Path::new(path).to_path_buf(), 94 | None => current_dir().unwrap_or_else(|err| { 95 | println!("{} {}", "Error accessing current_dir:".red(), err); 96 | process::exit(1); 97 | }), 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![recursion_limit = "128"] 2 | 3 | extern crate clap; 4 | extern crate colored; 5 | extern crate git2; 6 | extern crate lazy_static; 7 | extern crate reqwest; 8 | extern crate serde_yaml; 9 | extern crate walkdir; 10 | 11 | use std::{mem, sync::Mutex}; 12 | use std::process; 13 | 14 | use clap::{crate_version, App, AppSettings, Arg}; 15 | use colored::*; 16 | use lazy_static::lazy_static; 17 | 18 | use crate::conf::SSHConfig; 19 | use crate::input_args::InputCommand; 20 | 21 | mod clone; 22 | mod branches; 23 | mod config; 24 | mod conf; 25 | mod create; 26 | mod dir; 27 | mod fetch; 28 | mod git; 29 | mod input_args; 30 | mod status; 31 | 32 | mod progress; 33 | 34 | lazy_static! { 35 | pub static ref SSH_CONF: Mutex = Mutex::new(SSHConfig{ 36 | private_key: String::from(format!("{}/.ssh/id_rsa", std::env::var("HOME").expect("HOME env not found"))), 37 | ssh_agent: false, 38 | username: String::from("git"), 39 | }); 40 | } 41 | 42 | fn main() { 43 | let app = App::new("Git Governance") 44 | .setting(AppSettings::ArgRequiredElseHelp) 45 | .version(crate_version!()) 46 | .arg( 47 | Arg::with_name("conf") 48 | .short("c") 49 | .global(true) 50 | .takes_value(true) 51 | .help("config file to use. Defaults to .ggConf"), 52 | ) 53 | .arg( 54 | Arg::with_name("jobs") 55 | .short("j") 56 | .global(true) 57 | .takes_value(true) 58 | .help("Specifies the number of jobs to run simultaneously.\ 59 | Set to 1 to go monothread, by default is set to your number of CPUs.") 60 | .validator(|str| { 61 | str.parse() 62 | .map(|_: usize| ()) 63 | .map_err(|err| format!("{}", err)) 64 | }), 65 | ) 66 | .subcommand(status::sub_command()) 67 | .subcommand(create::sub_command()) 68 | .subcommand(fetch::sub_command()) 69 | .subcommand(branches::sub_command()) 70 | .subcommand(config::sub_command()) 71 | .subcommand(clone::sub_command()); 72 | 73 | 74 | let global_matches = app.get_matches(); 75 | 76 | let args = input_args::InputArgs::parse_inputs(global_matches.clone()); 77 | 78 | let conf = conf::read_conf_file(global_matches.value_of("conf").unwrap_or(".ggConf.yaml")) 79 | .unwrap_or_else(|err| { 80 | println!("{} {}", "error while reading conf file:".red(), err.to_string().red()); 81 | process::exit(1) 82 | }); 83 | 84 | if conf.ssh_config.is_some() { 85 | mem::replace( 86 | &mut *SSH_CONF.lock().unwrap(), 87 | conf.ssh_config.unwrap(), 88 | ); 89 | } 90 | 91 | match args.input_command() { 92 | InputCommand::Status => status::status(args, conf.filter_list_regex), 93 | InputCommand::Create => create::create(args), 94 | InputCommand::Branches => branches::branches(args), 95 | InputCommand::Config => config::config(args, conf.filter_list_regex, conf.filter_list, conf.clone_repos), 96 | InputCommand::Clone => clone::clone(args, conf.clone_repos), 97 | InputCommand::Fetch => fetch::fetch(args, conf.filter_list_regex), 98 | InputCommand::Error => {} 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/progress.rs: -------------------------------------------------------------------------------- 1 | use git2::{Error, Progress}; 2 | use indicatif::{HumanBytes, MultiProgress, ProgressBar, ProgressStyle}; 3 | use rayon::ThreadPool; 4 | 5 | use crate::git::GitAction; 6 | 7 | const STYLE_PRELOAD: &str = "{prefix:<40.blue} {spinner} {wide_msg:.cyan}"; 8 | const STYLE_LOAD: &str = "{prefix:<40.blue} {msg} {wide_bar} {percent:>3}% {eta}"; 9 | const STYLE_DONE: &str = "{prefix:<40.blue} {wide_msg} {elapsed_precise}"; 10 | const STYLE_ERROR: &str = "{prefix:<40.blue} {wide_msg:.red}"; 11 | 12 | pub enum ProgressTracker { 13 | MultiThread { 14 | progress: MultiProgress, 15 | pool: ThreadPool, 16 | }, 17 | MonoThread, 18 | } 19 | 20 | impl ProgressTracker { 21 | pub fn new(threading_settings: Option) -> Self { 22 | match threading_settings { 23 | Some(1) => ProgressTracker::MonoThread, 24 | _ => { 25 | let pool = rayon::ThreadPoolBuilder::new() 26 | .num_threads(threading_settings.unwrap_or(0)) 27 | .build() 28 | .unwrap(); 29 | let progress = MultiProgress::new(); 30 | progress.set_move_cursor(true); 31 | ProgressTracker::MultiThread { progress, pool } 32 | } 33 | } 34 | } 35 | 36 | pub fn new_bar(&self, remote_url: &str) -> ProgressReporter { 37 | let mut prog_bar = ProgressBar::new_spinner() 38 | .with_style(ProgressStyle::default_bar().template(STYLE_PRELOAD)); 39 | 40 | // Disable drawing for now (to avoid hitting the draw limit frequency) 41 | prog_bar.set_draw_delta(9); 42 | 43 | if let ProgressTracker::MultiThread { progress, .. } = self { 44 | prog_bar = progress.add(prog_bar); 45 | } 46 | 47 | prog_bar.set_prefix(remote_url); 48 | prog_bar.set_message("Waiting for process to begin"); 49 | 50 | prog_bar.set_draw_delta(0); 51 | prog_bar.tick(); 52 | 53 | ProgressReporter(prog_bar) 54 | } 55 | 56 | pub fn start_task(&self, mut action: impl GitAction + Send + 'static) { 57 | let progress_bar = self.new_bar(&action.get_name()); 58 | 59 | if let ProgressTracker::MultiThread { pool, .. } = self { 60 | pool.spawn(move || action.do_git_action(progress_bar)); 61 | } else { 62 | action.do_git_action(progress_bar); 63 | } 64 | } 65 | 66 | pub fn join(self) -> Result<(), std::io::Error> { 67 | if let ProgressTracker::MultiThread { progress, .. } = self { 68 | progress.join()?; 69 | } 70 | 71 | Ok(()) 72 | } 73 | } 74 | 75 | pub struct ProgressReporter(ProgressBar); 76 | 77 | #[derive(PartialEq)] 78 | enum Step { 79 | Waiting, 80 | Downloading, 81 | Unpacking, 82 | } 83 | 84 | impl ProgressReporter { 85 | pub fn finalize(self, status: &str) { 86 | self.0.set_draw_delta(0); 87 | self.0 88 | .set_style(ProgressStyle::default_bar().template(STYLE_DONE)); 89 | self.0.finish_with_message(status); 90 | } 91 | 92 | pub fn abandon(self, err: Error) { 93 | self.0.set_draw_delta(0); 94 | self.0 95 | .set_style(ProgressStyle::default_bar().template(STYLE_ERROR)); 96 | // self.0.println(format!("{}", err)); 97 | self.0.abandon_with_message(err.message()); 98 | } 99 | 100 | pub fn get_callback<'a>(&'a self) -> impl FnMut(Progress) -> bool + 'a { 101 | let prog_bar = self.0.clone(); 102 | let mut step = Step::Waiting; 103 | 104 | move |p: Progress| { 105 | prog_bar.set_style(ProgressStyle::default_bar().template(STYLE_LOAD)); 106 | prog_bar.set_length(p.total_objects() as u64); 107 | 108 | if p.total_objects() != p.received_objects() { 109 | prog_bar.set_position(p.received_objects() as u64); 110 | prog_bar.set_message(&format!( 111 | "Downloading object ({})", 112 | HumanBytes(p.received_bytes() as u64) 113 | )); 114 | 115 | if step != Step::Downloading { 116 | prog_bar.set_draw_delta(500); 117 | prog_bar.reset_eta(); 118 | step = Step::Downloading; 119 | } 120 | } else { 121 | prog_bar.set_position(p.indexed_objects() as u64); 122 | 123 | if step != Step::Unpacking { 124 | prog_bar.reset_eta(); 125 | prog_bar.set_message("Indexing object"); 126 | step = Step::Unpacking; 127 | } 128 | } 129 | true 130 | } 131 | } 132 | 133 | pub fn start(&self) { 134 | self.0.reset_elapsed(); 135 | self.report_message("Process is about to begin"); 136 | } 137 | 138 | pub fn report_message(&self, msg: &str) { 139 | self.0.set_message(msg); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/status.rs: -------------------------------------------------------------------------------- 1 | use clap::{App, Arg, SubCommand}; 2 | use colored::*; 3 | use git2::{Error as GitError, Repository, StatusOptions}; 4 | use regex::Regex; 5 | use std::path::PathBuf; 6 | 7 | use crate::dir::DirectoryTreeOptions; 8 | use crate::git::GitAction; 9 | use crate::input_args::InputArgs; 10 | use crate::progress::{ProgressReporter, ProgressTracker}; 11 | 12 | pub fn sub_command<'a, 'b>() -> App<'a, 'b> { 13 | SubCommand::with_name("status") 14 | .arg( 15 | Arg::with_name("PATH") 16 | .short("f") 17 | .takes_value(true) 18 | .help("path at which to create the local repo"), 19 | ) 20 | .arg( 21 | Arg::with_name("traverse-hidden") 22 | .short("i") 23 | .help("traverse through hidden directories also"), 24 | ) 25 | } 26 | 27 | pub fn status(args: InputArgs, filter_list: Vec) { 28 | let matches = args.get_matches(); 29 | let filter_hidden = matches.is_present("traverse-hidden"); 30 | 31 | let dir_tree_with_options = DirectoryTreeOptions { 32 | filter_list, 33 | filter_hidden, 34 | }; 35 | 36 | let root_path = args.get_root_path("PATH"); 37 | let root = root_path 38 | .to_str() 39 | .expect(format!("{}", "Error in converting directory to string".red()).as_str()); 40 | 41 | let multi_bars = ProgressTracker::new(matches.value_of("jobs").and_then(|e| e.parse().ok())); 42 | dir_tree_with_options 43 | .process_directories(root) 44 | .flat_map(|dir| { 45 | dir.ok().and_then(|d| { 46 | if d.file_name().eq(".git") { 47 | d.path().parent().map(|e| e.to_path_buf()) 48 | } else { 49 | None 50 | } 51 | }) 52 | }) 53 | .map(|dir| GitStatus { dir }) 54 | .for_each(|status| multi_bars.start_task(status)); 55 | multi_bars.join().unwrap(); 56 | } 57 | 58 | pub struct GitStatus { 59 | dir: PathBuf, 60 | } 61 | 62 | impl<'a> GitAction for GitStatus { 63 | fn get_name(&self) -> String { 64 | self.dir.to_string_lossy().to_string() 65 | } 66 | 67 | fn git_action(&mut self, _progress: &ProgressReporter) -> Result { 68 | let mut opts = StatusOptions::new(); 69 | opts.include_ignored(true) 70 | .include_untracked(true) 71 | .recurse_untracked_dirs(false) 72 | .exclude_submodules(false); 73 | 74 | let repo = Repository::open(self.dir.clone())?; 75 | 76 | let git_statuses = repo.statuses(Some(&mut opts))?; 77 | let mut statuses_in_dir = vec![]; 78 | 79 | for entry in git_statuses 80 | .iter() 81 | .filter(|e| e.status() != git2::Status::CURRENT) 82 | { 83 | let status = &entry.status(); 84 | if git2::Status::is_wt_new(status) { 85 | statuses_in_dir.push("new files".to_string()); 86 | }; 87 | if git2::Status::is_wt_deleted(status) { 88 | statuses_in_dir.push("deletions".to_string()); 89 | }; 90 | if git2::Status::is_wt_renamed(status) { 91 | statuses_in_dir.push("renames".to_string()); 92 | }; 93 | if git2::Status::is_wt_typechange(status) { 94 | statuses_in_dir.push("typechanges".to_string()); 95 | }; 96 | if git2::Status::is_wt_modified(status) { 97 | statuses_in_dir.push("modifications".to_string()); 98 | }; 99 | } 100 | 101 | // Adapted from @Kurt-Bonatz in https://github.com/rust-lang/git2-rs/issues/332#issuecomment-408453956 102 | if repo.revparse_single("HEAD").is_ok() { 103 | let head_ref = repo.revparse_single("HEAD").expect("HEAD not found").id(); 104 | let (is_ahead, is_behind) = repo 105 | .revparse_ext("@{u}") 106 | .ok() 107 | .and_then(|(upstream, _)| repo.graph_ahead_behind(head_ref, upstream.id()).ok()) 108 | .unwrap_or((0, 0)); 109 | 110 | if is_ahead > 0 { 111 | let push_string = format!("{} ahead", is_ahead); 112 | let push_string_colored = format!("{}", push_string.blue()); 113 | statuses_in_dir.push(push_string_colored); 114 | } 115 | 116 | if is_behind > 0 { 117 | let pull_string = format!("{} behind", is_behind); 118 | let pull_string_colored = format!("{}", pull_string.yellow()); 119 | statuses_in_dir.push(pull_string_colored); 120 | } 121 | } 122 | 123 | Ok(if statuses_in_dir.is_empty() { 124 | "no changes".green().to_string() 125 | } else { 126 | statuses_in_dir.sort(); 127 | statuses_in_dir.dedup(); 128 | statuses_in_dir.join(", ").red().to_string() 129 | }) 130 | } 131 | } 132 | --------------------------------------------------------------------------------