├── .github ├── FUNDING.yml └── workflows │ ├── ds.yml │ └── dstopic.yml ├── .gitignore ├── .rustfmt.toml ├── .vscode └── launch.json ├── ARCHITECTURE.md ├── CODE_OF_CONDUCT.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE.md ├── LICENSE-PARITY.md ├── LICENSE-PATRON.md ├── LICENSE.md ├── README.md ├── THIRD-PARTY-NOTICES.md ├── build.rs ├── commands ├── cmd-config │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── cmd-ping │ ├── Cargo.toml │ └── src │ │ └── lib.rs └── cmd-shell │ ├── Cargo.toml │ └── src │ └── lib.rs ├── dstopic ├── .gitignore ├── dist │ └── dstopic.js ├── package-lock.json ├── package.json └── src │ ├── extensions.js │ └── index.js ├── packages ├── ds-api-types │ ├── Cargo.toml │ └── src │ │ ├── entropic_packument.rs │ │ └── lib.rs ├── ds-command │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── ds-config │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── ds-error-context │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── ds-package-arg │ ├── Cargo.toml │ ├── src │ │ ├── lib.rs │ │ ├── parser.rs │ │ └── types.rs │ └── tests │ │ ├── dir.rs │ │ ├── entropic.rs │ │ └── npm.rs └── pick-version │ ├── Cargo.toml │ ├── src │ └── lib.rs │ └── tests │ └── tests.rs └── src ├── lib.rs └── main.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [zkat] 4 | open_collective: entropic 5 | -------------------------------------------------------------------------------- /.github/workflows/ds.yml: -------------------------------------------------------------------------------- 1 | name: Test ds 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - "dstopic/**" 7 | pull_request: 8 | paths-ignore: 9 | - "dstopic/**" 10 | 11 | env: 12 | RUSTFLAGS: -Dwarnings 13 | 14 | jobs: 15 | fmt_and_docs: 16 | name: Check fmt & docs 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: Install Rust 21 | uses: actions-rs/toolchain@v1 22 | with: 23 | profile: minimal 24 | toolchain: stable 25 | components: rustfmt 26 | override: true 27 | - name: rustfmt 28 | run: cargo fmt --all -- --check 29 | - name: docs 30 | run: cargo doc 31 | 32 | build_and_test: 33 | name: Build & Test 34 | runs-on: ${{ matrix.os }} 35 | strategy: 36 | matrix: 37 | rust: ["1.39.0", stable] 38 | os: [ubuntu-latest, macOS-latest, windows-latest] 39 | 40 | steps: 41 | - uses: actions/checkout@v1 42 | - name: Install Rust 43 | uses: actions-rs/toolchain@v1 44 | with: 45 | profile: minimal 46 | toolchain: ${{ matrix.rust }} 47 | components: clippy 48 | override: true 49 | - name: Cache cargo registry 50 | uses: actions/cache@v1 51 | with: 52 | path: ~/.cargo/registry 53 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} 54 | - name: Cache cargo index 55 | uses: actions/cache@v1 56 | with: 57 | path: ~/.cargo/git 58 | key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} 59 | - name: Cache cargo build 60 | uses: actions/cache@v1 61 | with: 62 | path: target 63 | key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} 64 | - name: Check 65 | run: cargo check 66 | - name: Clippy 67 | run: cargo clippy -- -D warnings 68 | - name: Run tests 69 | run: cargo test --verbose 70 | -------------------------------------------------------------------------------- /.github/workflows/dstopic.yml: -------------------------------------------------------------------------------- 1 | name: Test dstopic 2 | 3 | on: 4 | push: 5 | paths: 6 | - ".github/**" 7 | - "dstopic/**" 8 | pull_request: 9 | paths: 10 | - ".github/**" 11 | - "dstopic/**" 12 | 13 | jobs: 14 | test: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | matrix: 18 | node: [13, 12] 19 | os: [ubuntu-latest, macOS-latest, windows-latest] 20 | 21 | steps: 22 | - uses: actions/checkout@v1 23 | - name: Set up node 24 | uses: actions/setup-node@v1 25 | with: 26 | node-version: ${{ matrix.node }} 27 | - name: Get npm cache directory 28 | id: npm-cache 29 | run: | 30 | echo "::set-output name=dir::$(npm config get cache)" 31 | - uses: actions/cache@v1 32 | with: 33 | path: ${{ steps.npm-cache.outputs.dir }} 34 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 35 | restore-keys: | 36 | ${{ runner.os }}-node- 37 | - name: Install dependencies 38 | run: npm ci 39 | working-directory: dstopic 40 | - name: Build ds 41 | run: npm run build 42 | working-directory: dstopic 43 | - name: Run tests 44 | run: npm t 45 | working-directory: dstopic 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | /node_modules 4 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition = "2018" 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "lldb", 9 | "request": "launch", 10 | "name": "Debug unit tests in library 'dstopic'", 11 | "cargo": { 12 | "args": [ 13 | "test", 14 | "--no-run", 15 | "--lib", 16 | "--package=dstopic" 17 | ], 18 | "filter": { 19 | "name": "dstopic", 20 | "kind": "lib" 21 | } 22 | }, 23 | "args": [], 24 | "cwd": "${workspaceFolder}" 25 | }, 26 | { 27 | "type": "lldb", 28 | "request": "launch", 29 | "name": "Debug executable 'dstopic'", 30 | "cargo": { 31 | "args": [ 32 | "build", 33 | "--bin=dstopic", 34 | "--package=dstopic" 35 | ], 36 | "filter": { 37 | "name": "dstopic", 38 | "kind": "bin" 39 | } 40 | }, 41 | "args": [], 42 | "cwd": "${workspaceFolder}" 43 | }, 44 | { 45 | "type": "lldb", 46 | "request": "launch", 47 | "name": "Debug unit tests in executable 'dstopic'", 48 | "cargo": { 49 | "args": [ 50 | "test", 51 | "--no-run", 52 | "--bin=dstopic", 53 | "--package=dstopic" 54 | ], 55 | "filter": { 56 | "name": "dstopic", 57 | "kind": "bin" 58 | } 59 | }, 60 | "args": [], 61 | "cwd": "${workspaceFolder}" 62 | }, 63 | { 64 | "type": "lldb", 65 | "request": "launch", 66 | "name": "Debug unit tests in library 'entropic-client'", 67 | "cargo": { 68 | "args": [ 69 | "test", 70 | "--no-run", 71 | "--lib", 72 | "--package=entropic-client" 73 | ], 74 | "filter": { 75 | "name": "entropic-client", 76 | "kind": "lib" 77 | } 78 | }, 79 | "args": [], 80 | "cwd": "${workspaceFolder}" 81 | }, 82 | { 83 | "type": "lldb", 84 | "request": "launch", 85 | "name": "Debug unit tests in library 'parse-package-arg'", 86 | "cargo": { 87 | "args": [ 88 | "test", 89 | "--no-run", 90 | "--lib", 91 | "--package=parse-package-arg" 92 | ], 93 | "filter": { 94 | "name": "parse-package-arg", 95 | "kind": "lib" 96 | } 97 | }, 98 | "args": [], 99 | "cwd": "${workspaceFolder}" 100 | }, 101 | { 102 | "type": "lldb", 103 | "request": "launch", 104 | "name": "Debug integration test 'parse'", 105 | "cargo": { 106 | "args": [ 107 | "test", 108 | "--no-run", 109 | "--test=parse", 110 | "--package=parse-package-arg" 111 | ], 112 | "filter": { 113 | "name": "parse", 114 | "kind": "test" 115 | } 116 | }, 117 | "args": [], 118 | "cwd": "${workspaceFolder}" 119 | } 120 | ] 121 | } -------------------------------------------------------------------------------- /ARCHITECTURE.md: -------------------------------------------------------------------------------- 1 | # ds/dstopic architecture 2 | 3 | This document gives a super-high-level view of the various components of `ds`, the Entropic CLI. 4 | 5 | It is, right now, only an initial sketch at an architectural design of the overall application, and is split into two halves: `ds`, the Rust client with the bulk of the package management logic; and `dstopic`, the Node wrapper that takes advantage of the work `ds` does to provide a bunch of nice features. 6 | 7 | ## ds 8 | 9 | `ds` is the primary interface for users. It's the actual Rust-based CLI, which runs all the various user-level commands. It wraps [`dstopic`](#dstopic), currently invoking it as a subprocess. 10 | 11 | ### Commands 12 | 13 | These are the actual commands users run on the node-ish side. 14 | 15 | #### `$ ds sh [script.js]` 16 | 17 | This is the replacement for `$ node`. It starts a node process with all the various [node patches](#node-patches) applied. 18 | 19 | #### `$ ds prep` 20 | 21 | Pre-fetches metadata for required packages. 22 | 23 | #### `$ ds rm [pkg...]` 28 | 29 | Removes existing dependencies. Edits Ds.toml. Goes interactive if no arguments passed ot it. 30 | 31 | #### `$ ds check` 36 | 37 | Runs a bunch of checks, except the test suite. 38 | 39 | Implementation: A sketch was written up: https://github.com/npm/tink#--tink-check 40 | 41 | #### `$ ds test` 42 | 43 | Runs the test suite, including `ds check`. 44 | 45 | #### `$ ds unwrap [pkg...]` 46 | 47 | Extracts a package into `node_modules/`, or all dependencies (and their dependencies) if an argument is passed. Only direct dependencies can be passed as arguments. 48 | 49 | Implementation: This needs to invoke the installer, once it exists. 50 | 51 | ### ensure file 52 | 53 | Downloads a specific file by content address from Entropic. Requires metadata that [`ensure package`](#ensure-package) fetches. 54 | 55 | Implementation: This takes a resolved file path into a package and downloads it using the [entropic client](#entropic-client), into the [cache](#cacache-rs). 56 | 57 | ### ensure package 58 | 59 | Makes sure everything needed for a package is available. When a package needs to actually be extracted to `node_modules/` in order to work, this does that. Otherwise, it just fetches metadata and lets individual file fetches be lazy, through [ensure file](#ensure-file). 60 | 61 | Implementation: When the [file resolver](#file-resolver) can't find metadata for a particular package, this is called and uses the [entropic client](#entropic-client) to download the appropriate package metadata, cache it, and return it so resolution can continue. This needs to be a blocking operation if invoked by the file resolver, and an async operation when invoked by the [installer](#installer)/[tree builder](#tree-builder). 62 | 63 | ### installer 64 | 65 | This is the main interface into the "installer" part of the package manager. It contains all the installation logic. (handwave. This needs more fleshing out.) 66 | 67 | Implementation: (handwaves). This is actually a much larger and more nuanced project, and this is just a placeholder. 68 | 69 | ### tree builder 70 | 71 | This is the part of the [installer](#installer) that actually takes care of calculating the target tree. It fetches any missing metadata using the [entropic client](#entropic-client) and builds a data structure representing the final dependency tree. 72 | 73 | Implementation: This is a larger project, but a good starting point would be to prototype the necessary tree data structure and any necessary manipulation methods on that that the installer will need. 74 | 75 | ### script runner 76 | 77 | This runs any required run-scripts. By default, it will prompt if a new package wants to run an install script, and save its result to the lockfile. 78 | 79 | Implementation: This should be a rewrite of https://github.com/npm/npm-lifecycle 80 | 81 | ### entropic client 82 | 83 | This is an http client especially designed to communicate with the entropic registry. For now, this can be any client that supports both sync and async http requests. Long-term, it would be good to have built-in caching support (into [cacache](#cacache-rs)) that's fully http cache spec-compliant. 84 | 85 | Implementation: This will be written using [surf](https://crates.io/crates/surf), and will use [surf-middleware-cache](https://github.com/zkat/surf-middleware-cache) once it's ready. 86 | 87 | ### cacache-rs 88 | 89 | This is the Rust implementation of cacache, a content-addressable cache where all package metadata and individual files for Entropic are stored for fast, easy access. It deduplicates globally by content address, reducing overall storage use. 90 | 91 | ## dstopic 92 | 93 | `dstopic` is the Node side of the package manager. It's a series of patches to Node that enable things like TypeScript support, shared package files, and other stuff. 94 | 95 | ### Node Patches 96 | 97 | The idea behind `ds sh` is that it replaces `node` as your invoked binary, adding various features like not requiring a physical `node_modules/` directory, auto-fetching missing dependency files, etc. In order to achieve this, it loads node and monkey-patches `fs`, as well as adding some new extensions, and hooking up `spawn-wrap` so child processes replicate these patches. 98 | 99 | `dstopic` will invoke `ds` as-needed to make sure all required packages are available. 100 | 101 | #### fs patches 102 | 103 | This patches `fs` and makes it so anything going into `node_modules/` gets redirected over to the central cache, if there's not a physical version of a file at that path. It is unclear right now whether the file resolver this uses should call out to dstopic, or whether the resolver code should be duplicated in both languages for efficiency's sake. 104 | 105 | Implementation: This exists as an external module already, extracted from tink. See https://github.com/npm/fallback-fs 106 | 107 | #### spawn-wrap 108 | 109 | This uses [`spawn-wrap`](https://npm.im/spawn-wrap) to make it so any node child processes also have the Node Patches installed. 110 | 111 | Implementation: Basically copy what tink is doing: https://github.com/npm/tink/blob/latest/lib/node/child_process.js 112 | 113 | #### extensions 114 | 115 | This sets up all the [loaders](#loaders) for the various supported extensions, such as `.ts`, `.jsx`, and esm files. 116 | 117 | Implementation: Mostly copy tink here: https://github.com/npm/tink/blob/latest/lib/node/extensions.js 118 | 119 | ### Loaders 120 | 121 | This sets up various loaders for different kinds of source files: 122 | 123 | - `.ts` - typescript loading, using the typescript compiler 124 | - `.jsx`/`.tsx` - JSX loading, through babel 125 | - `.wasm` - WebAssembly module support, through [`esm`](https://npm.im/esm) 126 | - ESM support - through `esm` as well. 127 | 128 | Implementation: Mostly copy tink here: https://github.com/npm/tink/blob/latest/lib/node/extensions.js 129 | 130 | ### file resolver 131 | 132 | Resolves a path within `node_modules/` into a path into [`cacache-rs`](#cacache-rs). Fetches any missing package metadata as it resolves. 133 | 134 | Implementation: This should be ported to Rust: https://github.com/npm/tink/blob/latest/lib/pkglock.js#L22, and adapted accordingly. 135 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | ## When Something Happens 4 | 5 | If you see a Code of Conduct violation, follow these steps: 6 | 7 | 1. Let the person know that what they did is not appropriate and ask them to stop and/or edit their message(s) or commits. 8 | 2. That person should immediately stop the behavior and correct the issue. 9 | 3. If this doesn’t happen, or if you're uncomfortable speaking up, [contact the maintainers](#contacting-maintainers). 10 | 4. As soon as available, a maintainer will look into the issue, and take [further action (see below)](#further-enforcement), starting with a warning, then temporary block, then long-term repo or organization ban. 11 | 12 | When reporting, please include any relevant details, links, screenshots, context, or other information that may be used to better understand and resolve the situation. 13 | 14 | **The maintainer team will prioritize the well-being and comfort of the recipients of the violation over the comfort of the violator.** See [some examples below](#enforcement-examples). 15 | 16 | ## Our Pledge 17 | 18 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers of this project pledge to making participation in our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, technical preferences, nationality, personal appearance, race, religion, or sexual identity and orientation. 19 | 20 | ## Our Standards 21 | 22 | Examples of behavior that contributes to creating a positive environment include: 23 | 24 | - Using welcoming and inclusive language. 25 | - Being respectful of differing viewpoints and experiences. 26 | - Gracefully accepting constructive feedback. 27 | - Focusing on what is best for the community. 28 | - Showing empathy and kindness towards other community members. 29 | - Encouraging and raising up your peers in the project so you can all bask in hacks and glory. 30 | 31 | Examples of unacceptable behavior by participants include: 32 | 33 | - The use of sexualized language or imagery and unwelcome sexual attention or advances, including when simulated online. The only exception to sexual topics is channels/spaces specifically for topics of sexual identity. 34 | - Casual mention of slavery or indentured servitude and/or false comparisons of one's occupation or situation to slavery. Please consider using or asking about alternate terminology when referring to such metaphors in technology. 35 | - Making light of/making mocking comments about trigger warnings and content warnings. 36 | - Trolling, insulting/derogatory comments, and personal or political attacks. 37 | - Public or private harassment, deliberate intimidation, or threats. 38 | - Publishing others' private information, such as a physical or electronic address, without explicit permission. This includes any sort of "outing" of any aspect of someone's identity without their consent. 39 | - Publishing private screenshots or quotes of interactions in the context of this project without all quoted users' _explicit_ consent. 40 | - Publishing of private communication that doesn't have to do with reporting harrassment. 41 | - Any of the above even when [presented as "ironic" or "joking"](https://en.wikipedia.org/wiki/Hipster_racism). 42 | - Any attempt to present "reverse-ism" versions of the above as violations. Examples of reverse-isms are "reverse racism", "reverse sexism", "heterophobia", and "cisphobia". 43 | - Unsolicited explanations under the assumption that someone doesn't already know it. Ask before you teach! Don't assume what people's knowledge gaps are. 44 | - [Feigning or exaggerating surprise](https://www.recurse.com/manual#no-feigned-surprise) when someone admits to not knowing something. 45 | - "[Well-actuallies](https://www.recurse.com/manual#no-well-actuallys)" 46 | - Other conduct which could reasonably be considered inappropriate in a professional or community setting. 47 | 48 | ## Scope 49 | 50 | This Code of Conduct applies both within spaces involving this project and in other spaces involving community members. This includes the repository, its Pull Requests and Issue tracker, its Twitter community, private email communications in the context of the project, and any events where members of the project are participating, as well as adjacent communities and venues affecting the project's members. 51 | 52 | Depending on the violation, the maintainers may decide that violations of this code of conduct that have happened outside of the scope of the community may deem an individual unwelcome, and take appropriate action to maintain the comfort and safety of its members. 53 | 54 | ### Other Community Standards 55 | 56 | As a project on GitHub, this project is additionally covered by the [GitHub Community Guidelines](https://help.github.com/articles/github-community-guidelines/). 57 | 58 | Additionally, as a project hosted on npm, is is covered by [npm, Inc's Code of Conduct](https://www.npmjs.com/policies/conduct). 59 | 60 | Enforcement of those guidelines after violations overlapping with the above are the responsibility of the entities, and enforcement may happen in any or all of the services/communities. 61 | 62 | ## Maintainer Enforcement Process 63 | 64 | Once the maintainers get involved, they will follow a documented series of steps and do their best to preserve the well-being of project members. This section covers actual concrete steps. 65 | 66 | ### Contacting Maintainers 67 | 68 | Refer to the GitHub repository for collaborator/maintainer information and email someone there. 69 | 70 | ### Further Enforcement 71 | 72 | If you've already followed the [initial enforcement steps](#enforcement), these are the steps maintainers will take for further enforcement, as needed: 73 | 74 | 1. Repeat the request to stop. 75 | 2. If the person doubles down, they will have offending messages removed or edited by a maintainers given an official warning. The PR or Issue may be locked. 76 | 3. If the behavior continues or is repeated later, the person will be blocked from participating for 24 hours. 77 | 4. If the behavior continues or is repeated after the temporary block, a long-term (6-12mo) ban will be used. 78 | 79 | On top of this, maintainers may remove any offending messages, images, contributions, etc, as they deem necessary. 80 | 81 | Maintainers reserve full rights to skip any of these steps, at their discretion, if the violation is considered to be a serious and/or immediate threat to the health and well-being of members of the community. These include any threats, serious physical or verbal attacks, and other such behavior that would be completely unacceptable in any social setting that puts our members at risk. 82 | 83 | Members expelled from events or venues with any sort of paid attendance will not be refunded. 84 | 85 | ### Who Watches the Watchers? 86 | 87 | Maintainers and other leaders who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. These may include anything from removal from the maintainer team to a permanent ban from the community. 88 | 89 | Additionally, as a project hosted on both GitHub and npm, [their own Codes of Conducts may be applied against maintainers of this project](#other-community-standards), externally of this project's procedures. 90 | 91 | ### Enforcement Examples 92 | 93 | #### The Best Case 94 | 95 | The vast majority of situations work out like this. This interaction is common, and generally positive. 96 | 97 | > Alex: "Yeah I used X and it was really crazy!" 98 | 99 | > Patt (not a maintainer): "Hey, could you not use that word? What about 'ridiculous' instead?" 100 | 101 | > Alex: "oh sorry, sure." -> edits old comment to say "it was really confusing!" 102 | 103 | #### The Maintainer Case 104 | 105 | Sometimes, though, you need to get maintainers involved. Maintainers will do their best to resolve conflicts, but people who were harmed by something **will take priority**. 106 | 107 | > Patt: "Honestly, sometimes I just really hate using \$library and anyone who uses it probably sucks at their job." 108 | 109 | > Alex: "Whoa there, could you dial it back a bit? There's a CoC thing about attacking folks' tech use like that." 110 | 111 | > Patt: "I'm not attacking anyone, what's your problem?" 112 | 113 | > Alex: "@maintainers hey uh. Can someone look at this issue? Patt is getting a bit aggro. I tried to nudge them about it, but nope." 114 | 115 | > KeeperOfCommitBits: (on issue) "Hey Patt, maintainer here. Could you tone it down? This sort of attack is really not okay in this space." 116 | 117 | > Patt: "Leave me alone I haven't said anything bad wtf is wrong with you." 118 | 119 | > KeeperOfCommitBits: (deletes user's comment), "@patt I mean it. Please refer to the CoC over at (URL to this CoC) if you have questions, but you can consider this an actual warning. I'd appreciate it if you reworded your messages in this thread, since they made folks there uncomfortable. Let's try and be kind, yeah?" 120 | 121 | > Patt: "@keeperofbits Okay sorry. I'm just frustrated and I'm kinda burnt out and I guess I got carried away. I'll DM Alex a note apologizing and edit my messages. Sorry for the trouble." 122 | 123 | > KeeperOfCommitBits: "@patt Thanks for that. I hear you on the stress. Burnout sucks :/. Have a good one!" 124 | 125 | #### The Nope Case 126 | 127 | > PepeTheFrog🐸: "Hi, I am a literal actual nazi and I think white supremacists are quite fashionable." 128 | 129 | > Patt: "NOOOOPE. OH NOPE NOPE." 130 | 131 | > Alex: "JFC NO. NOPE. @keeperofbits NOPE NOPE LOOK HERE" 132 | 133 | > KeeperOfCommitBits: "👀 Nope. NOPE NOPE NOPE. 🔥" 134 | 135 | > PepeTheFrog🐸 has been banned from all organization or user repositories belonging to KeeperOfCommitBits. 136 | 137 | ## Attribution 138 | 139 | This Code of Conduct was generated using [WeAllJS Code of Conduct Generator](https://npm.im/weallbehave), which is based on the [WeAllJS Code of 140 | Conduct](https://wealljs.org/code-of-conduct), which is itself based on 141 | [Contributor Covenant](http://contributor-covenant.org), version 1.4, available 142 | at 143 | [http://contributor-covenant.org/version/1/4](http://contributor-covenant.org/version/1/4), 144 | and the LGBTQ in Technology Slack [Code of 145 | Conduct](http://lgbtq.technology/coc.html). 146 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "aho-corasick" 5 | version = "0.7.6" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | dependencies = [ 8 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 9 | ] 10 | 11 | [[package]] 12 | name = "ansi_term" 13 | version = "0.11.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | dependencies = [ 16 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 17 | ] 18 | 19 | [[package]] 20 | name = "anyhow" 21 | version = "1.0.25" 22 | source = "registry+https://github.com/rust-lang/crates.io-index" 23 | 24 | [[package]] 25 | name = "arrayref" 26 | version = "0.3.5" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | 29 | [[package]] 30 | name = "arrayvec" 31 | version = "0.4.12" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | dependencies = [ 34 | "nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", 35 | ] 36 | 37 | [[package]] 38 | name = "arrayvec" 39 | version = "0.5.1" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | 42 | [[package]] 43 | name = "assert-json-diff" 44 | version = "1.0.1" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | dependencies = [ 47 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 48 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 49 | ] 50 | 51 | [[package]] 52 | name = "async-attributes" 53 | version = "1.1.1" 54 | source = "registry+https://github.com/rust-lang/crates.io-index" 55 | dependencies = [ 56 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 57 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 58 | ] 59 | 60 | [[package]] 61 | name = "async-macros" 62 | version = "2.0.0" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | dependencies = [ 65 | "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 66 | "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", 67 | ] 68 | 69 | [[package]] 70 | name = "async-std" 71 | version = "1.2.0" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | dependencies = [ 74 | "async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 75 | "async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 76 | "async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 77 | "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 78 | "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 79 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 80 | "futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 81 | "futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 82 | "futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 83 | "kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", 84 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 85 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 86 | "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", 87 | "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", 88 | "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 89 | "once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", 92 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 93 | ] 94 | 95 | [[package]] 96 | name = "async-task" 97 | version = "1.0.0" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | dependencies = [ 100 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 101 | ] 102 | 103 | [[package]] 104 | name = "async-trait" 105 | version = "0.1.19" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | dependencies = [ 108 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 109 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 111 | ] 112 | 113 | [[package]] 114 | name = "atty" 115 | version = "0.2.13" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | dependencies = [ 118 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 119 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 120 | ] 121 | 122 | [[package]] 123 | name = "autocfg" 124 | version = "0.1.7" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | 127 | [[package]] 128 | name = "backtrace" 129 | version = "0.3.40" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | dependencies = [ 132 | "backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", 133 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 134 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 135 | "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 136 | ] 137 | 138 | [[package]] 139 | name = "backtrace-sys" 140 | version = "0.1.32" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | dependencies = [ 143 | "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 145 | ] 146 | 147 | [[package]] 148 | name = "base64" 149 | version = "0.10.1" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | dependencies = [ 152 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 153 | ] 154 | 155 | [[package]] 156 | name = "bitflags" 157 | version = "1.2.1" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | 160 | [[package]] 161 | name = "blake2b_simd" 162 | version = "0.5.9" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | dependencies = [ 165 | "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 166 | "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 167 | "constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 168 | ] 169 | 170 | [[package]] 171 | name = "block-buffer" 172 | version = "0.7.3" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | dependencies = [ 175 | "block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 176 | "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 177 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 178 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 179 | ] 180 | 181 | [[package]] 182 | name = "block-padding" 183 | version = "0.1.5" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | dependencies = [ 186 | "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 187 | ] 188 | 189 | [[package]] 190 | name = "bumpalo" 191 | version = "2.6.0" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | 194 | [[package]] 195 | name = "byte-tools" 196 | version = "0.3.1" 197 | source = "registry+https://github.com/rust-lang/crates.io-index" 198 | 199 | [[package]] 200 | name = "byteorder" 201 | version = "1.3.2" 202 | source = "registry+https://github.com/rust-lang/crates.io-index" 203 | 204 | [[package]] 205 | name = "bytes" 206 | version = "0.4.12" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | dependencies = [ 209 | "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 210 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 211 | ] 212 | 213 | [[package]] 214 | name = "c2-chacha" 215 | version = "0.2.3" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | dependencies = [ 218 | "ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 219 | ] 220 | 221 | [[package]] 222 | name = "cc" 223 | version = "1.0.47" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | 226 | [[package]] 227 | name = "cfg-if" 228 | version = "0.1.10" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | 231 | [[package]] 232 | name = "chrono" 233 | version = "0.4.10" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | dependencies = [ 236 | "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", 237 | "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 238 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 239 | "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", 240 | ] 241 | 242 | [[package]] 243 | name = "clap" 244 | version = "2.33.0" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | dependencies = [ 247 | "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 248 | "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 249 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 250 | "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 251 | "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 252 | "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 253 | "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 254 | ] 255 | 256 | [[package]] 257 | name = "cloudabi" 258 | version = "0.0.3" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | dependencies = [ 261 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 262 | ] 263 | 264 | [[package]] 265 | name = "cmd-config" 266 | version = "0.1.0" 267 | dependencies = [ 268 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 269 | "async-trait 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", 270 | "ds-command 0.1.0", 271 | "ds-config 0.1.0", 272 | "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 273 | ] 274 | 275 | [[package]] 276 | name = "cmd-ping" 277 | version = "0.1.0" 278 | dependencies = [ 279 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 280 | "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 281 | "async-trait 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", 282 | "ds-command 0.1.0", 283 | "ds-error-context 0.1.0", 284 | "mockito 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", 285 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 286 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 287 | "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 288 | "surf 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 289 | "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 290 | ] 291 | 292 | [[package]] 293 | name = "cmd-shell" 294 | version = "0.1.0" 295 | dependencies = [ 296 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 297 | "async-trait 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", 298 | "directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 299 | "ds-command 0.1.0", 300 | "ds-error-context 0.1.0", 301 | "ssri 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 302 | "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 303 | ] 304 | 305 | [[package]] 306 | name = "colored" 307 | version = "1.9.0" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | dependencies = [ 310 | "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 311 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 312 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 313 | ] 314 | 315 | [[package]] 316 | name = "config" 317 | version = "0.9.3" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | dependencies = [ 320 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 321 | "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 322 | "rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", 323 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 324 | "serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 325 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 326 | "toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 327 | "yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", 328 | ] 329 | 330 | [[package]] 331 | name = "constant_time_eq" 332 | version = "0.1.4" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | 335 | [[package]] 336 | name = "crossbeam-channel" 337 | version = "0.3.9" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | dependencies = [ 340 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 341 | ] 342 | 343 | [[package]] 344 | name = "crossbeam-channel" 345 | version = "0.4.0" 346 | source = "registry+https://github.com/rust-lang/crates.io-index" 347 | dependencies = [ 348 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 349 | ] 350 | 351 | [[package]] 352 | name = "crossbeam-deque" 353 | version = "0.7.2" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | dependencies = [ 356 | "crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 357 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 358 | ] 359 | 360 | [[package]] 361 | name = "crossbeam-epoch" 362 | version = "0.8.0" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | dependencies = [ 365 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 366 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 367 | "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 368 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 369 | "memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 370 | "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 371 | ] 372 | 373 | [[package]] 374 | name = "crossbeam-utils" 375 | version = "0.6.6" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | dependencies = [ 378 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 380 | ] 381 | 382 | [[package]] 383 | name = "crossbeam-utils" 384 | version = "0.7.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | dependencies = [ 387 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 388 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 389 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 390 | ] 391 | 392 | [[package]] 393 | name = "curl" 394 | version = "0.4.25" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | dependencies = [ 397 | "curl-sys 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 398 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 399 | "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 400 | "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", 401 | "schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", 402 | "socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", 403 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 404 | ] 405 | 406 | [[package]] 407 | name = "curl-sys" 408 | version = "0.4.24" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | dependencies = [ 411 | "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", 412 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 413 | "libnghttp2-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 415 | "openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)", 416 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 417 | "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 418 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 419 | ] 420 | 421 | [[package]] 422 | name = "derive_more" 423 | version = "0.99.2" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | dependencies = [ 426 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 427 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 428 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 429 | ] 430 | 431 | [[package]] 432 | name = "difference" 433 | version = "2.0.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | 436 | [[package]] 437 | name = "digest" 438 | version = "0.8.1" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | dependencies = [ 441 | "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 442 | ] 443 | 444 | [[package]] 445 | name = "directories" 446 | version = "2.0.2" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | dependencies = [ 449 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 450 | "dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 451 | ] 452 | 453 | [[package]] 454 | name = "dirs-sys" 455 | version = "0.3.4" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | dependencies = [ 458 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 459 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 460 | "redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 461 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 462 | ] 463 | 464 | [[package]] 465 | name = "ds" 466 | version = "0.1.0" 467 | dependencies = [ 468 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 469 | "async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 470 | "async-trait 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", 471 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 472 | "cmd-config 0.1.0", 473 | "cmd-ping 0.1.0", 474 | "cmd-shell 0.1.0", 475 | "ds-command 0.1.0", 476 | "ds-config 0.1.0", 477 | "ds-error-context 0.1.0", 478 | "structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 479 | ] 480 | 481 | [[package]] 482 | name = "ds-api-types" 483 | version = "0.1.0" 484 | dependencies = [ 485 | "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 486 | "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 487 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 488 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 489 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 490 | "ssri 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 491 | ] 492 | 493 | [[package]] 494 | name = "ds-command" 495 | version = "0.1.0" 496 | dependencies = [ 497 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 498 | "async-trait 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)", 499 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 500 | "config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 501 | ] 502 | 503 | [[package]] 504 | name = "ds-config" 505 | version = "0.1.0" 506 | dependencies = [ 507 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 508 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 509 | "config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 510 | "directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 511 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 512 | "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 513 | ] 514 | 515 | [[package]] 516 | name = "ds-error-context" 517 | version = "0.1.0" 518 | dependencies = [ 519 | "derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)", 520 | ] 521 | 522 | [[package]] 523 | name = "ds-package-arg" 524 | version = "0.1.0" 525 | dependencies = [ 526 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 527 | "ds-error-context 0.1.0", 528 | "nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 529 | "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 530 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 531 | "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 532 | "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 533 | ] 534 | 535 | [[package]] 536 | name = "dtoa" 537 | version = "0.4.4" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | 540 | [[package]] 541 | name = "failure" 542 | version = "0.1.6" 543 | source = "registry+https://github.com/rust-lang/crates.io-index" 544 | dependencies = [ 545 | "backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", 546 | "failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 547 | ] 548 | 549 | [[package]] 550 | name = "failure_derive" 551 | version = "0.1.6" 552 | source = "registry+https://github.com/rust-lang/crates.io-index" 553 | dependencies = [ 554 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 555 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 556 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 557 | "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", 558 | ] 559 | 560 | [[package]] 561 | name = "fake-simd" 562 | version = "0.1.2" 563 | source = "registry+https://github.com/rust-lang/crates.io-index" 564 | 565 | [[package]] 566 | name = "fnv" 567 | version = "1.0.6" 568 | source = "registry+https://github.com/rust-lang/crates.io-index" 569 | 570 | [[package]] 571 | name = "fuchsia-cprng" 572 | version = "0.1.1" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | 575 | [[package]] 576 | name = "fuchsia-zircon" 577 | version = "0.3.3" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | dependencies = [ 580 | "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 581 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 582 | ] 583 | 584 | [[package]] 585 | name = "fuchsia-zircon-sys" 586 | version = "0.3.3" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | 589 | [[package]] 590 | name = "futures" 591 | version = "0.1.29" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | 594 | [[package]] 595 | name = "futures-channel-preview" 596 | version = "0.3.0-alpha.19" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | dependencies = [ 599 | "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 600 | "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 601 | ] 602 | 603 | [[package]] 604 | name = "futures-core" 605 | version = "0.3.1" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | 608 | [[package]] 609 | name = "futures-core-preview" 610 | version = "0.3.0-alpha.19" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | 613 | [[package]] 614 | name = "futures-executor-preview" 615 | version = "0.3.0-alpha.19" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | dependencies = [ 618 | "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 619 | "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 620 | "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", 621 | ] 622 | 623 | [[package]] 624 | name = "futures-io" 625 | version = "0.3.1" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | 628 | [[package]] 629 | name = "futures-io-preview" 630 | version = "0.3.0-alpha.19" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | 633 | [[package]] 634 | name = "futures-preview" 635 | version = "0.3.0-alpha.19" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | dependencies = [ 638 | "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 639 | "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 640 | "futures-executor-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 641 | "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 642 | "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 643 | "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 644 | ] 645 | 646 | [[package]] 647 | name = "futures-sink-preview" 648 | version = "0.3.0-alpha.19" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | 651 | [[package]] 652 | name = "futures-timer" 653 | version = "2.0.2" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | 656 | [[package]] 657 | name = "futures-util-preview" 658 | version = "0.3.0-alpha.19" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | dependencies = [ 661 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 662 | "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 663 | "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 664 | "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 665 | "futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 666 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 667 | "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)", 668 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 669 | "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 670 | ] 671 | 672 | [[package]] 673 | name = "generic-array" 674 | version = "0.12.3" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | dependencies = [ 677 | "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", 678 | ] 679 | 680 | [[package]] 681 | name = "getrandom" 682 | version = "0.1.13" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | dependencies = [ 685 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 686 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 687 | "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 688 | ] 689 | 690 | [[package]] 691 | name = "heck" 692 | version = "0.3.1" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | dependencies = [ 695 | "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 696 | ] 697 | 698 | [[package]] 699 | name = "hermit-abi" 700 | version = "0.1.3" 701 | source = "registry+https://github.com/rust-lang/crates.io-index" 702 | dependencies = [ 703 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 704 | ] 705 | 706 | [[package]] 707 | name = "hex" 708 | version = "0.3.2" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | 711 | [[package]] 712 | name = "http" 713 | version = "0.1.20" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | dependencies = [ 716 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 717 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 718 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 719 | ] 720 | 721 | [[package]] 722 | name = "httparse" 723 | version = "1.3.4" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | 726 | [[package]] 727 | name = "idna" 728 | version = "0.2.0" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | dependencies = [ 731 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 732 | "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 733 | "unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 734 | ] 735 | 736 | [[package]] 737 | name = "iovec" 738 | version = "0.1.4" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | dependencies = [ 741 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 742 | ] 743 | 744 | [[package]] 745 | name = "isahc" 746 | version = "0.7.6" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | dependencies = [ 749 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 750 | "crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 751 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 752 | "curl 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)", 753 | "curl-sys 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", 754 | "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 755 | "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 756 | "http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 757 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 758 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 759 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 760 | "sluice 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 761 | ] 762 | 763 | [[package]] 764 | name = "itoa" 765 | version = "0.4.4" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | 768 | [[package]] 769 | name = "js-sys" 770 | version = "0.3.32" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | dependencies = [ 773 | "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 774 | ] 775 | 776 | [[package]] 777 | name = "kernel32-sys" 778 | version = "0.2.2" 779 | source = "registry+https://github.com/rust-lang/crates.io-index" 780 | dependencies = [ 781 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 782 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 783 | ] 784 | 785 | [[package]] 786 | name = "kv-log-macro" 787 | version = "1.0.4" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | dependencies = [ 790 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 791 | ] 792 | 793 | [[package]] 794 | name = "lazy_static" 795 | version = "0.2.11" 796 | source = "registry+https://github.com/rust-lang/crates.io-index" 797 | 798 | [[package]] 799 | name = "lazy_static" 800 | version = "1.4.0" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | 803 | [[package]] 804 | name = "lexical-core" 805 | version = "0.4.6" 806 | source = "registry+https://github.com/rust-lang/crates.io-index" 807 | dependencies = [ 808 | "arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 809 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 810 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 811 | "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 812 | "static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 813 | ] 814 | 815 | [[package]] 816 | name = "libc" 817 | version = "0.2.65" 818 | source = "registry+https://github.com/rust-lang/crates.io-index" 819 | 820 | [[package]] 821 | name = "libnghttp2-sys" 822 | version = "0.1.2" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | dependencies = [ 825 | "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", 826 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 827 | ] 828 | 829 | [[package]] 830 | name = "libz-sys" 831 | version = "1.0.25" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | dependencies = [ 834 | "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", 835 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 836 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 837 | "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 838 | ] 839 | 840 | [[package]] 841 | name = "linked-hash-map" 842 | version = "0.3.0" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | dependencies = [ 845 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 846 | "serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 847 | ] 848 | 849 | [[package]] 850 | name = "linked-hash-map" 851 | version = "0.5.2" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | 854 | [[package]] 855 | name = "log" 856 | version = "0.4.8" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | dependencies = [ 859 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 860 | ] 861 | 862 | [[package]] 863 | name = "maplit" 864 | version = "1.0.2" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | 867 | [[package]] 868 | name = "matches" 869 | version = "0.1.8" 870 | source = "registry+https://github.com/rust-lang/crates.io-index" 871 | 872 | [[package]] 873 | name = "memchr" 874 | version = "2.2.1" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | 877 | [[package]] 878 | name = "memoffset" 879 | version = "0.5.3" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | dependencies = [ 882 | "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 883 | ] 884 | 885 | [[package]] 886 | name = "mime" 887 | version = "0.3.14" 888 | source = "registry+https://github.com/rust-lang/crates.io-index" 889 | 890 | [[package]] 891 | name = "mime_guess" 892 | version = "2.0.1" 893 | source = "registry+https://github.com/rust-lang/crates.io-index" 894 | dependencies = [ 895 | "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 896 | "unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 897 | ] 898 | 899 | [[package]] 900 | name = "mio" 901 | version = "0.6.21" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | dependencies = [ 904 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 905 | "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 906 | "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 907 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 908 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 909 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 910 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 911 | "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 912 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 913 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 914 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 915 | ] 916 | 917 | [[package]] 918 | name = "mio-uds" 919 | version = "0.6.7" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | dependencies = [ 922 | "iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 923 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 924 | "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", 925 | ] 926 | 927 | [[package]] 928 | name = "miow" 929 | version = "0.2.1" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | dependencies = [ 932 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 933 | "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", 934 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 935 | "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 936 | ] 937 | 938 | [[package]] 939 | name = "mockito" 940 | version = "0.22.0" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | dependencies = [ 943 | "assert-json-diff 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 944 | "colored 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 945 | "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 946 | "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 947 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 948 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 949 | "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 950 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 951 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 952 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 953 | ] 954 | 955 | [[package]] 956 | name = "net2" 957 | version = "0.2.33" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | dependencies = [ 960 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 961 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 962 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 963 | ] 964 | 965 | [[package]] 966 | name = "nodrop" 967 | version = "0.1.14" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | 970 | [[package]] 971 | name = "nom" 972 | version = "4.2.3" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | dependencies = [ 975 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 976 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 977 | ] 978 | 979 | [[package]] 980 | name = "nom" 981 | version = "5.0.1" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | dependencies = [ 984 | "lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", 985 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 986 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 987 | ] 988 | 989 | [[package]] 990 | name = "num-integer" 991 | version = "0.1.41" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | dependencies = [ 994 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 995 | "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 996 | ] 997 | 998 | [[package]] 999 | name = "num-traits" 1000 | version = "0.1.43" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | dependencies = [ 1003 | "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 1004 | ] 1005 | 1006 | [[package]] 1007 | name = "num-traits" 1008 | version = "0.2.10" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | dependencies = [ 1011 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1012 | ] 1013 | 1014 | [[package]] 1015 | name = "num_cpus" 1016 | version = "1.11.1" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | dependencies = [ 1019 | "hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1020 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "once_cell" 1025 | version = "1.2.0" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | 1028 | [[package]] 1029 | name = "opaque-debug" 1030 | version = "0.2.3" 1031 | source = "registry+https://github.com/rust-lang/crates.io-index" 1032 | 1033 | [[package]] 1034 | name = "openssl-probe" 1035 | version = "0.1.2" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | 1038 | [[package]] 1039 | name = "openssl-sys" 1040 | version = "0.9.53" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | dependencies = [ 1043 | "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 1044 | "cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)", 1045 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1046 | "pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)", 1047 | "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "percent-encoding" 1052 | version = "1.0.1" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | 1055 | [[package]] 1056 | name = "percent-encoding" 1057 | version = "2.1.0" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | 1060 | [[package]] 1061 | name = "pick-version" 1062 | version = "0.1.0" 1063 | dependencies = [ 1064 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 1065 | "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", 1066 | "ds-api-types 0.1.0", 1067 | "ds-error-context 0.1.0", 1068 | "ds-package-arg 0.1.0", 1069 | "maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1070 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1071 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 1072 | "ssri 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1073 | "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "pin-project-lite" 1078 | version = "0.1.1" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | 1081 | [[package]] 1082 | name = "pin-utils" 1083 | version = "0.1.0-alpha.4" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | 1086 | [[package]] 1087 | name = "pkg-config" 1088 | version = "0.3.17" 1089 | source = "registry+https://github.com/rust-lang/crates.io-index" 1090 | 1091 | [[package]] 1092 | name = "ppv-lite86" 1093 | version = "0.2.6" 1094 | source = "registry+https://github.com/rust-lang/crates.io-index" 1095 | 1096 | [[package]] 1097 | name = "proc-macro-error" 1098 | version = "0.2.6" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | dependencies = [ 1101 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1102 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1103 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "proc-macro2" 1108 | version = "1.0.6" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | dependencies = [ 1111 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "quote" 1116 | version = "1.0.2" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | dependencies = [ 1119 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1120 | ] 1121 | 1122 | [[package]] 1123 | name = "rand" 1124 | version = "0.7.2" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | dependencies = [ 1127 | "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1128 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1129 | "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1130 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1131 | "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1132 | ] 1133 | 1134 | [[package]] 1135 | name = "rand_chacha" 1136 | version = "0.2.1" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | dependencies = [ 1139 | "c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1140 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1141 | ] 1142 | 1143 | [[package]] 1144 | name = "rand_core" 1145 | version = "0.3.1" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | dependencies = [ 1148 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1149 | ] 1150 | 1151 | [[package]] 1152 | name = "rand_core" 1153 | version = "0.4.2" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | 1156 | [[package]] 1157 | name = "rand_core" 1158 | version = "0.5.1" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | dependencies = [ 1161 | "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "rand_hc" 1166 | version = "0.2.0" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | dependencies = [ 1169 | "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "rand_os" 1174 | version = "0.1.3" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | dependencies = [ 1177 | "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 1178 | "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1179 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1180 | "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 1181 | "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1182 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "rdrand" 1187 | version = "0.4.0" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | dependencies = [ 1190 | "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "redox_syscall" 1195 | version = "0.1.56" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | 1198 | [[package]] 1199 | name = "redox_users" 1200 | version = "0.3.1" 1201 | source = "registry+https://github.com/rust-lang/crates.io-index" 1202 | dependencies = [ 1203 | "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1204 | "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1205 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1206 | "rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1207 | ] 1208 | 1209 | [[package]] 1210 | name = "regex" 1211 | version = "1.3.1" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | dependencies = [ 1214 | "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", 1215 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1216 | "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", 1217 | "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "regex-syntax" 1222 | version = "0.6.12" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | 1225 | [[package]] 1226 | name = "remove_dir_all" 1227 | version = "0.5.2" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | dependencies = [ 1230 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1231 | ] 1232 | 1233 | [[package]] 1234 | name = "rust-argon2" 1235 | version = "0.5.1" 1236 | source = "registry+https://github.com/rust-lang/crates.io-index" 1237 | dependencies = [ 1238 | "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1239 | "blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", 1240 | "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", 1241 | ] 1242 | 1243 | [[package]] 1244 | name = "rust-ini" 1245 | version = "0.13.0" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | 1248 | [[package]] 1249 | name = "rustc-demangle" 1250 | version = "0.1.16" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | 1253 | [[package]] 1254 | name = "rustc_version" 1255 | version = "0.2.3" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | dependencies = [ 1258 | "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 1259 | ] 1260 | 1261 | [[package]] 1262 | name = "ryu" 1263 | version = "1.0.2" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | 1266 | [[package]] 1267 | name = "schannel" 1268 | version = "0.1.16" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | dependencies = [ 1271 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1272 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1273 | ] 1274 | 1275 | [[package]] 1276 | name = "scopeguard" 1277 | version = "1.0.0" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | 1280 | [[package]] 1281 | name = "semver" 1282 | version = "0.9.0" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | dependencies = [ 1285 | "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 1286 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "semver-parser" 1291 | version = "0.7.0" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | 1294 | [[package]] 1295 | name = "serde" 1296 | version = "0.8.23" 1297 | source = "registry+https://github.com/rust-lang/crates.io-index" 1298 | 1299 | [[package]] 1300 | name = "serde" 1301 | version = "1.0.103" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | dependencies = [ 1304 | "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "serde-hjson" 1309 | version = "0.8.2" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | dependencies = [ 1312 | "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 1313 | "linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1314 | "num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", 1315 | "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1316 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 1317 | ] 1318 | 1319 | [[package]] 1320 | name = "serde_derive" 1321 | version = "1.0.103" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | dependencies = [ 1324 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1325 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1326 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1327 | ] 1328 | 1329 | [[package]] 1330 | name = "serde_json" 1331 | version = "1.0.44" 1332 | source = "registry+https://github.com/rust-lang/crates.io-index" 1333 | dependencies = [ 1334 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1335 | "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1336 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "serde_test" 1341 | version = "0.8.23" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | dependencies = [ 1344 | "serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)", 1345 | ] 1346 | 1347 | [[package]] 1348 | name = "serde_urlencoded" 1349 | version = "0.6.1" 1350 | source = "registry+https://github.com/rust-lang/crates.io-index" 1351 | dependencies = [ 1352 | "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1353 | "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", 1354 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1355 | "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1356 | ] 1357 | 1358 | [[package]] 1359 | name = "sha-1" 1360 | version = "0.8.1" 1361 | source = "registry+https://github.com/rust-lang/crates.io-index" 1362 | dependencies = [ 1363 | "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1364 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1365 | "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1366 | "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1367 | ] 1368 | 1369 | [[package]] 1370 | name = "sha2" 1371 | version = "0.8.0" 1372 | source = "registry+https://github.com/rust-lang/crates.io-index" 1373 | dependencies = [ 1374 | "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", 1375 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1376 | "fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 1377 | "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "slab" 1382 | version = "0.4.2" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | 1385 | [[package]] 1386 | name = "sluice" 1387 | version = "0.4.2" 1388 | source = "registry+https://github.com/rust-lang/crates.io-index" 1389 | dependencies = [ 1390 | "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 1391 | "futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 1392 | "futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "smallvec" 1397 | version = "1.0.0" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | 1400 | [[package]] 1401 | name = "socket2" 1402 | version = "0.3.11" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | dependencies = [ 1405 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1406 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1407 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1408 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1409 | ] 1410 | 1411 | [[package]] 1412 | name = "sourcefile" 1413 | version = "0.1.4" 1414 | source = "registry+https://github.com/rust-lang/crates.io-index" 1415 | 1416 | [[package]] 1417 | name = "ssri" 1418 | version = "5.0.0" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | dependencies = [ 1421 | "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", 1422 | "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1423 | "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 1424 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1425 | "serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1426 | "sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", 1427 | "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 1428 | "thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "static_assertions" 1433 | version = "0.3.4" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | 1436 | [[package]] 1437 | name = "strsim" 1438 | version = "0.8.0" 1439 | source = "registry+https://github.com/rust-lang/crates.io-index" 1440 | 1441 | [[package]] 1442 | name = "structopt" 1443 | version = "0.3.5" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | dependencies = [ 1446 | "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", 1447 | "structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 1448 | ] 1449 | 1450 | [[package]] 1451 | name = "structopt-derive" 1452 | version = "0.3.5" 1453 | source = "registry+https://github.com/rust-lang/crates.io-index" 1454 | dependencies = [ 1455 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1456 | "proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", 1457 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1458 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1459 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1460 | ] 1461 | 1462 | [[package]] 1463 | name = "surf" 1464 | version = "1.0.3" 1465 | source = "registry+https://github.com/rust-lang/crates.io-index" 1466 | dependencies = [ 1467 | "futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 1468 | "http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", 1469 | "isahc 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", 1470 | "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", 1471 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1472 | "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 1473 | "mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1474 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1475 | "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 1476 | "serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 1477 | "url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1478 | "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1479 | "wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", 1480 | "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", 1481 | ] 1482 | 1483 | [[package]] 1484 | name = "syn" 1485 | version = "1.0.11" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | dependencies = [ 1488 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1489 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1490 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1491 | ] 1492 | 1493 | [[package]] 1494 | name = "synstructure" 1495 | version = "0.12.3" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | dependencies = [ 1498 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1499 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1500 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1501 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1502 | ] 1503 | 1504 | [[package]] 1505 | name = "tempfile" 1506 | version = "3.1.0" 1507 | source = "registry+https://github.com/rust-lang/crates.io-index" 1508 | dependencies = [ 1509 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1510 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1511 | "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", 1512 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1513 | "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1514 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1515 | ] 1516 | 1517 | [[package]] 1518 | name = "textwrap" 1519 | version = "0.11.0" 1520 | source = "registry+https://github.com/rust-lang/crates.io-index" 1521 | dependencies = [ 1522 | "unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 1523 | ] 1524 | 1525 | [[package]] 1526 | name = "thiserror" 1527 | version = "1.0.9" 1528 | source = "registry+https://github.com/rust-lang/crates.io-index" 1529 | dependencies = [ 1530 | "thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "thiserror-impl" 1535 | version = "1.0.9" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | dependencies = [ 1538 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1539 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1540 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1541 | ] 1542 | 1543 | [[package]] 1544 | name = "thread_local" 1545 | version = "0.3.6" 1546 | source = "registry+https://github.com/rust-lang/crates.io-index" 1547 | dependencies = [ 1548 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1549 | ] 1550 | 1551 | [[package]] 1552 | name = "time" 1553 | version = "0.1.42" 1554 | source = "registry+https://github.com/rust-lang/crates.io-index" 1555 | dependencies = [ 1556 | "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", 1557 | "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", 1558 | "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 1559 | ] 1560 | 1561 | [[package]] 1562 | name = "tokio-io" 1563 | version = "0.1.12" 1564 | source = "registry+https://github.com/rust-lang/crates.io-index" 1565 | dependencies = [ 1566 | "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", 1567 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1568 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1569 | ] 1570 | 1571 | [[package]] 1572 | name = "toml" 1573 | version = "0.4.10" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | dependencies = [ 1576 | "serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "typenum" 1581 | version = "1.11.2" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | 1584 | [[package]] 1585 | name = "unicase" 1586 | version = "2.6.0" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | dependencies = [ 1589 | "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", 1590 | ] 1591 | 1592 | [[package]] 1593 | name = "unicode-bidi" 1594 | version = "0.3.4" 1595 | source = "registry+https://github.com/rust-lang/crates.io-index" 1596 | dependencies = [ 1597 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1598 | ] 1599 | 1600 | [[package]] 1601 | name = "unicode-normalization" 1602 | version = "0.1.11" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | dependencies = [ 1605 | "smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1606 | ] 1607 | 1608 | [[package]] 1609 | name = "unicode-segmentation" 1610 | version = "1.6.0" 1611 | source = "registry+https://github.com/rust-lang/crates.io-index" 1612 | 1613 | [[package]] 1614 | name = "unicode-width" 1615 | version = "0.1.6" 1616 | source = "registry+https://github.com/rust-lang/crates.io-index" 1617 | 1618 | [[package]] 1619 | name = "unicode-xid" 1620 | version = "0.2.0" 1621 | source = "registry+https://github.com/rust-lang/crates.io-index" 1622 | 1623 | [[package]] 1624 | name = "url" 1625 | version = "2.1.0" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | dependencies = [ 1628 | "idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 1629 | "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 1630 | "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1631 | ] 1632 | 1633 | [[package]] 1634 | name = "vcpkg" 1635 | version = "0.2.7" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | 1638 | [[package]] 1639 | name = "vec_map" 1640 | version = "0.8.1" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | 1643 | [[package]] 1644 | name = "version_check" 1645 | version = "0.1.5" 1646 | source = "registry+https://github.com/rust-lang/crates.io-index" 1647 | 1648 | [[package]] 1649 | name = "version_check" 1650 | version = "0.9.1" 1651 | source = "registry+https://github.com/rust-lang/crates.io-index" 1652 | 1653 | [[package]] 1654 | name = "wasi" 1655 | version = "0.7.0" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | 1658 | [[package]] 1659 | name = "wasm-bindgen" 1660 | version = "0.2.55" 1661 | source = "registry+https://github.com/rust-lang/crates.io-index" 1662 | dependencies = [ 1663 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1664 | "wasm-bindgen-macro 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1665 | ] 1666 | 1667 | [[package]] 1668 | name = "wasm-bindgen-backend" 1669 | version = "0.2.55" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | dependencies = [ 1672 | "bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 1673 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1674 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1675 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1676 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1677 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1678 | "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1679 | ] 1680 | 1681 | [[package]] 1682 | name = "wasm-bindgen-futures" 1683 | version = "0.3.27" 1684 | source = "registry+https://github.com/rust-lang/crates.io-index" 1685 | dependencies = [ 1686 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 1687 | "futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", 1688 | "futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 1689 | "futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)", 1690 | "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", 1691 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1692 | "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1693 | "web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", 1694 | ] 1695 | 1696 | [[package]] 1697 | name = "wasm-bindgen-macro" 1698 | version = "0.2.55" 1699 | source = "registry+https://github.com/rust-lang/crates.io-index" 1700 | dependencies = [ 1701 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1702 | "wasm-bindgen-macro-support 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1703 | ] 1704 | 1705 | [[package]] 1706 | name = "wasm-bindgen-macro-support" 1707 | version = "0.2.55" 1708 | source = "registry+https://github.com/rust-lang/crates.io-index" 1709 | dependencies = [ 1710 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1711 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1712 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1713 | "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1714 | "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "wasm-bindgen-shared" 1719 | version = "0.2.55" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | 1722 | [[package]] 1723 | name = "wasm-bindgen-webidl" 1724 | version = "0.2.55" 1725 | source = "registry+https://github.com/rust-lang/crates.io-index" 1726 | dependencies = [ 1727 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 1728 | "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1729 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1730 | "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 1731 | "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1732 | "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", 1733 | "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1734 | "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 1735 | ] 1736 | 1737 | [[package]] 1738 | name = "web-sys" 1739 | version = "0.3.32" 1740 | source = "registry+https://github.com/rust-lang/crates.io-index" 1741 | dependencies = [ 1742 | "anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", 1743 | "js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)", 1744 | "sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 1745 | "wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1746 | "wasm-bindgen-webidl 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", 1747 | ] 1748 | 1749 | [[package]] 1750 | name = "weedle" 1751 | version = "0.10.0" 1752 | source = "registry+https://github.com/rust-lang/crates.io-index" 1753 | dependencies = [ 1754 | "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 1755 | ] 1756 | 1757 | [[package]] 1758 | name = "winapi" 1759 | version = "0.2.8" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | 1762 | [[package]] 1763 | name = "winapi" 1764 | version = "0.3.8" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | dependencies = [ 1767 | "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1768 | "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1769 | ] 1770 | 1771 | [[package]] 1772 | name = "winapi-build" 1773 | version = "0.1.1" 1774 | source = "registry+https://github.com/rust-lang/crates.io-index" 1775 | 1776 | [[package]] 1777 | name = "winapi-i686-pc-windows-gnu" 1778 | version = "0.4.0" 1779 | source = "registry+https://github.com/rust-lang/crates.io-index" 1780 | 1781 | [[package]] 1782 | name = "winapi-x86_64-pc-windows-gnu" 1783 | version = "0.4.0" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | 1786 | [[package]] 1787 | name = "ws2_32-sys" 1788 | version = "0.2.1" 1789 | source = "registry+https://github.com/rust-lang/crates.io-index" 1790 | dependencies = [ 1791 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 1792 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 1793 | ] 1794 | 1795 | [[package]] 1796 | name = "yaml-rust" 1797 | version = "0.4.3" 1798 | source = "registry+https://github.com/rust-lang/crates.io-index" 1799 | dependencies = [ 1800 | "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", 1801 | ] 1802 | 1803 | [metadata] 1804 | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" 1805 | "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 1806 | "checksum anyhow 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" 1807 | "checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" 1808 | "checksum arrayvec 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" 1809 | "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 1810 | "checksum assert-json-diff 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9881d306dee755eccf052d652b774a6b2861e86b4772f555262130e58e4f81d2" 1811 | "checksum async-attributes 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" 1812 | "checksum async-macros 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "644a5a8de80f2085a1e7e57cd1544a2a7438f6e003c0790999bd43b92a77cdb2" 1813 | "checksum async-std 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "513ee3c49800679a319912340f5601afda9e72848d7dea3a48bab489e8c1a46f" 1814 | "checksum async-task 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de6bd58f7b9cc49032559422595c81cbfcf04db2f2133592f70af19e258a1ced" 1815 | "checksum async-trait 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3495c8ae99b96d8a84050dee9d7b9d6425f9bfe84c2e3f800c2c2859457f8590" 1816 | "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" 1817 | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 1818 | "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" 1819 | "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" 1820 | "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" 1821 | "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 1822 | "checksum blake2b_simd 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b83b7baab1e671718d78204225800d6b170e648188ac7dc992e9d6bddf87d0c0" 1823 | "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" 1824 | "checksum block-padding 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" 1825 | "checksum bumpalo 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" 1826 | "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" 1827 | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" 1828 | "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" 1829 | "checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" 1830 | "checksum cc 1.0.47 (registry+https://github.com/rust-lang/crates.io-index)" = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" 1831 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 1832 | "checksum chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" 1833 | "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" 1834 | "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" 1835 | "checksum colored 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "433e7ac7d511768127ed85b0c4947f47a254131e37864b2dc13f52aa32cd37e5" 1836 | "checksum config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f9107d78ed62b3fa5a86e7d18e647abed48cfd8f8fab6c72f4cdb982d196f7e6" 1837 | "checksum constant_time_eq 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" 1838 | "checksum crossbeam-channel 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c8ec7fcd21571dc78f96cc96243cab8d8f035247c3efd16c687be154c3fa9efa" 1839 | "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" 1840 | "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" 1841 | "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" 1842 | "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" 1843 | "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" 1844 | "checksum curl 0.4.25 (registry+https://github.com/rust-lang/crates.io-index)" = "06aa71e9208a54def20792d877bc663d6aae0732b9852e612c4a933177c31283" 1845 | "checksum curl-sys 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "f659f3ffac9582d6177bb86d1d2aa649f4eb9d0d4de9d03ccc08b402832ea340" 1846 | "checksum derive_more 0.99.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2159be042979966de68315bce7034bb000c775f22e3e834e1c52ff78f041cae8" 1847 | "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" 1848 | "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" 1849 | "checksum directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" 1850 | "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" 1851 | "checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" 1852 | "checksum failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" 1853 | "checksum failure_derive 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0bc225b78e0391e4b8683440bf2e63c2deeeb2ce5189eab46e2b68c6d3725d08" 1854 | "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" 1855 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 1856 | "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 1857 | "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1858 | "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1859 | "checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" 1860 | "checksum futures-channel-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "d5e5f4df964fa9c1c2f8bddeb5c3611631cacd93baf810fc8bb2fb4b495c263a" 1861 | "checksum futures-core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "79564c427afefab1dfb3298535b21eda083ef7935b4f0ecbfcb121f0aec10866" 1862 | "checksum futures-core-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" 1863 | "checksum futures-executor-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "75236e88bd9fe88e5e8bfcd175b665d0528fe03ca4c5207fabc028c8f9d93e98" 1864 | "checksum futures-io 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" 1865 | "checksum futures-io-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "f4914ae450db1921a56c91bde97a27846287d062087d4a652efc09bb3a01ebda" 1866 | "checksum futures-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "3b1dce2a0267ada5c6ff75a8ba864b4e679a9e2aa44262af7a3b5516d530d76e" 1867 | "checksum futures-sink-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "86f148ef6b69f75bb610d4f9a2336d4fc88c4b5b67129d1a340dd0fd362efeec" 1868 | "checksum futures-timer 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" 1869 | "checksum futures-util-preview 0.3.0-alpha.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" 1870 | "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" 1871 | "checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" 1872 | "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 1873 | "checksum hermit-abi 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" 1874 | "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" 1875 | "checksum http 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "2790658cddc82e82b08e25176c431d7015a0adeb1718498715cbd20138a0bf68" 1876 | "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 1877 | "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1878 | "checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 1879 | "checksum isahc 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "17b77027f12e53ae59a379f7074259d32eb10867e6183388020e922832d9c3fb" 1880 | "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" 1881 | "checksum js-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414" 1882 | "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 1883 | "checksum kv-log-macro 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" 1884 | "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" 1885 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1886 | "checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14" 1887 | "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" 1888 | "checksum libnghttp2-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02254d44f4435dd79e695f2c2b83cd06a47919adea30216ceaf0c57ca0a72463" 1889 | "checksum libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "2eb5e43362e38e2bca2fd5f5134c4d4564a23a5c28e9b95411652021a8675ebe" 1890 | "checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" 1891 | "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" 1892 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1893 | "checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 1894 | "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1895 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1896 | "checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" 1897 | "checksum mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "dd1d63acd1b78403cc0c325605908475dd9b9a3acbf65ed8bcab97e27014afcf" 1898 | "checksum mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a0ed03949aef72dbdf3116a383d7b38b4768e6f960528cd6a6044aa9ed68599" 1899 | "checksum mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)" = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" 1900 | "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" 1901 | "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1902 | "checksum mockito 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4e524e85ea7c80559354217a6470c14abc2411802a9996aed1821559b9e28e3c" 1903 | "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 1904 | "checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" 1905 | "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" 1906 | "checksum nom 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c618b63422da4401283884e6668d39f819a106ef51f5f59b81add00075da35ca" 1907 | "checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" 1908 | "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" 1909 | "checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" 1910 | "checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" 1911 | "checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" 1912 | "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" 1913 | "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 1914 | "checksum openssl-sys 0.9.53 (registry+https://github.com/rust-lang/crates.io-index)" = "465d16ae7fc0e313318f7de5cecf57b2fbe7511fd213978b457e1c96ff46736f" 1915 | "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" 1916 | "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1917 | "checksum pin-project-lite 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991" 1918 | "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587" 1919 | "checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 1920 | "checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" 1921 | "checksum proc-macro-error 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097" 1922 | "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" 1923 | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 1924 | "checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412" 1925 | "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" 1926 | "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" 1927 | "checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" 1928 | "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1929 | "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1930 | "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" 1931 | "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" 1932 | "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 1933 | "checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" 1934 | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" 1935 | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" 1936 | "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 1937 | "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" 1938 | "checksum rust-ini 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" 1939 | "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1940 | "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1941 | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" 1942 | "checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021" 1943 | "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" 1944 | "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1945 | "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1946 | "checksum serde 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" 1947 | "checksum serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" 1948 | "checksum serde-hjson 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b833c5ad67d52ced5f5938b2980f32a9c1c5ef047f0b4fb3127e7a423c76153" 1949 | "checksum serde_derive 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)" = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" 1950 | "checksum serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)" = "48c575e0cc52bdd09b47f330f646cf59afc586e9c4e3ccd6fc1f625b8ea1dad7" 1951 | "checksum serde_test 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)" = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" 1952 | "checksum serde_urlencoded 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" 1953 | "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68" 1954 | "checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d" 1955 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1956 | "checksum sluice 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0a7d06dfb3e8743bc19e6de8a302277471d08077d68946b307280496dc5a3531" 1957 | "checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" 1958 | "checksum socket2 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "e8b74de517221a2cb01a53349cf54182acdc31a074727d3079068448c0676d85" 1959 | "checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3" 1960 | "checksum ssri 5.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e875e58f12c33f832d09cff94b079aee84a48d8188d7a7132b3434358afb70c9" 1961 | "checksum static_assertions 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3" 1962 | "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1963 | "checksum structopt 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3a3e93f5ad553c38b3301c8a0a0cec829a36783f6a0c467fc4bf553a5f5bf" 1964 | "checksum structopt-derive 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea692d40005b3ceba90a9fe7a78fa8d4b82b0ce627eebbffc329aab850f3410e" 1965 | "checksum surf 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "741a8008f8a833ef16f47df94a30754478fb2c2bf822b9c2e6f7f09203b97ace" 1966 | "checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" 1967 | "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" 1968 | "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1969 | "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1970 | "checksum thiserror 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6f357d1814b33bc2dc221243f8424104bfe72dbe911d5b71b3816a2dff1c977e" 1971 | "checksum thiserror-impl 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef" 1972 | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" 1973 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" 1974 | "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" 1975 | "checksum toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" 1976 | "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" 1977 | "checksum unicase 2.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1978 | "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1979 | "checksum unicode-normalization 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b561e267b2326bb4cebfc0ef9e68355c7abe6c6f522aeac2f5bf95d56c59bdcf" 1980 | "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 1981 | "checksum unicode-width 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" 1982 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" 1983 | "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" 1984 | "checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" 1985 | "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" 1986 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 1987 | "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" 1988 | "checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" 1989 | "checksum wasm-bindgen 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "29ae32af33bacd663a9a28241abecf01f2be64e6a185c6139b04f18b6385c5f2" 1990 | "checksum wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "1845584bd3593442dc0de6e6d9f84454a59a057722f36f005e44665d6ab19d85" 1991 | "checksum wasm-bindgen-futures 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c" 1992 | "checksum wasm-bindgen-macro 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "87fcc747e6b73c93d22c947a6334644d22cfec5abd8b66238484dc2b0aeb9fe4" 1993 | "checksum wasm-bindgen-macro-support 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc4b3f2c4078c8c4a5f363b92fcf62604c5913cbd16c6ff5aaf0f74ec03f570" 1994 | "checksum wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "ca0b78d6d3be8589b95d1d49cdc0794728ca734adf36d7c9f07e6459508bb53d" 1995 | "checksum wasm-bindgen-webidl 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)" = "3126356474ceb717c8fb5549ae387c9fbf4872818454f4d87708bee997214bb5" 1996 | "checksum web-sys 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "98405c0a2e722ed3db341b4c5b70eb9fe0021621f7350bab76df93b09b649bbf" 1997 | "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" 1998 | "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1999 | "checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 2000 | "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 2001 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2002 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2003 | "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 2004 | "checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d" 2005 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ds" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | build = "build.rs" 7 | 8 | [dependencies] 9 | # Subcommands 10 | cmd-config = { path = "./commands/cmd-config" } 11 | cmd-ping = { path = "./commands/cmd-ping" } 12 | cmd-shell = { path = "./commands/cmd-shell" } 13 | 14 | # Workspace Deps 15 | ds-command = { path = "./packages/ds-command" } 16 | ds-config = { path = "./packages/ds-config" } 17 | ds-error-context = { path = "./packages/ds-error-context" } 18 | 19 | # Actual Deps 20 | anyhow = "1.0.24" 21 | structopt = "0.3.5" 22 | async-trait = "0.1.19" 23 | async-std = { version = "1.2.0", features = ["attributes"] } 24 | clap = "2.33.0" 25 | 26 | 27 | [workspace] 28 | members = [".", "packages/*", "commands/*"] 29 | default-members = [".", "packages/*", "commands/*"] 30 | 31 | [build-dependencies] 32 | anyhow = "1.0.24" 33 | -------------------------------------------------------------------------------- /LICENSE-APACHE.md: -------------------------------------------------------------------------------- 1 | Copyright 2019 Entropic Contributors 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /LICENSE-PARITY.md: -------------------------------------------------------------------------------- 1 | # The Parity Public License 7.0.0 2 | 3 | Contributor: Kat Marchán 4 | 5 | Source Code: https://github.com/entropic-dev/ds 6 | 7 | ## Purpose 8 | 9 | This license allows you to use and share this software for free, but you have to share software that builds on it alike. 10 | 11 | ## Agreement 12 | 13 | In order to receive this license, you have to agree to its rules. Those rules are both obligations under that agreement and conditions to your license. Don't do anything with this software that triggers a rule you can't or won't follow. 14 | 15 | ## Notices 16 | 17 | Make sure everyone who gets a copy of any part of this software from you, with or without changes, also gets the text of this license and the contributor and source code lines above. 18 | 19 | ## Copyleft 20 | 21 | [Contribute](#contribute) software you develop, operate, or analyze with this software, including changes or additions to this software. When in doubt, [contribute](#contribute). 22 | 23 | ## Prototypes 24 | 25 | You don't have to [contribute](#contribute) any change, addition, or other software that meets all these criteria: 26 | 27 | 1. You don't use it for more than thirty days. 28 | 29 | 2. You don't share it outside the team developing it, other than for non-production user testing. 30 | 31 | 3. You don't develop, operate, or analyze other software with it for anyone outside the team developing it. 32 | 33 | ## Reverse Engineering 34 | 35 | You may use this software to operate and analyze software you can't [contribute](#contribute) in order to develop alternatives you can and do [contribute](#contribute). 36 | 37 | ## Contribute 38 | 39 | To [contribute](#contribute) software: 40 | 41 | 1. Publish all source code for the software in the preferred form for making changes through a freely accessible distribution system widely used for similar source code so the contributor and others can find and copy it. 42 | 43 | 2. Make sure every part of the source code is available under this license or another license that allows everything this license does, such as [the Blue Oak Model License 1.0.0](https://blueoakcouncil.org/license/1.0.0), [the Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0.html), [the MIT license](https://spdx.org/licenses/MIT.html), or [the two-clause BSD license](https://spdx.org/licenses/BSD-2-Clause.html). 44 | 45 | 3. Take these steps within thirty days. 46 | 47 | 4. Note that this license does _not_ allow you to change the license terms for this software. You must follow [Notices](#notices). 48 | 49 | ## Excuse 50 | 51 | You're excused for unknowingly breaking [Copyleft](#copyleft) if you [contribute](#contribute) as required, or stop doing anything requiring this license, within thirty days of learning you broke the rule. You're excused for unknowingly breaking [Notices](#notices) if you take all practical steps to comply within thirty days of learning you broke the rule. 52 | 53 | ## Defense 54 | 55 | Don't make any legal claim against anyone accusing this software, with or without changes, alone or with other technology, of infringing any patent. 56 | 57 | ## Copyright 58 | 59 | The contributor licenses you to do everything with this software that would otherwise infringe their copyright in it. 60 | 61 | ## Patent 62 | 63 | The contributor licenses you to do everything with this software that would otherwise infringe any patents they can license or become able to license. 64 | 65 | ## Reliability 66 | 67 | The contributor can't revoke this license. 68 | 69 | ## No Liability 70 | 71 | **_As far as the law allows, this software comes as is, without any warranty or condition, and the contributor won't be liable to anyone for any damages related to this software or this license, under any kind of legal claim._** 72 | -------------------------------------------------------------------------------- /LICENSE-PATRON.md: -------------------------------------------------------------------------------- 1 | # Patron License 2 | 3 | Payment Platforms: 4 | 5 | - 6 | 7 | Participating Contributors: 8 | 9 | - Kat Marchán 10 | 11 | ## Purpose 12 | 13 | This license gives everyone patronizing contributors to this software permission to ignore any noncommercial or copyleft rules of its free public license, while continuing to protect contributors from liability. 14 | 15 | ## Acceptance 16 | 17 | In order to agree to these terms and receive a license, you must qualify under [Patrons](#patrons). The rules of these terms are both obligations under your agreement and conditions to your license. That agreement and your license continue only while you qualify as a patron. You must not do anything with this software that triggers a rule that you cannot or will not follow. 18 | 19 | ## Patrons 20 | 21 | To accept these terms, you must be enrolled to make regular payments through any of the payment platforms pages listed above, in amounts qualifying you for a tier that includes a "patron license" or otherwise identifies a license under these terms as a reward. 22 | 23 | ## Scope 24 | 25 | Except under [Seat](#seat) and [Applications](#applications), you may not sublicense or transfer any agreement or license under these terms to anyone else. 26 | 27 | ## Seat 28 | 29 | If a legal entity, rather than an individual, accepts these terms, the entity may sublicense one individual employee or independent contractor at any given time. If the employee or contractor breaks any rule of these terms, the entity will stand directly responsible. 30 | 31 | ## Applications 32 | 33 | If you combine this software with other software in a larger application, you may sublicense this software as part of your larger application, and allow further sublicensing in turn, under these rules: 34 | 35 | 1. Your larger application must have significant additional content or functionality beyond that of this software, and end users must license your larger application primarily for that added content or functionality. 36 | 37 | 2. You may not sublicense anyone to break any rule of the public license for this software for any changes of their own or any software besides your larger application. 38 | 39 | 3. You may build, and sublicense for, as many larger applications as you like. 40 | 41 | ## Copyright 42 | 43 | Each contributor licenses you to do everything with this software that would otherwise infringe that contributor's copyright in it. 44 | 45 | ## Notices 46 | 47 | You must ensure that everyone who gets a copy of any part of this software from you, with or without changes, also gets the texts of both this license and the free public license for this software. 48 | 49 | ## Excuse 50 | 51 | If anyone notifies you in writing that you have not complied with [Notices](#notices), you can keep your agreement and your license by taking all practical steps to comply within 30 days after the notice. If you do not do so, your agreement under these terms ends immediately, and your license ends with it. 52 | 53 | ## Patent 54 | 55 | Each contributor licenses you to do everything with this software that would otherwise infringe any patent claims they can license or become able to license. 56 | 57 | ## Reliability 58 | 59 | No contributor can revoke this license, but your license may end if you break any rule of these terms. 60 | 61 | ## No Liability 62 | 63 | **_As far as the law allows, this software comes as is, without any warranty or condition, and no contributor will be liable to anyone for any damages related to this software or this license, under any kind of legal claim._** 64 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2019 Entropic Collaborators and Contributors 2 | 3 | This project is licensed under [the Parity License](LICENSE-PARITY.md). Third-party contributions are licensed under [Apache-2.0](LICENSE-APACHE.md) and belong to their respective authors. 4 | 5 | The Parity License is a copyleft license that, unlike the GPL family, allows you to license derivative and connected works under permissive licenses like MIT or Apache-2.0. It's free to use provided the work you do is freely available! 6 | 7 | For proprietary use, please [contact us](mailto:kzm@zkat.tech?subject=ds%20license), or just [sponsor us on OpenCollective](https://opencollective.com/entropic) under the appropriate tier to [acquire a proprietary-use license](LICENSE-PATRON.md)! This funding model helps us make our work sustainable and compensates us for the work it took to write this code! 8 | 9 | Please note that proprietary licenses will not be granted to any organization working with ICE or the military. The Entropic Collaborators reserve the right to deny licenses or license renewals. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ds 2 | 3 | entropy delta: the entropic client 4 | 5 | This project is in progress. 6 | 7 | ## Supported Rust Versions 8 | 9 | This project supports Rust 1.39.0 and later stable versions. 10 | -------------------------------------------------------------------------------- /THIRD-PARTY-NOTICES.md: -------------------------------------------------------------------------------- 1 | All the code for the javascript code under `dstopic` is licensed as follows: 2 | 3 | Copyright (c) Entropic Contributors. 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | ----- 18 | 19 | Some parts of the dstopic application are also derived from the tink 20 | application, with the following copyright: 21 | 22 | The tink application 23 | Copyright (c) npm, Inc. and Contributors. 24 | Licensed on the terms of The Artistic License 2.0 25 | 26 | """ 27 | The Artistic License 2.0 28 | 29 | Copyright (c) 2000-2006, The Perl Foundation. 30 | 31 | Everyone is permitted to copy and distribute verbatim copies 32 | of this license document, but changing it is not allowed. 33 | 34 | Preamble 35 | 36 | This license establishes the terms under which a given free software 37 | Package may be copied, modified, distributed, and/or redistributed. 38 | The intent is that the Copyright Holder maintains some artistic 39 | control over the development of that Package while still keeping the 40 | Package available as open source and free software. 41 | 42 | You are always permitted to make arrangements wholly outside of this 43 | license directly with the Copyright Holder of a given Package. If the 44 | terms of this license do not permit the full use that you propose to 45 | make of the Package, you should contact the Copyright Holder and seek 46 | a different licensing arrangement. 47 | 48 | Definitions 49 | 50 | "Copyright Holder" means the individual(s) or organization(s) 51 | named in the copyright notice for the entire Package. 52 | 53 | "Contributor" means any party that has contributed code or other 54 | material to the Package, in accordance with the Copyright Holder's 55 | procedures. 56 | 57 | "You" and "your" means any person who would like to copy, 58 | distribute, or modify the Package. 59 | 60 | "Package" means the collection of files distributed by the 61 | Copyright Holder, and derivatives of that collection and/or of 62 | those files. A given Package may consist of either the Standard 63 | Version, or a Modified Version. 64 | 65 | "Distribute" means providing a copy of the Package or making it 66 | accessible to anyone else, or in the case of a company or 67 | organization, to others outside of your company or organization. 68 | 69 | "Distributor Fee" means any fee that you charge for Distributing 70 | this Package or providing support for this Package to another 71 | party. It does not mean licensing fees. 72 | 73 | "Standard Version" refers to the Package if it has not been 74 | modified, or has been modified only in ways explicitly requested 75 | by the Copyright Holder. 76 | 77 | "Modified Version" means the Package, if it has been changed, and 78 | such changes were not explicitly requested by the Copyright 79 | Holder. 80 | 81 | "Original License" means this Artistic License as Distributed with 82 | the Standard Version of the Package, in its current version or as 83 | it may be modified by The Perl Foundation in the future. 84 | 85 | "Source" form means the source code, documentation source, and 86 | configuration files for the Package. 87 | 88 | "Compiled" form means the compiled bytecode, object code, binary, 89 | or any other form resulting from mechanical transformation or 90 | translation of the Source form. 91 | 92 | 93 | Permission for Use and Modification Without Distribution 94 | 95 | (1) You are permitted to use the Standard Version and create and use 96 | Modified Versions for any purpose without restriction, provided that 97 | you do not Distribute the Modified Version. 98 | 99 | 100 | Permissions for Redistribution of the Standard Version 101 | 102 | (2) You may Distribute verbatim copies of the Source form of the 103 | Standard Version of this Package in any medium without restriction, 104 | either gratis or for a Distributor Fee, provided that you duplicate 105 | all of the original copyright notices and associated disclaimers. At 106 | your discretion, such verbatim copies may or may not include a 107 | Compiled form of the Package. 108 | 109 | (3) You may apply any bug fixes, portability changes, and other 110 | modifications made available from the Copyright Holder. The resulting 111 | Package will still be considered the Standard Version, and as such 112 | will be subject to the Original License. 113 | 114 | 115 | Distribution of Modified Versions of the Package as Source 116 | 117 | (4) You may Distribute your Modified Version as Source (either gratis 118 | or for a Distributor Fee, and with or without a Compiled form of the 119 | Modified Version) provided that you clearly document how it differs 120 | from the Standard Version, including, but not limited to, documenting 121 | any non-standard features, executables, or modules, and provided that 122 | you do at least ONE of the following: 123 | 124 | (a) make the Modified Version available to the Copyright Holder 125 | of the Standard Version, under the Original License, so that the 126 | Copyright Holder may include your modifications in the Standard 127 | Version. 128 | 129 | (b) ensure that installation of your Modified Version does not 130 | prevent the user installing or running the Standard Version. In 131 | addition, the Modified Version must bear a name that is different 132 | from the name of the Standard Version. 133 | 134 | (c) allow anyone who receives a copy of the Modified Version to 135 | make the Source form of the Modified Version available to others 136 | under 137 | 138 | (i) the Original License or 139 | 140 | (ii) a license that permits the licensee to freely copy, 141 | modify and redistribute the Modified Version using the same 142 | licensing terms that apply to the copy that the licensee 143 | received, and requires that the Source form of the Modified 144 | Version, and of any works derived from it, be made freely 145 | available in that license fees are prohibited but Distributor 146 | Fees are allowed. 147 | 148 | 149 | Distribution of Compiled Forms of the Standard Version 150 | or Modified Versions without the Source 151 | 152 | (5) You may Distribute Compiled forms of the Standard Version without 153 | the Source, provided that you include complete instructions on how to 154 | get the Source of the Standard Version. Such instructions must be 155 | valid at the time of your distribution. If these instructions, at any 156 | time while you are carrying out such distribution, become invalid, you 157 | must provide new instructions on demand or cease further distribution. 158 | If you provide valid instructions or cease distribution within thirty 159 | days after you become aware that the instructions are invalid, then 160 | you do not forfeit any of your rights under this license. 161 | 162 | (6) You may Distribute a Modified Version in Compiled form without 163 | the Source, provided that you comply with Section 4 with respect to 164 | the Source of the Modified Version. 165 | 166 | 167 | Aggregating or Linking the Package 168 | 169 | (7) You may aggregate the Package (either the Standard Version or 170 | Modified Version) with other packages and Distribute the resulting 171 | aggregation provided that you do not charge a licensing fee for the 172 | Package. Distributor Fees are permitted, and licensing fees for other 173 | components in the aggregation are permitted. The terms of this license 174 | apply to the use and Distribution of the Standard or Modified Versions 175 | as included in the aggregation. 176 | 177 | (8) You are permitted to link Modified and Standard Versions with 178 | other works, to embed the Package in a larger work of your own, or to 179 | build stand-alone binary or bytecode versions of applications that 180 | include the Package, and Distribute the result without restriction, 181 | provided the result does not expose a direct interface to the Package. 182 | 183 | 184 | Items That are Not Considered Part of a Modified Version 185 | 186 | (9) Works (including, but not limited to, modules and scripts) that 187 | merely extend or make use of the Package, do not, by themselves, cause 188 | the Package to be a Modified Version. In addition, such works are not 189 | considered parts of the Package itself, and are not subject to the 190 | terms of this license. 191 | 192 | 193 | General Provisions 194 | 195 | (10) Any use, modification, and distribution of the Standard or 196 | Modified Versions is governed by this Artistic License. By using, 197 | modifying or distributing the Package, you accept this license. Do not 198 | use, modify, or distribute the Package, if you do not accept this 199 | license. 200 | 201 | (11) If your Modified Version has been derived from a Modified 202 | Version made by someone other than you, you are nevertheless required 203 | to ensure that your Modified Version complies with the requirements of 204 | this license. 205 | 206 | (12) This license does not grant you the right to use any trademark, 207 | service mark, tradename, or logo of the Copyright Holder. 208 | 209 | (13) This license includes the non-exclusive, worldwide, 210 | free-of-charge patent license to make, have made, use, offer to sell, 211 | sell, import and otherwise transfer the Package with respect to any 212 | patent claims licensable by the Copyright Holder that are necessarily 213 | infringed by the Package. If you institute patent litigation 214 | (including a cross-claim or counterclaim) against any party alleging 215 | that the Package constitutes direct or contributory patent 216 | infringement, then this Artistic License to you shall terminate on the 217 | date that such litigation is filed. 218 | 219 | (14) Disclaimer of Warranty: 220 | THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS 221 | IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED 222 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 223 | NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL 224 | LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL 225 | BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 226 | DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF 227 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 228 | """ 229 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::fs::{self, File}; 3 | use std::io::Write; 4 | use std::path::Path; 5 | 6 | use anyhow::Result; 7 | 8 | fn main() -> Result<()> { 9 | let out_dir = env::var("OUT_DIR")?; 10 | fs::create_dir_all(&out_dir)?; 11 | let dest_path = Path::new(&out_dir).join("dssh"); 12 | let mut f = File::create(&dest_path)?; 13 | 14 | f.write_all( 15 | b"#!/bin/sh 16 | ./ds sh -- $@ 17 | ", 18 | )?; 19 | Ok(()) 20 | } 21 | -------------------------------------------------------------------------------- /commands/cmd-config/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cmd-config" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | ds-command = { path = "../../packages/ds-command" } 11 | ds-config = { path = "../../packages/ds-config" } 12 | structopt = "0.3.5" 13 | anyhow = "1.0.24" 14 | async-trait = "0.1.19" 15 | -------------------------------------------------------------------------------- /commands/cmd-config/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use anyhow::{anyhow, Result}; 4 | use async_trait::async_trait; 5 | use ds_command::{ArgMatches, Config, DsCommand}; 6 | use ds_config::ConfigOptions; 7 | use structopt::StructOpt; 8 | 9 | #[derive(Debug, StructOpt)] 10 | pub enum ConfigCmd { 11 | #[structopt(about = "Gets a config value.")] 12 | Get { 13 | key: String, 14 | #[structopt(flatten)] 15 | opts: ConfigOpts, 16 | }, 17 | #[structopt(about = "Sets a config value.")] 18 | Set { 19 | key: String, 20 | value: String, 21 | #[structopt(flatten)] 22 | opts: ConfigOpts, 23 | }, 24 | #[structopt(about = "Removes a config value.")] 25 | Rm { 26 | key: String, 27 | #[structopt(flatten)] 28 | opts: ConfigOpts, 29 | }, 30 | } 31 | 32 | #[derive(Debug, StructOpt)] 33 | pub struct ConfigOpts { 34 | #[structopt(long, short)] 35 | local: bool, 36 | #[structopt(long, short)] 37 | global: bool, 38 | #[structopt(skip)] 39 | config: Option, 40 | } 41 | 42 | #[async_trait] 43 | impl DsCommand for ConfigCmd { 44 | fn layer_config(&mut self, args: ArgMatches<'_>, _: Config) -> Result<()> { 45 | match self { 46 | ConfigCmd::Get { ref mut opts, .. } => { 47 | opts.config = if args.is_present("config") { 48 | args.value_of("config").map(PathBuf::from) 49 | } else { 50 | None 51 | }; 52 | Ok(()) 53 | } 54 | _ => Ok(()), 55 | } 56 | } 57 | 58 | async fn execute(mut self) -> Result<()> { 59 | match self { 60 | ConfigCmd::Get { key, opts } => config_read(key, opts)?, 61 | ConfigCmd::Set { .. } => return Err(anyhow!("Command not yet implemented.")), 62 | ConfigCmd::Rm { .. } => return Err(anyhow!("Command not yet implemented.")), 63 | } 64 | Ok(()) 65 | } 66 | } 67 | 68 | fn config_read(key: String, opts: ConfigOpts) -> Result<()> { 69 | let config = if opts.config.is_some() { 70 | ConfigOptions::new() 71 | .env(false) 72 | .local(false) 73 | .global_config_file(opts.config.clone()) 74 | .load()? 75 | } else if opts.global { 76 | ConfigOptions::new() 77 | .env(false) 78 | .local(false) 79 | .global(true) 80 | .load()? 81 | } else if opts.local { 82 | ConfigOptions::new() 83 | .env(false) 84 | .local(true) 85 | .global(false) 86 | .load()? 87 | } else { 88 | ConfigOptions::new() 89 | .env(true) 90 | .local(true) 91 | .global(true) 92 | .load()? 93 | }; 94 | println!("{}", config.get_str(&key)?); 95 | Ok(()) 96 | } 97 | -------------------------------------------------------------------------------- /commands/cmd-ping/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cmd-ping" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | ds-command = { path = "../../packages/ds-command" } 11 | ds-error-context = { path = "../../packages/ds-error-context" } 12 | 13 | surf = "1.0.3" 14 | anyhow = "1.0.25" 15 | structopt = "0.3.5" 16 | url = "2.1.0" 17 | async-trait = "0.1.19" 18 | serde = { version = "1.0.103", features = ["derive"] } 19 | serde_json = "1.0.42" 20 | 21 | [dev-dependencies] 22 | mockito = "0.22.0" 23 | async-std = { version = "1.2.0", features = ["attributes"] } 24 | -------------------------------------------------------------------------------- /commands/cmd-ping/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, Write}; 2 | use std::time::Instant; 3 | 4 | use anyhow::{anyhow, Context, Result}; 5 | use async_trait::async_trait; 6 | use ds_command::{ArgMatches, Config, DsCommand}; 7 | use ds_error_context::DsErrContext as Ctx; 8 | use serde::Deserialize; 9 | use serde_json::Value; 10 | use structopt::StructOpt; 11 | use surf; 12 | use url::Url; 13 | 14 | #[derive(Debug, StructOpt)] 15 | pub struct PingCmd { 16 | #[structopt( 17 | help = "Registry to ping.", 18 | default_value = "https://registry.entropic.dev" 19 | )] 20 | registry: Url, 21 | #[structopt(long, help = "Format output as JSON.")] 22 | json: bool, 23 | } 24 | 25 | #[derive(Debug, Deserialize)] 26 | struct EntropicError { 27 | message: String, 28 | } 29 | 30 | #[async_trait] 31 | impl DsCommand for PingCmd { 32 | fn layer_config(&mut self, args: ArgMatches<'_>, config: Config) -> Result<()> { 33 | if args.occurrences_of("registry") == 0 { 34 | if let Ok(reg) = config.get_str("registry") { 35 | self.registry = Url::parse(®).with_context(|| Ctx::DS1010(reg))?; 36 | } 37 | } 38 | Ok(()) 39 | } 40 | 41 | async fn execute(self) -> Result<()> { 42 | self.ping(io::stdout(), io::stderr()).await 43 | } 44 | } 45 | 46 | impl PingCmd { 47 | async fn ping(self, mut stdout: O, mut stderr: E) -> Result<()> 48 | where 49 | O: Write, 50 | E: Write, 51 | { 52 | writeln!(stderr, "PING: {}", self.registry)?; 53 | let start = Instant::now(); 54 | // This silliness is due to silliness in Surf that should be addressed 55 | // soon. Once it's fixed, this line will just be a nice .await? See: 56 | // https://github.com/dtolnay/anyhow/issues/35#issuecomment-547986739 57 | let mut res = match surf::get(&self.registry).await { 58 | Ok(response) => response, 59 | Err(err) => { 60 | return Err(anyhow!(format!("{:?}", err))) 61 | .with_context(|| Ctx::DS1017(self.registry.to_string())) 62 | } 63 | }; 64 | if res.status().as_u16() >= 400 { 65 | let msg = match res.body_json::().await { 66 | Ok(err) => err.message, 67 | parse_err @ Err(_) => match res.body_string().await { 68 | Ok(msg) => msg, 69 | body_err @ Err(_) => { 70 | return Err(anyhow!("{}", Ctx::DS1016)) 71 | .with_context(|| format!("{:?}", parse_err)) 72 | .with_context(|| format!("{:?}", body_err)) 73 | } 74 | }, 75 | }; 76 | return Err(anyhow!( 77 | "{}", 78 | Ctx::DS1015 { 79 | registry: self.registry.to_string().clone(), 80 | message: msg.clone() 81 | } 82 | )); 83 | } 84 | 85 | let time = start.elapsed().as_millis() as u64; 86 | writeln!(stderr, "PONG: {}ms", time)?; 87 | if self.json { 88 | let details: Value = 89 | serde_json::from_str(&res.body_string().await.unwrap_or("{}".into())) 90 | .context(Ctx::DS1011)?; 91 | writeln!( 92 | stdout, 93 | "{}", 94 | serde_json::to_string_pretty(&serde_json::json!({ 95 | "registry": self.registry.to_string(), 96 | "time": time, 97 | "details": details, 98 | }))? 99 | )?; 100 | } else { 101 | writeln!( 102 | stderr, 103 | "PONG: {}", 104 | res.body_string().await.unwrap_or("".into()) 105 | )?; 106 | } 107 | Ok(()) 108 | } 109 | } 110 | 111 | #[cfg(test)] 112 | mod tests { 113 | use super::*; 114 | 115 | use anyhow::Result; 116 | use async_std; 117 | use mockito::mock; 118 | use serde_json::json; 119 | 120 | #[async_std::test] 121 | async fn basic() -> Result<()> { 122 | let m = mock("GET", "/") 123 | .with_status(200) 124 | .with_body("hello, world!") 125 | .create(); 126 | let registry = &mockito::server_url(); 127 | let mut stdout: Vec = Vec::new(); 128 | let mut stderr: Vec = Vec::new(); 129 | let cmd = PingCmd { 130 | registry: Url::parse(registry)?, 131 | json: false, 132 | }; 133 | cmd.ping(&mut stdout, &mut stderr).await?; 134 | m.assert(); 135 | assert_eq!(String::from_utf8(stdout)?, ""); 136 | let stderr = String::from_utf8(stderr)?; 137 | assert!(stderr.contains(&format!("PING: {}", registry))); 138 | assert!(stderr.contains("PONG:")); 139 | assert!(stderr.contains("hello, world!")); 140 | Ok(()) 141 | } 142 | 143 | #[async_std::test] 144 | async fn json() -> Result<()> { 145 | let m = mock("GET", "/") 146 | .with_status(200) 147 | .with_body(r#"{"message": "hello, world!"}"#) 148 | .create(); 149 | let registry = &mockito::server_url(); 150 | let mut stdout: Vec = Vec::new(); 151 | let mut stderr: Vec = Vec::new(); 152 | let cmd = PingCmd { 153 | registry: Url::parse(registry)?, 154 | json: true, 155 | }; 156 | 157 | cmd.ping(&mut stdout, &mut stderr).await?; 158 | m.assert(); 159 | 160 | let stdout = String::from_utf8(stdout)?; 161 | assert!(stdout.contains(r#""message": "hello, world!""#)); 162 | let mut parsed = serde_json::from_str::(&stdout)?; 163 | assert!(parsed["time"].take().is_number()); 164 | assert_eq!( 165 | parsed, 166 | json!({ 167 | "registry": Url::parse(registry)?.to_string(), 168 | "details": { 169 | "message": "hello, world!" 170 | }, 171 | "time": null, 172 | }) 173 | ); 174 | 175 | let stderr = String::from_utf8(stderr).unwrap(); 176 | assert!(stderr.contains(&format!("PING: {}", registry))); 177 | assert!(stderr.contains("PONG:")); 178 | 179 | Ok(()) 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /commands/cmd-shell/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cmd-shell" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | ds-command = { path = "../../packages/ds-command" } 11 | ds-error-context = { path = "../../packages/ds-error-context" } 12 | 13 | anyhow = "1.0.25" 14 | structopt = "0.3.5" 15 | async-trait = "0.1.19" 16 | directories = "2.0.2" 17 | ssri = "5.0.0" 18 | -------------------------------------------------------------------------------- /commands/cmd-shell/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | use std::process::{self, Command, Stdio}; 3 | use std::{env, fs}; 4 | 5 | use anyhow::{anyhow, Context, Result}; 6 | use async_trait::async_trait; 7 | use directories::ProjectDirs; 8 | use ds_command::{ArgMatches, Config, DsCommand}; 9 | use ds_error_context::DsErrContext as Ctx; 10 | use ssri::Integrity; 11 | use structopt::StructOpt; 12 | 13 | #[derive(Debug, StructOpt)] 14 | pub struct ShellCmd { 15 | #[structopt(long, default_value = "node")] 16 | node: String, 17 | #[structopt(long, hidden = true)] 18 | data_dir: Option, 19 | #[structopt(multiple = true)] 20 | args: Vec, 21 | } 22 | 23 | #[async_trait] 24 | impl DsCommand for ShellCmd { 25 | fn layer_config(&mut self, args: ArgMatches, config: Config) -> Result<()> { 26 | if args.occurrences_of("node") == 0 { 27 | if let Ok(node) = config.get_str("node") { 28 | self.node = node; 29 | } 30 | } 31 | if args.occurrences_of("data_dir") == 0 { 32 | if let Ok(data_dir) = config.get_str("data_dir") { 33 | self.data_dir = Some(PathBuf::from(data_dir)); 34 | } 35 | } 36 | Ok(()) 37 | } 38 | 39 | async fn execute(self) -> Result<()> { 40 | let code = Command::new(&self.node) 41 | .env("DS_BIN", env::current_exe().context(Ctx::DS1000)?) 42 | .arg("-r") 43 | .arg(ensure_dstopic(self.data_dir)?) 44 | .args(self.args) 45 | .stdout(Stdio::inherit()) 46 | .stderr(Stdio::inherit()) 47 | .stdin(Stdio::inherit()) 48 | .status() 49 | .context(Ctx::DS1001(self.node))? 50 | .code() 51 | .unwrap_or(1); 52 | if code > 0 { 53 | process::exit(code); 54 | } 55 | Ok(()) 56 | } 57 | } 58 | 59 | fn ensure_dstopic(dir_override: Option) -> Result { 60 | let dir = match dir_override { 61 | Some(dir) => dir, 62 | None => ProjectDirs::from("dev", "entropic", "ds") 63 | .ok_or_else(|| anyhow!("Couldn't find home directory.")) 64 | .context(Ctx::DS1002)? 65 | .data_dir() 66 | .to_path_buf(), 67 | }; 68 | fs::create_dir_all(&dir).with_context(|| Ctx::DS1003(dir.clone()))?; 69 | let data = include_bytes!("../../../dstopic/dist/dstopic.js").to_vec(); 70 | let hash = Integrity::from(&data).to_hex().1; 71 | let script = dir.join(format!("dstopic-{}", hash.to_string())); 72 | if !script.exists() { 73 | fs::write(&script, &data).with_context(|| Ctx::DS1004(script.clone()))?; 74 | } 75 | Ok(script) 76 | } 77 | -------------------------------------------------------------------------------- /dstopic/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /dstopic/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dstopic", 3 | "private": true, 4 | "version": "1.0.0", 5 | "description": "javascript runtime", 6 | "main": "index.js", 7 | "scripts": { 8 | "build": "webpack --entry ./src/index.js --mode production --target node -o dist/dstopic.js", 9 | "check": "prettier -c ./src/**", 10 | "clean": "rimraf dist", 11 | "format": "prettier --write ./src/**" 12 | }, 13 | "devDependencies": { 14 | "prettier": "^1.18.2", 15 | "rimraf": "^2.6.3", 16 | "webpack": "^4.41.2", 17 | "webpack-cli": "^3.3.10" 18 | }, 19 | "dependencies": { 20 | "babel-core": "^7.0.0-beta.3", 21 | "babel-plugin-transform-react-jsx": "^7.0.0-beta.3", 22 | "babel-plugin-transform-typescript": "^7.0.0-beta.3" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dstopic/src/extensions.js: -------------------------------------------------------------------------------- 1 | const babel = require("babel-core"); 2 | const reactPlugin = require("babel-plugin-transform-react-jsx"); 3 | const tsPlugin = require("babel-plugin-transform-typescript"); 4 | const fs = require("fs"); 5 | const Module = require("module"); 6 | 7 | module.exports.overrideNode = overrideNode; 8 | function overrideNode() { 9 | // These modules are lazy-loaded. 10 | Module._extensions[".jsx"] = (module, filename) => { 11 | const content = fs.readFileSync(filename, "utf8"); 12 | const { code } = babel.transform(content, { 13 | plugins: [ 14 | [ 15 | reactPlugin, 16 | { 17 | useBuiltIns: true 18 | } 19 | ] 20 | ] 21 | }); 22 | module._compile(code, filename); 23 | }; 24 | 25 | Module._extensions[".ts"] = (module, filename) => { 26 | const content = fs.readFileSync(filename, "utf8"); 27 | const { code } = babel.transform(content, { 28 | plugins: [tsPlugin] 29 | }); 30 | module._compile(code, filename); 31 | }; 32 | 33 | Module._extensions[".tsx"] = Module._extensions[".ts"]; 34 | } 35 | -------------------------------------------------------------------------------- /dstopic/src/index.js: -------------------------------------------------------------------------------- 1 | module.exports = overrideNode(); 2 | function overrideNode() { 3 | require("./extensions").overrideNode(); 4 | } 5 | overrideNode(); 6 | -------------------------------------------------------------------------------- /packages/ds-api-types/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ds-api-types" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | chrono = { version = "0.4.10", features = ["serde"] } 11 | semver = { version = "0.9.0", features = ["serde"] } 12 | ssri = "5.0.0" 13 | serde = { version = "1.0.103", features = ["derive"] } 14 | 15 | [dev-dependencies] 16 | maplit = "1.0.2" 17 | serde_json = "1.0.44" 18 | -------------------------------------------------------------------------------- /packages/ds-api-types/src/entropic_packument.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use chrono::prelude::*; 4 | use semver::Version; 5 | use serde::Deserialize; 6 | use ssri::Integrity; 7 | 8 | #[derive(Debug, Deserialize, Clone, PartialEq)] 9 | pub struct EntropicPackument { 10 | #[serde(default = "Utc::now")] 11 | pub created: DateTime, 12 | #[serde(default = "Utc::now")] 13 | pub modified: DateTime, 14 | #[serde(default)] 15 | pub name: String, 16 | #[serde(default)] 17 | pub require_tfa: bool, 18 | #[serde(default = "HashMap::new")] 19 | pub tags: HashMap, 20 | #[serde(default = "HashMap::new")] 21 | pub versions: HashMap, 22 | } 23 | 24 | impl Default for EntropicPackument { 25 | fn default() -> Self { 26 | EntropicPackument { 27 | created: Utc::now(), 28 | modified: Utc::now(), 29 | name: "".into(), 30 | require_tfa: false, 31 | tags: HashMap::new(), 32 | versions: HashMap::new(), 33 | } 34 | } 35 | } 36 | 37 | #[cfg(test)] 38 | mod tests { 39 | use super::*; 40 | 41 | use serde_json; 42 | #[test] 43 | fn empty_object() { 44 | let json = "{}"; 45 | let packument: EntropicPackument = serde_json::from_str(json).unwrap(); 46 | assert_eq!( 47 | packument, 48 | EntropicPackument { 49 | created: packument.created.clone(), 50 | modified: packument.modified.clone(), 51 | ..EntropicPackument::default() 52 | } 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/ds-api-types/src/lib.rs: -------------------------------------------------------------------------------- 1 | mod entropic_packument; 2 | pub use entropic_packument::*; 3 | -------------------------------------------------------------------------------- /packages/ds-command/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ds-command" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | anyhow = "1.0.24" 9 | clap = "2.33.0" 10 | config = "0.9.3" 11 | async-trait = "0.1.19" 12 | 13 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 14 | -------------------------------------------------------------------------------- /packages/ds-command/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use async_trait::async_trait; 3 | pub use clap::ArgMatches; 4 | pub use config::Config; 5 | 6 | #[async_trait] 7 | pub trait DsCommand { 8 | fn layer_config(&mut self, _matches: ArgMatches, _config: Config) -> Result<()> { 9 | Ok(()) 10 | } 11 | async fn execute(self) -> Result<()>; 12 | } 13 | -------------------------------------------------------------------------------- /packages/ds-config/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ds-config" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | config = { version = "0.9.3", features = ["toml"] } 11 | serde = { version = "1.0.103", features = ["derive"] } 12 | directories = "2.0.2" 13 | anyhow = "1.0.24" 14 | clap = "2.33.0" 15 | 16 | [dev-dependencies] 17 | tempfile = "3.1.0" 18 | -------------------------------------------------------------------------------- /packages/ds-config/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::path::PathBuf; 3 | 4 | use anyhow::Result; 5 | pub use config::Config; 6 | use config::{ConfigError, Environment, File}; 7 | use directories::ProjectDirs; 8 | 9 | pub struct ConfigOptions { 10 | global: bool, 11 | local: bool, 12 | env: bool, 13 | local_config_dir: Option, 14 | global_config_file: Option, 15 | } 16 | 17 | impl Default for ConfigOptions { 18 | fn default() -> Self { 19 | ConfigOptions { 20 | global: true, 21 | local: true, 22 | env: true, 23 | local_config_dir: env::current_dir().ok().map(|d| d.to_owned()), 24 | global_config_file: ProjectDirs::from("dev", "entropic", "ds") 25 | .map(|d| d.config_dir().to_owned().join("dsrc.toml")), 26 | } 27 | } 28 | } 29 | 30 | impl ConfigOptions { 31 | pub fn new() -> Self { 32 | Self::default() 33 | } 34 | 35 | pub fn local(mut self, local: bool) -> Self { 36 | self.local = local; 37 | self 38 | } 39 | 40 | pub fn global(mut self, global: bool) -> Self { 41 | self.global = global; 42 | self 43 | } 44 | 45 | pub fn env(mut self, env: bool) -> Self { 46 | self.env = env; 47 | self 48 | } 49 | 50 | pub fn local_config_dir(mut self, dir: Option) -> Self { 51 | self.local_config_dir = dir; 52 | self 53 | } 54 | 55 | pub fn global_config_file(mut self, file: Option) -> Self { 56 | self.global_config_file = file; 57 | self 58 | } 59 | 60 | pub fn load(self) -> Result { 61 | let mut c = Config::new(); 62 | if self.global { 63 | if let Some(config_file) = self.global_config_file { 64 | let path = config_file.display().to_string(); 65 | c.merge(File::with_name(&path[..]).required(false))?; 66 | } 67 | } 68 | if self.local { 69 | if let Some(dir) = self.local_config_dir { 70 | for path in dir.ancestors().collect::>().iter().rev() { 71 | let p = path.join("dsrc").display().to_string(); 72 | c.merge(File::with_name(&p[..]).required(false))?; 73 | let p = path.join(".dsrc").display().to_string(); 74 | c.merge(File::with_name(&p[..]).required(false))?; 75 | } 76 | } 77 | } 78 | if self.env { 79 | c.merge(Environment::with_prefix("ds_config"))?; 80 | } 81 | Ok(c) 82 | } 83 | } 84 | 85 | #[cfg(test)] 86 | mod tests { 87 | use super::*; 88 | 89 | use std::env; 90 | use std::fs; 91 | 92 | use anyhow::Result; 93 | use tempfile::tempdir; 94 | 95 | #[test] 96 | fn working_dir_config() -> Result<()> { 97 | let dir = tempdir()?; 98 | let file = dir.path().join("dsrc.toml"); 99 | fs::write(file, "store = \"hello world\"")?; 100 | let config = ConfigOptions::new() 101 | .env(false) 102 | .global(false) 103 | .local_config_dir(Some(dir.path().to_owned())) 104 | .load()?; 105 | assert_eq!(config.get_str("store")?, String::from("hello world")); 106 | Ok(()) 107 | } 108 | 109 | #[test] 110 | fn parent_dir_config() -> Result<()> { 111 | let dir = tempdir()?; 112 | let file = dir.path().join("dsrc.toml"); 113 | fs::write(file, "store = \"hello world\"")?; 114 | let subpath = dir.path().join("foo").join("bar"); 115 | fs::create_dir_all(&subpath)?; 116 | let config = ConfigOptions::new() 117 | .env(false) 118 | .global(false) 119 | .local_config_dir(Some(subpath.to_owned())) 120 | .load()?; 121 | assert_eq!(config.get_str("store")?, String::from("hello world")); 122 | Ok(()) 123 | } 124 | 125 | #[test] 126 | fn working_dir_shadowing_config() -> Result<()> { 127 | let dir = tempdir()?; 128 | let file = dir.path().join("dsrc.toml"); 129 | fs::write(file, "store = \"goodbye world\"")?; 130 | let subpath = dir.path().join("foo").join("bar"); 131 | fs::create_dir_all(&subpath)?; 132 | let file = dir.path().join("foo").join("dsrc.toml"); 133 | fs::write(file, "store = \"hello world\"")?; 134 | let config = ConfigOptions::new() 135 | .env(false) 136 | .global(false) 137 | .local_config_dir(Some(subpath.to_owned())) 138 | .load()?; 139 | assert_eq!(config.get_str("store")?, String::from("hello world")); 140 | Ok(()) 141 | } 142 | 143 | #[test] 144 | fn working_dir_shadowing_config_dotfile() -> Result<()> { 145 | let dir = tempdir()?; 146 | let file = dir.path().join(".dsrc.toml"); 147 | fs::write(file, "store = \"goodbye world\"")?; 148 | let subpath = dir.path().join("foo").join("bar"); 149 | fs::create_dir_all(&subpath)?; 150 | let file = dir.path().join("foo").join(".dsrc.toml"); 151 | fs::write(file, "store = \"hello world\"")?; 152 | let config = ConfigOptions::new() 153 | .env(false) 154 | .global(false) 155 | .local_config_dir(Some(subpath.to_owned())) 156 | .load()?; 157 | assert_eq!(config.get_str("store")?, String::from("hello world")); 158 | Ok(()) 159 | } 160 | 161 | #[test] 162 | fn env_configs() -> Result<()> { 163 | let dir = tempdir()?; 164 | env::set_var("DS_CONFIG_STORE", dir.path().display().to_string()); 165 | let config = ConfigOptions::new().local(false).global(false).load()?; 166 | env::remove_var("DS_CONFIG_STORE"); 167 | assert_eq!(config.get_str("store")?, dir.path().display().to_string()); 168 | Ok(()) 169 | } 170 | 171 | #[test] 172 | fn file_config() -> Result<()> { 173 | let dir = tempdir()?; 174 | let file = dir.path().join("dsrc.toml"); 175 | fs::write(&file, "store = \"hello world\"")?; 176 | let config = ConfigOptions::new() 177 | .local(false) 178 | .env(false) 179 | .global_config_file(Some(file.to_owned())) 180 | .load()?; 181 | assert_eq!(config.get_str("store")?, String::from("hello world")); 182 | Ok(()) 183 | } 184 | 185 | #[test] 186 | fn missing_config() -> Result<()> { 187 | let config = ConfigOptions::new() 188 | .local(false) 189 | .global(false) 190 | .env(false) 191 | .load()?; 192 | assert!(config.get_str("store").is_err()); 193 | Ok(()) 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /packages/ds-error-context/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ds-error-context" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | derive_more = "0.99.2" 11 | -------------------------------------------------------------------------------- /packages/ds-error-context/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use derive_more::Display; 4 | 5 | /// Contextual error codes for a variety of `ds` error messages. These codes 6 | /// have an M:N relationship to actual errors and are intended to provide 7 | /// users with additional context that they can easily look up in the `ds` 8 | /// documentation. 9 | #[derive(Display)] 10 | pub enum DsErrContext { 11 | /// This error occurs due to a failure to get the current executable (see 12 | /// [std::env::current_exe](https://doc.rust-lang.org/1.39.0/std/env/fn.current_exe.html#)), 13 | /// and can be for any number of system-related reasons beyond the control 14 | /// of `ds`. 15 | #[display(fmt = "DS1000: Failed to get the location of the current ds binary.")] 16 | DS1000, 17 | 18 | /// `ds shell` tried to execute a given Node.js binary, but the operation 19 | /// failed for some reason. Is Node installed and available in your $PATH? 20 | /// Did you pass in an invalid `--node` argument? Are you sure the file is 21 | /// executable? 22 | #[display(fmt = "DS1001: Failed to execute node binary at `{}`", _0)] 23 | DS1001(String), 24 | 25 | #[display(fmt = "DS1002: A home directory is required for ds patch scripts.")] 26 | DS1002, 27 | 28 | #[display(fmt = "DS1003: Failed to create data directory at `{:?}`", _0)] 29 | DS1003(PathBuf), 30 | 31 | #[display(fmt = "DS1004: Failed to write dstopic data file at `{:?}`", _0)] 32 | DS1004(PathBuf), 33 | 34 | /// Invalid Package Arg. 35 | #[display(fmt = "DS1005: Invalid package arg: `{}`", _0)] 36 | DS1005(String), 37 | 38 | #[display( 39 | fmt = "DS1006: Tried to resolve a registry spec ({}) without a name.", 40 | _0 41 | )] 42 | DS1006(String), 43 | 44 | #[display(fmt = "DS1007: Neither a name nor a spec were passed in. Failed to resolve.")] 45 | DS1007, 46 | 47 | #[display(fmt = "DS1008: Invalid registry arg string: `{}`", _0)] 48 | DS1008(String), 49 | 50 | #[display(fmt = "DS1009: No package name found in registry arg: `{}`", _0)] 51 | DS1009(String), 52 | 53 | #[display(fmt = "DS1010: Failed to parse registry URL from `{}`", _0)] 54 | DS1010(String), 55 | 56 | #[display(fmt = "DS1011: Failed to parse response body")] 57 | DS1011, 58 | 59 | #[display(fmt = "DS1012: No versions were present in the packument for `{}`", _0)] 60 | DS1012(String), 61 | 62 | #[display(fmt = "DS1013: Received an unexpected PackageArg type: `{}`", _0)] 63 | DS1013(String), 64 | 65 | #[display( 66 | fmt = "DS1014: No versions could be found because `{}` did not match any existing versions", 67 | _0 68 | )] 69 | DS1014(String), 70 | 71 | #[display(fmt = "DS1015: Ping failed for {}: {}", registry, message)] 72 | DS1015 { registry: String, message: String }, 73 | 74 | #[display(fmt = "DS1016: Failed to get response body.")] 75 | DS1016, 76 | 77 | #[display(fmt = "DS1017: No response from registry at {}", _0)] 78 | DS1017(String), 79 | 80 | /// Failed to parse a package arg for some reason. The message includes 81 | /// the actual error. 82 | #[display(fmt = "DS1018: Package arg `{}` failed to parse:\n{}", input, msg)] 83 | DS1018 { input: String, msg: String }, 84 | } 85 | -------------------------------------------------------------------------------- /packages/ds-package-arg/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ds-package-arg" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | ds-error-context = { path = "../ds-error-context" } 9 | 10 | anyhow = "1.0.20" 11 | url = "2.1.0" 12 | semver = "0.9.0" 13 | nom = "5.0.1" 14 | thiserror = "1.0.9" 15 | percent-encoding = "2.1.0" 16 | -------------------------------------------------------------------------------- /packages/ds-package-arg/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::str::FromStr; 2 | 3 | use anyhow::{self, Result}; 4 | 5 | mod parser; 6 | mod types; 7 | 8 | pub use types::{PackageArg, PackageArgError, VersionReq}; 9 | 10 | impl PackageArg { 11 | pub fn from_string>(s: S) -> Result { 12 | parser::parse_package_arg(&s.as_ref()) 13 | } 14 | 15 | pub fn resolve(name: String, spec: String) -> Result { 16 | let mut arg = String::new(); 17 | arg.push_str(&name); 18 | arg.push_str("@"); 19 | arg.push_str(&spec); 20 | parser::parse_package_arg(&arg) 21 | } 22 | 23 | pub fn validate_name>(name: S) -> Result { 24 | let name = name.as_ref(); 25 | Ok(name.into()) 26 | } 27 | 28 | pub fn is_registry(&self) -> bool { 29 | match self { 30 | PackageArg::Alias { package, .. } => package.is_registry(), 31 | PackageArg::Dir { .. } => false, 32 | PackageArg::Npm { .. } | PackageArg::Entropic { .. } => true, 33 | } 34 | } 35 | } 36 | 37 | impl FromStr for PackageArg { 38 | type Err = anyhow::Error; 39 | 40 | fn from_str(s: &str) -> std::result::Result { 41 | PackageArg::from_string(s) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/ds-package-arg/src/parser.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use anyhow::{anyhow, Context, Result}; 4 | use ds_error_context::DsErrContext as Ctx; 5 | use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC}; 6 | use url::Url; 7 | 8 | use nom::branch::alt; 9 | use nom::bytes::complete::{tag_no_case as tag, take_till1}; 10 | use nom::character::complete::{anychar, char, one_of}; 11 | use nom::combinator::{all_consuming, cut, map, map_res, opt, recognize, rest}; 12 | use nom::error::{context, convert_error, ParseError, VerboseError}; 13 | use nom::multi::many1; 14 | use nom::sequence::{delimited, preceded, tuple}; 15 | use nom::{Err, IResult}; 16 | 17 | use crate::types::{PackageArg, PackageArgError, VersionReq}; 18 | 19 | const JS_ENCODED: &'static AsciiSet = { 20 | &NON_ALPHANUMERIC 21 | .remove(b'-') 22 | .remove(b'_') 23 | .remove(b'.') 24 | .remove(b'!') 25 | .remove(b'~') 26 | .remove(b'*') 27 | .remove(b'\'') 28 | .remove(b'(') 29 | .remove(b')') 30 | }; 31 | 32 | pub fn parse_package_arg>(input: I) -> Result { 33 | let input = &input.as_ref()[..]; 34 | match all_consuming(package_arg::>)(input) { 35 | Ok((_, arg)) => Ok(arg), 36 | Err(err) => Err(PackageArgError::ParseError).with_context(|| Ctx::DS1018 { 37 | input: input.into(), 38 | msg: format!( 39 | "{}", 40 | match err { 41 | Err::Error(e) => convert_error(input, e), 42 | Err::Failure(e) => convert_error(input, e), 43 | Err::Incomplete(_) => "More data was needed".into(), 44 | } 45 | ), 46 | })?, 47 | } 48 | } 49 | 50 | /// package-arg := alias | ( [ "npm:" ] npm-pkg ) | ( [ "ent:" ] ent-pkg ) | ( [ "file:" ] path ) 51 | fn package_arg<'a, E>(input: &'a str) -> IResult<&'a str, PackageArg, E> 52 | where 53 | E: ParseError<&'a str>, 54 | { 55 | context( 56 | "package arg", 57 | alt(( 58 | alias, 59 | preceded(opt(tag("file:")), path), 60 | preceded(opt(tag("ent:")), ent_pkg), 61 | preceded(opt(tag("npm:")), npm_pkg), 62 | )), 63 | )(input) 64 | } 65 | 66 | /// prefixed_package-arg := ( "npm:" npm-pkg ) | ( "ent:" ent-pkg ) | ( [ "file:" ] path ) 67 | fn prefixed_package_arg<'a, E>(input: &'a str) -> IResult<&'a str, PackageArg, E> 68 | where 69 | E: ParseError<&'a str>, 70 | { 71 | context( 72 | "package spec", 73 | alt(( 74 | // Paths don't need to be prefixed, but they can be. 75 | preceded(opt(tag("file:")), path), 76 | preceded(tag("npm:"), npm_pkg), 77 | preceded(tag("ent:"), ent_pkg), 78 | )), 79 | )(input) 80 | } 81 | 82 | // alias := [ [ '@' ], not('/')+ '/' ] not('@/')+ '@' prefixed-package-arg 83 | fn alias<'a, E>(input: &'a str) -> IResult<&'a str, PackageArg, E> 84 | where 85 | E: ParseError<&'a str>, 86 | { 87 | context( 88 | "alias", 89 | map( 90 | tuple(( 91 | opt(scope), 92 | map_res(take_till1(|c| c == '@' || c == '/'), no_url_encode), 93 | tag("@"), 94 | prefixed_package_arg, 95 | )), 96 | |(scope, name, _, arg)| { 97 | let mut fullname = String::new(); 98 | if let Some(scope) = scope { 99 | fullname.push_str(&scope); 100 | fullname.push_str("/"); 101 | } 102 | fullname.push_str(name); 103 | PackageArg::Alias { 104 | name: fullname, 105 | package: Box::new(arg), 106 | } 107 | }, 108 | ), 109 | )(input) 110 | } 111 | 112 | fn scope<'a, E>(input: &'a str) -> IResult<&'a str, String, E> 113 | where 114 | E: ParseError<&'a str>, 115 | { 116 | context( 117 | "scope", 118 | map( 119 | tuple(( 120 | opt(tag("@")), 121 | map_res(take_till1(|c| c == '/'), no_url_encode), 122 | tag("/"), 123 | )), 124 | |(at, scope, _)| { 125 | let mut out = String::new(); 126 | if let Some(at) = at { 127 | out.push_str(at); 128 | } 129 | out.push_str(scope); 130 | out 131 | }, 132 | ), 133 | )(input) 134 | } 135 | 136 | /// ent-pkg := not('/')+ '/' not('/')+ '/' not('@/')+ [ '@' version=req ] 137 | fn ent_pkg<'a, E>(input: &'a str) -> IResult<&'a str, PackageArg, E> 138 | where 139 | E: ParseError<&'a str>, 140 | { 141 | context( 142 | "entropic package", 143 | map( 144 | tuple(( 145 | map_res(take_till1(|c| c == '/'), |host| { 146 | let mut string = String::from("https://"); 147 | string.push_str(host); 148 | Url::parse(&string).and_then(|x| { 149 | x.host() 150 | .ok_or(url::ParseError::EmptyHost) 151 | .map(|x| x.to_owned()) 152 | }) 153 | }), 154 | preceded(tag("/"), map_res(take_till1(|c| c == '/'), no_url_encode)), 155 | preceded( 156 | tag("/"), 157 | map_res(take_till1(|c| c == '/' || c == '@'), no_url_encode), 158 | ), 159 | opt(preceded(tag("@"), cut(version_req))), 160 | )), 161 | |(host, user, name, req)| { 162 | let mut pkg = String::new(); 163 | pkg.push_str(user); 164 | pkg.push_str("/"); 165 | pkg.push_str(name); 166 | PackageArg::Entropic { 167 | host, 168 | name: pkg, 169 | requested: req, 170 | } 171 | }, 172 | ), 173 | )(input) 174 | } 175 | 176 | /// npm-pkg := [ '@' not('/')+ '/' ] not('@/')+ [ '@' version-req ] 177 | fn npm_pkg<'a, E>(input: &'a str) -> IResult<&'a str, PackageArg, E> 178 | where 179 | E: ParseError<&'a str>, 180 | { 181 | context( 182 | "npm package", 183 | map( 184 | tuple(( 185 | opt(delimited( 186 | char('@'), 187 | map_res(take_till1(|c| c == '/'), no_url_encode), 188 | char('/'), 189 | )), 190 | map_res(take_till1(|x| x == '@' || x == '/'), no_url_encode), 191 | opt(preceded(tag("@"), cut(version_req))), 192 | )), 193 | |(scope_opt, name, req)| PackageArg::Npm { 194 | scope: scope_opt.map(|x| x.into()), 195 | name: name.into(), 196 | requested: req, 197 | }, 198 | ), 199 | )(input) 200 | } 201 | 202 | fn version_req<'a, E>(input: &'a str) -> IResult<&'a str, VersionReq, E> 203 | where 204 | E: ParseError<&'a str>, 205 | { 206 | context( 207 | "version requirement", 208 | alt((semver_version, semver_range, version_tag)), 209 | )(input) 210 | } 211 | 212 | fn semver_version<'a, E>(input: &'a str) -> IResult<&'a str, VersionReq, E> 213 | where 214 | E: ParseError<&'a str>, 215 | { 216 | let (input, version) = map_res(take_till1(|_| false), semver::Version::parse)(input)?; 217 | Ok((input, VersionReq::Version(version))) 218 | } 219 | 220 | fn semver_range<'a, E>(input: &'a str) -> IResult<&'a str, VersionReq, E> 221 | where 222 | E: ParseError<&'a str>, 223 | { 224 | let (input, range) = map_res(take_till1(|_| false), semver::VersionReq::parse)(input)?; 225 | Ok((input, VersionReq::Range(range))) 226 | } 227 | 228 | fn version_tag<'a, E>(input: &'a str) -> IResult<&'a str, VersionReq, E> 229 | where 230 | E: ParseError<&'a str>, 231 | { 232 | context( 233 | "dist tag", 234 | map(map_res(take_till1(|_| false), no_url_encode), |t| { 235 | VersionReq::Tag(t.into()) 236 | }), 237 | )(input) 238 | } 239 | 240 | fn no_url_encode(tag: &str) -> Result<&str> { 241 | if format!("{}", utf8_percent_encode(tag, JS_ENCODED)) == tag { 242 | Ok(tag) 243 | } else { 244 | Err(anyhow!("invalid characters")) 245 | } 246 | } 247 | 248 | /// path := ( relative-dir | absolute-dir ) 249 | fn path<'a, E>(input: &'a str) -> IResult<&'a str, PackageArg, E> 250 | where 251 | E: ParseError<&'a str>, 252 | { 253 | map(alt((relative_path, absolute_path)), |p| PackageArg::Dir { 254 | path: p, 255 | })(input) 256 | } 257 | 258 | /// relative-path := [ '.' ] '.' path-sep .* 259 | fn relative_path<'a, E>(input: &'a str) -> IResult<&'a str, PathBuf, E> 260 | where 261 | E: ParseError<&'a str>, 262 | { 263 | map( 264 | recognize(tuple((tag("."), opt(tag(".")), many1(path_sep), rest))), 265 | |p| PathBuf::from(p), 266 | )(input) 267 | } 268 | 269 | /// absolute-path := [ alpha ':' ] path-sep+ [ '?' path-sep+ ] .* 270 | fn absolute_path<'a, E>(input: &'a str) -> IResult<&'a str, PathBuf, E> 271 | where 272 | E: ParseError<&'a str>, 273 | { 274 | map( 275 | recognize(preceded( 276 | delimited( 277 | opt(preceded( 278 | map_res(anychar, |c| { 279 | if c.is_alphabetic() { 280 | Ok(c) 281 | } else { 282 | Err(anyhow!("drive letters can only be alphabetic")) 283 | } 284 | }), 285 | tag(":"), 286 | )), 287 | many1(path_sep), 288 | opt(preceded(tag("?"), many1(path_sep))), 289 | ), 290 | rest, 291 | )), 292 | |p| PathBuf::from(p), 293 | )(input) 294 | } 295 | 296 | /// path-sep := ( '/' | '\' ) 297 | fn path_sep<'a, E>(input: &'a str) -> IResult<&'a str, char, E> 298 | where 299 | E: ParseError<&'a str>, 300 | { 301 | one_of("/\\")(input) 302 | } 303 | -------------------------------------------------------------------------------- /packages/ds-package-arg/src/types.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use semver::{Version, VersionReq as Range}; 4 | use thiserror::Error; 5 | use url::Host; 6 | 7 | #[derive(Debug, Error)] 8 | pub enum PackageArgError { 9 | #[error("Failed to parse package arg.")] 10 | ParseError, 11 | } 12 | 13 | #[derive(Debug, Clone, PartialEq, Eq)] 14 | pub enum VersionReq { 15 | Tag(String), 16 | Version(Version), 17 | Range(Range), 18 | } 19 | 20 | #[derive(Debug, Clone, PartialEq, Eq)] 21 | pub enum PackageArg { 22 | Dir { 23 | path: PathBuf, 24 | }, 25 | Alias { 26 | name: String, 27 | package: Box, 28 | }, 29 | Entropic { 30 | host: Host, 31 | name: String, 32 | requested: Option, 33 | }, 34 | Npm { 35 | scope: Option, 36 | name: String, 37 | requested: Option, 38 | }, 39 | } 40 | -------------------------------------------------------------------------------- /packages/ds-package-arg/tests/dir.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use anyhow::Result; 4 | 5 | use ds_package_arg::PackageArg; 6 | 7 | fn ppa(input: &str) -> Result { 8 | input.parse() 9 | } 10 | 11 | #[test] 12 | fn relative_path_current_dir() -> Result<()> { 13 | let res = ppa("./")?; 14 | assert_eq!( 15 | res, 16 | PackageArg::Dir { 17 | path: PathBuf::from("./") 18 | } 19 | ); 20 | Ok(()) 21 | } 22 | 23 | #[test] 24 | fn relative_path_unix() -> Result<()> { 25 | let res = ppa("./foo/bar/baz")?; 26 | assert_eq!( 27 | res, 28 | PackageArg::Dir { 29 | path: PathBuf::from("./foo/bar/baz") 30 | } 31 | ); 32 | Ok(()) 33 | } 34 | 35 | #[test] 36 | fn absolute_path_unix() -> Result<()> { 37 | let res = ppa("/foo/bar/baz")?; 38 | assert_eq!( 39 | res, 40 | PackageArg::Dir { 41 | path: PathBuf::from("/foo/bar/baz") 42 | } 43 | ); 44 | Ok(()) 45 | } 46 | 47 | #[test] 48 | fn relative_path_windows() -> Result<()> { 49 | let res = ppa(".\\foo\\bar\\baz")?; 50 | assert_eq!( 51 | res, 52 | PackageArg::Dir { 53 | path: PathBuf::from(".\\foo\\bar\\baz") 54 | } 55 | ); 56 | Ok(()) 57 | } 58 | 59 | #[test] 60 | fn absolute_path_windows() -> Result<()> { 61 | let res = ppa("C:\\foo\\bar\\baz")?; 62 | assert_eq!( 63 | res, 64 | PackageArg::Dir { 65 | path: PathBuf::from("C:\\foo\\bar\\baz") 66 | } 67 | ); 68 | Ok(()) 69 | } 70 | 71 | #[test] 72 | fn absolute_path_windows_qmark() -> Result<()> { 73 | let res = ppa("\\\\?\\foo\\bar\\baz")?; 74 | assert_eq!( 75 | res, 76 | PackageArg::Dir { 77 | path: PathBuf::from("\\\\?\\foo\\bar\\baz") 78 | } 79 | ); 80 | Ok(()) 81 | } 82 | 83 | #[test] 84 | fn absolute_path_windows_double_slash() -> Result<()> { 85 | let res = ppa("\\\\foo\\bar\\baz")?; 86 | assert_eq!( 87 | res, 88 | PackageArg::Dir { 89 | path: PathBuf::from("\\\\foo\\bar\\baz") 90 | } 91 | ); 92 | Ok(()) 93 | } 94 | 95 | #[test] 96 | fn absolute_path_windows_multiple_drive_letters() -> Result<()> { 97 | let res = ppa("ACAB:\\foo\\bar\\baz"); 98 | assert!(res.is_err()); 99 | Ok(()) 100 | } 101 | 102 | #[test] 103 | fn spaces() -> Result<()> { 104 | // NOTE: This succeeds in NPM, but we treat it as an error because we 105 | // require ./ for relative paths. 106 | let res = ppa("@f fo o al/ a d s ;f"); 107 | assert!(res.is_err()); 108 | Ok(()) 109 | } 110 | -------------------------------------------------------------------------------- /packages/ds-package-arg/tests/entropic.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use url::Url; 3 | 4 | use ds_package_arg::{PackageArg, VersionReq}; 5 | 6 | fn ppa(input: &str) -> Result { 7 | input.parse() 8 | } 9 | 10 | #[test] 11 | fn ent_pkg_basic() -> Result<()> { 12 | let res = ppa("example.com/hello/world")?; 13 | assert_eq!( 14 | res, 15 | PackageArg::Entropic { 16 | name: "hello/world".into(), 17 | requested: None, 18 | host: Url::parse("https://example.com")? 19 | .host() 20 | .map(|x| x.to_owned()) 21 | .unwrap(), 22 | } 23 | ); 24 | Ok(()) 25 | } 26 | 27 | #[test] 28 | fn ent_pkg_prefixed() -> Result<()> { 29 | let res = ppa("ent:example.com/hello/world")?; 30 | assert_eq!( 31 | res, 32 | PackageArg::Entropic { 33 | name: "hello/world".into(), 34 | requested: None, 35 | host: Url::parse("https://example.com")? 36 | .host() 37 | .map(|x| x.to_owned()) 38 | .unwrap(), 39 | } 40 | ); 41 | Ok(()) 42 | } 43 | 44 | #[test] 45 | fn ent_pkg_with_req() -> Result<()> { 46 | let res = ppa("example.com/hello/world@^1.2.3")?; 47 | assert_eq!( 48 | res, 49 | PackageArg::Entropic { 50 | name: "hello/world".into(), 51 | requested: Some(VersionReq::Range(semver::VersionReq::parse("^1.2.3")?)), 52 | host: Url::parse("https://example.com")? 53 | .host() 54 | .map(|x| x.to_owned()) 55 | .unwrap(), 56 | } 57 | ); 58 | Ok(()) 59 | } 60 | -------------------------------------------------------------------------------- /packages/ds-package-arg/tests/npm.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | 3 | use ds_package_arg::{PackageArg, VersionReq}; 4 | 5 | fn ppa(input: &str) -> Result { 6 | input.parse() 7 | } 8 | 9 | #[test] 10 | fn npm_pkg_basic() -> Result<()> { 11 | let res = ppa("hello-world")?; 12 | assert_eq!( 13 | res, 14 | PackageArg::Npm { 15 | scope: None, 16 | name: "hello-world".into(), 17 | requested: None 18 | } 19 | ); 20 | Ok(()) 21 | } 22 | 23 | #[test] 24 | fn npm_pkg_tag() -> Result<()> { 25 | let res = ppa("hello-world@latest")?; 26 | assert_eq!( 27 | res, 28 | PackageArg::Npm { 29 | scope: None, 30 | name: "hello-world".into(), 31 | requested: Some(VersionReq::Tag("latest".into())) 32 | } 33 | ); 34 | Ok(()) 35 | } 36 | 37 | #[test] 38 | fn alias_npm_pkg_basic() -> Result<()> { 39 | let res = ppa("foo@npm:hello-world")?; 40 | assert_eq!( 41 | res, 42 | PackageArg::Alias { 43 | name: "foo".into(), 44 | package: Box::new(PackageArg::Npm { 45 | scope: None, 46 | name: "hello-world".into(), 47 | requested: None 48 | }) 49 | } 50 | ); 51 | Ok(()) 52 | } 53 | 54 | #[test] 55 | fn alias_not_recursive() -> Result<()> { 56 | let res = ppa("foo@bar@npm:hello-world"); 57 | assert!(res.is_err()); 58 | Ok(()) 59 | } 60 | 61 | #[test] 62 | fn npm_pkg_prefixed() -> Result<()> { 63 | let res = ppa("npm:hello-world")?; 64 | assert_eq!( 65 | res, 66 | PackageArg::Npm { 67 | scope: None, 68 | name: "hello-world".into(), 69 | requested: None 70 | } 71 | ); 72 | Ok(()) 73 | } 74 | 75 | #[test] 76 | fn npm_pkg_scoped() -> Result<()> { 77 | let res = ppa("@hello/world")?; 78 | assert_eq!( 79 | res, 80 | PackageArg::Npm { 81 | scope: Some("hello".into()), 82 | name: "world".into(), 83 | requested: None 84 | } 85 | ); 86 | Ok(()) 87 | } 88 | 89 | #[test] 90 | fn npm_pkg_with_req() -> Result<()> { 91 | let res = ppa("hello-world@1.2.3")?; 92 | assert_eq!( 93 | res, 94 | PackageArg::Npm { 95 | scope: None, 96 | name: "hello-world".into(), 97 | requested: Some(VersionReq::Version(semver::Version::parse("1.2.3")?)) 98 | } 99 | ); 100 | Ok(()) 101 | } 102 | 103 | #[test] 104 | fn npm_pkg_with_tag() -> Result<()> { 105 | let res = ppa("hello-world@howdy")?; 106 | assert_eq!( 107 | res, 108 | PackageArg::Npm { 109 | scope: None, 110 | name: "hello-world".into(), 111 | requested: Some(VersionReq::Tag("howdy".into())), 112 | } 113 | ); 114 | Ok(()) 115 | } 116 | 117 | #[test] 118 | fn npm_pkg_scoped_with_req() -> Result<()> { 119 | let res = ppa("@hello/world@1.2.3")?; 120 | assert_eq!( 121 | res, 122 | PackageArg::Npm { 123 | scope: Some("hello".into()), 124 | name: "world".into(), 125 | requested: Some(VersionReq::Version(semver::Version::parse("1.2.3")?)) 126 | } 127 | ); 128 | Ok(()) 129 | } 130 | 131 | #[test] 132 | fn npm_pkg_prefixed_with_req() -> Result<()> { 133 | let res = ppa("npm:@hello/world@1.2.3")?; 134 | assert_eq!( 135 | res, 136 | PackageArg::Npm { 137 | scope: Some("hello".into()), 138 | name: "world".into(), 139 | requested: Some(VersionReq::Version(semver::Version::parse("1.2.3")?)) 140 | } 141 | ); 142 | Ok(()) 143 | } 144 | 145 | #[test] 146 | fn npm_pkg_bad_tag() -> Result<()> { 147 | let res = ppa("hello-world@%&W$@#$"); 148 | assert!(res.is_err()); 149 | Ok(()) 150 | } 151 | -------------------------------------------------------------------------------- /packages/pick-version/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "pick-version" 3 | version = "0.1.0" 4 | authors = ["Kat Marchán "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | ds-package-arg = { path = "../../packages/ds-package-arg" } 11 | ds-api-types = { path = "../../packages/ds-api-types" } 12 | ds-error-context = { path = "../../packages/ds-error-context" } 13 | 14 | semver = "0.9.0" 15 | serde_json = "1.0.42" 16 | anyhow = "1.0.25" 17 | ssri = "5.0.0" 18 | chrono = "0.4.10" 19 | thiserror = "1.0.9" 20 | 21 | [dev-dependencies] 22 | maplit = "1.0.2" 23 | -------------------------------------------------------------------------------- /packages/pick-version/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{Context, Result}; 2 | use ds_api_types::EntropicPackument; 3 | use ds_error_context::DsErrContext as Ctx; 4 | use ds_package_arg::PackageArg; 5 | use semver::{Version, VersionReq}; 6 | use ssri::Integrity; 7 | use thiserror::Error; 8 | 9 | pub struct Picker { 10 | pub default_tag: String, 11 | } 12 | 13 | impl Default for Picker { 14 | fn default() -> Self { 15 | Picker { 16 | default_tag: "latest".into(), 17 | } 18 | } 19 | } 20 | 21 | #[derive(Debug, Error)] 22 | pub enum PickerError { 23 | #[error("No matching version.")] 24 | NoVersion, 25 | #[error("Only Version, Tag, Range, and Alias package args are supported.")] 26 | InvalidPackageArg, 27 | } 28 | 29 | impl Picker { 30 | pub fn new() -> Self { 31 | Picker::default() 32 | } 33 | 34 | pub fn default_tag(mut self, tag: String) -> Self { 35 | self.default_tag = tag; 36 | self 37 | } 38 | 39 | pub fn pick(&self, packument: &EntropicPackument, wanted: &PackageArg) -> Result { 40 | if packument.versions.len() == 0 { 41 | Err(PickerError::NoVersion).with_context(|| Ctx::DS1012(packument.name.clone()))?; 42 | } 43 | match wanted { 44 | PackageArg::Alias { package, .. } => return self.pick(&packument, &package), 45 | _ => (), 46 | } 47 | 48 | let mut target: Option = match wanted { 49 | PackageArg::Version { version, .. } => Some(version.clone()), 50 | PackageArg::Tag { tag, .. } => packument.tags.get(tag.as_str()).map(|v| v.clone()), 51 | PackageArg::Range { .. } => None, 52 | _ => Err(PickerError::InvalidPackageArg) 53 | .with_context(|| Ctx::DS1013(format!("{:?}", wanted)))?, 54 | }; 55 | 56 | let tag_version = packument.tags.get(&self.default_tag).map(|v| v.clone()); 57 | 58 | if target.is_none() 59 | && tag_version.is_some() 60 | && packument 61 | .versions 62 | .get(&tag_version.clone().unwrap()) 63 | .is_some() 64 | && match wanted { 65 | PackageArg::Range { range, .. } => range.matches(&tag_version.clone().unwrap()), 66 | _ => false, 67 | } 68 | { 69 | target = tag_version.clone(); 70 | } 71 | 72 | if target.is_none() { 73 | match wanted { 74 | PackageArg::Range { range, .. } => { 75 | target = max_satisfying(packument.versions.keys(), range) 76 | } 77 | _ => (), 78 | } 79 | } 80 | 81 | if target.is_none() { 82 | match wanted { 83 | PackageArg::Range { range, .. } => { 84 | if range == &VersionReq::any() || range == &VersionReq::parse("*").unwrap() { 85 | target = tag_version; 86 | } 87 | } 88 | _ => (), 89 | } 90 | } 91 | 92 | target 93 | .and_then(|v| packument.versions.get(&v)) 94 | .map(|i| i.clone()) 95 | .ok_or_else(|| PickerError::NoVersion) 96 | .with_context(|| Ctx::DS1014(format!("{:?}", wanted))) 97 | } 98 | } 99 | 100 | fn max_satisfying<'a>( 101 | versions: impl Iterator, 102 | range: &VersionReq, 103 | ) -> Option { 104 | versions 105 | .filter(|v| range.matches(v)) 106 | .max() 107 | .map(|v| v.clone()) 108 | } 109 | -------------------------------------------------------------------------------- /packages/pick-version/tests/tests.rs: -------------------------------------------------------------------------------- 1 | use ds_api_types::EntropicPackument; 2 | use maplit::hashmap; 3 | use parse_package_arg::PackageArg; 4 | use semver::{Version, VersionReq}; 5 | use ssri::Integrity; 6 | 7 | use pick_version::Picker; 8 | 9 | #[test] 10 | fn basic_carat_range() { 11 | let packument = EntropicPackument { 12 | versions: hashmap! { 13 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 14 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 15 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 16 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 17 | }, 18 | ..EntropicPackument::default() 19 | }; 20 | let sri = Picker::new() 21 | .pick( 22 | &packument, 23 | &PackageArg::Range { 24 | host: None, 25 | name: "foo".into(), 26 | range: VersionReq::parse("^1.0.0").unwrap(), 27 | }, 28 | ) 29 | .unwrap(); 30 | assert_eq!(sri, "sha256-102".parse::().unwrap()); 31 | } 32 | 33 | #[test] 34 | fn basic_tilde_range() { 35 | let packument = EntropicPackument { 36 | versions: hashmap! { 37 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 38 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 39 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 40 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 41 | }, 42 | ..EntropicPackument::default() 43 | }; 44 | let sri = Picker::new() 45 | .pick( 46 | &packument, 47 | &PackageArg::Range { 48 | host: None, 49 | name: "foo".into(), 50 | range: VersionReq::parse("~1.0.0").unwrap(), 51 | }, 52 | ) 53 | .unwrap(); 54 | assert_eq!(sri, "sha256-102".parse::().unwrap()); 55 | } 56 | 57 | #[test] 58 | fn basic_math_range() { 59 | let packument = EntropicPackument { 60 | versions: hashmap! { 61 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 62 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 63 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 64 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 65 | }, 66 | ..EntropicPackument::default() 67 | }; 68 | let sri = Picker::new() 69 | .pick( 70 | &packument, 71 | &PackageArg::Range { 72 | host: None, 73 | name: "foo".into(), 74 | range: VersionReq::parse("<2.0.0").unwrap(), 75 | }, 76 | ) 77 | .unwrap(); 78 | assert_eq!(sri, "sha256-102".parse::().unwrap()); 79 | } 80 | 81 | #[test] 82 | fn basic_version_match() { 83 | let packument = EntropicPackument { 84 | versions: hashmap! { 85 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 86 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 87 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 88 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 89 | }, 90 | ..EntropicPackument::default() 91 | }; 92 | let sri = Picker::new() 93 | .pick( 94 | &packument, 95 | &PackageArg::Version { 96 | host: None, 97 | name: "foo".into(), 98 | version: Version::parse("1.0.1").unwrap(), 99 | }, 100 | ) 101 | .unwrap(); 102 | assert_eq!(sri, "sha256-101".parse::().unwrap()); 103 | } 104 | 105 | #[test] 106 | fn basic_tag_match() { 107 | let packument = EntropicPackument { 108 | tags: hashmap! { 109 | "latest".into() => Version::parse("1.0.1").unwrap() 110 | }, 111 | versions: hashmap! { 112 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 113 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 114 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 115 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 116 | }, 117 | ..EntropicPackument::default() 118 | }; 119 | let sri = Picker::new() 120 | .pick( 121 | &packument, 122 | &PackageArg::Tag { 123 | host: None, 124 | name: "foo".into(), 125 | tag: "latest".into(), 126 | }, 127 | ) 128 | .unwrap(); 129 | assert_eq!(sri, "sha256-101".parse::().unwrap()); 130 | } 131 | 132 | #[test] 133 | fn tag_match_with_custom_default_tag() { 134 | let packument = EntropicPackument { 135 | tags: hashmap! { 136 | "something".into() => Version::parse("1.0.1").unwrap(), 137 | "latest".into() => Version::parse("1.0.2").unwrap() 138 | }, 139 | versions: hashmap! { 140 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 141 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 142 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 143 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 144 | }, 145 | ..EntropicPackument::default() 146 | }; 147 | let sri = Picker::new() 148 | .default_tag("something".into()) 149 | .pick( 150 | &packument, 151 | &PackageArg::Tag { 152 | host: None, 153 | name: "foo".into(), 154 | tag: "something".into(), 155 | }, 156 | ) 157 | .unwrap(); 158 | assert_eq!(sri, "sha256-101".parse::().unwrap()); 159 | } 160 | 161 | #[test] 162 | fn star_range_uses_default_tag() { 163 | let packument = EntropicPackument { 164 | tags: hashmap! { 165 | "latest".into() => Version::parse("1.0.0-pre.0").unwrap(), 166 | "beta".into() => Version::parse("2.0.0-beta.0").unwrap(), 167 | }, 168 | versions: hashmap! { 169 | Version::parse("1.0.0-pre.0").unwrap() => "sha256-100b0".parse().unwrap(), 170 | Version::parse("1.0.0-pre.1").unwrap() => "sha256-100b1".parse().unwrap(), 171 | Version::parse("2.0.0-beta.0").unwrap() => "sha256-200b0".parse().unwrap(), 172 | Version::parse("2.0.0-beta.1").unwrap() => "sha256-200b1".parse().unwrap(), 173 | }, 174 | ..EntropicPackument::default() 175 | }; 176 | let sri = Picker::new() 177 | .default_tag("beta".into()) 178 | .pick( 179 | &packument, 180 | &PackageArg::Range { 181 | host: None, 182 | name: "foo".into(), 183 | range: VersionReq::any(), 184 | }, 185 | ) 186 | .unwrap(); 187 | assert_eq!(sri, "sha256-200b0".parse::().unwrap()); 188 | let sri = Picker::new() 189 | .pick( 190 | &packument, 191 | &PackageArg::Range { 192 | host: None, 193 | name: "foo".into(), 194 | range: VersionReq::parse("*").unwrap(), 195 | }, 196 | ) 197 | .unwrap(); 198 | assert_eq!(sri, "sha256-100b0".parse::().unwrap()); 199 | } 200 | 201 | #[test] 202 | fn error_if_no_match() { 203 | let packument = EntropicPackument { 204 | versions: hashmap! { 205 | Version::parse("1.0.0").unwrap() => "sha256-100".parse().unwrap(), 206 | Version::parse("1.0.1").unwrap() => "sha256-101".parse().unwrap(), 207 | Version::parse("1.0.2").unwrap() => "sha256-102".parse().unwrap(), 208 | Version::parse("2.0.0").unwrap() => "sha256-200".parse().unwrap(), 209 | }, 210 | ..EntropicPackument::default() 211 | }; 212 | let sri = Picker::new().pick( 213 | &packument, 214 | &PackageArg::Range { 215 | host: None, 216 | name: "foo".into(), 217 | range: VersionReq::parse("^2.0.1").unwrap(), 218 | }, 219 | ); 220 | assert!(sri.is_err()); 221 | } 222 | 223 | #[test] 224 | fn error_if_no_versions() { 225 | let packument = EntropicPackument::default(); 226 | let sri = Picker::new().pick( 227 | &packument, 228 | &PackageArg::Range { 229 | host: None, 230 | name: "foo".into(), 231 | range: VersionReq::parse("^1.0.0").unwrap(), 232 | }, 233 | ); 234 | assert!(sri.is_err()); 235 | } 236 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use anyhow::Result; 4 | use async_trait::async_trait; 5 | use clap; 6 | use ds_command::{ArgMatches, Config, DsCommand}; 7 | use ds_config::ConfigOptions; 8 | use structopt::StructOpt; 9 | 10 | use cmd_config::ConfigCmd; 11 | use cmd_ping::PingCmd; 12 | use cmd_shell::ShellCmd; 13 | 14 | pub use ds_error_context::DsErrContext; 15 | 16 | #[derive(Debug, StructOpt)] 17 | #[structopt( 18 | author = "Kat Marchán ", 19 | about = "Manage your Entropic packages.", 20 | setting = clap::AppSettings::ColoredHelp, 21 | setting = clap::AppSettings::DisableHelpSubcommand, 22 | setting = clap::AppSettings::DeriveDisplayOrder, 23 | )] 24 | pub struct Ds { 25 | #[structopt(help = "File to read configuration values from.", long, global = true)] 26 | config: Option, 27 | #[structopt(subcommand)] 28 | subcommand: DsCmd, 29 | } 30 | 31 | impl Ds { 32 | pub async fn load() -> Result<()> { 33 | let clp = Ds::clap(); 34 | let matches = clp.get_matches(); 35 | let mut ds = Ds::from_clap(&matches); 36 | let cfg = if let Some(file) = &ds.config { 37 | ConfigOptions::new() 38 | .local(false) 39 | .global_config_file(Some(file.clone())) 40 | .load()? 41 | } else { 42 | ConfigOptions::new().load()? 43 | }; 44 | ds.layer_config(matches, cfg)?; 45 | ds.execute().await?; 46 | Ok(()) 47 | } 48 | } 49 | 50 | #[derive(Debug, StructOpt)] 51 | pub enum DsCmd { 52 | #[structopt(about = "Configuration subcommands.", alias = "c")] 53 | Config(ConfigCmd), 54 | #[structopt(about = "Ping an entropic server")] 55 | Ping(PingCmd), 56 | #[structopt( 57 | about = "Execute a new wrapped `node` shell.", 58 | alias = "sh", 59 | setting = clap::AppSettings::TrailingVarArg 60 | )] 61 | Shell(ShellCmd), 62 | } 63 | 64 | #[async_trait] 65 | impl DsCommand for Ds { 66 | fn layer_config(&mut self, args: ArgMatches<'_>, conf: Config) -> Result<()> { 67 | match self.subcommand { 68 | DsCmd::Config(ref mut cfg) => { 69 | cfg.layer_config(args.subcommand_matches("config").unwrap().clone(), conf) 70 | } 71 | DsCmd::Ping(ref mut ping) => { 72 | ping.layer_config(args.subcommand_matches("ping").unwrap().clone(), conf) 73 | } 74 | DsCmd::Shell(ref mut shell) => { 75 | shell.layer_config(args.subcommand_matches("shell").unwrap().clone(), conf) 76 | } 77 | } 78 | } 79 | 80 | async fn execute(self) -> Result<()> { 81 | match self.subcommand { 82 | DsCmd::Config(cfg) => cfg.execute().await, 83 | DsCmd::Ping(ping) => ping.execute().await, 84 | DsCmd::Shell(shell) => shell.execute().await, 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use async_std; 3 | 4 | use ds::Ds; 5 | 6 | #[async_std::main] 7 | async fn main() -> Result<()> { 8 | Ds::load().await 9 | } 10 | --------------------------------------------------------------------------------