├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ ├── build.yaml │ ├── chore.yaml │ ├── ci.yaml │ ├── config.yml │ ├── documentation.yaml │ ├── feature_request.yaml │ ├── performance.yaml │ ├── refactor.yaml │ ├── revert.yaml │ ├── style.yaml │ └── test.yaml ├── PULL_REQUEST_TEMPLATE.md ├── cspell.json ├── dependabot.yaml └── workflows │ ├── main.yaml │ ├── pub_publish.yaml │ └── sync_labels.yaml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── build.yaml ├── coverage_badge.svg ├── example └── main.dart ├── lib ├── pub_updater.dart └── src │ ├── models │ ├── models.dart │ ├── package_info.dart │ └── package_info.g.dart │ └── pub_updater.dart ├── pubspec.yaml ├── test ├── fixtures │ ├── fixtures.dart │ ├── pre_release_package_info_response.dart │ └── valid_package_info_response.dart ├── pub_update_test.dart └── src │ └── models │ └── package_info_test.dart └── tool └── release_ready.sh /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Every request must be reviewed and accepted by: 2 | 3 | * @VeryGoodOpenSource/codeowners -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: Create a report to help us improve 3 | title: "fix: " 4 | labels: [bug] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: A clear and concise description of what the bug is. 11 | placeholder: "Describe the bug." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: setps-to-reproduce 16 | attributes: 17 | label: Steps To Reproduce 18 | description: A set of instructions, step by step, explaining how to reproduce the bug. 19 | placeholder: | 20 | 1. Go to '...' 21 | 2. Click on '....' 22 | 3. Scroll down to '....' 23 | 4. See error 24 | validations: 25 | required: true 26 | - type: textarea 27 | id: expected-behavior 28 | attributes: 29 | label: Expected Behavior 30 | description: A clear and concise description of what you expected to happen. 31 | placeholder: "Describe what you expected to happen." 32 | validations: 33 | required: true 34 | - type: textarea 35 | id: additional-context 36 | attributes: 37 | label: Additional Context 38 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 39 | placeholder: "Provide context here." 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/build.yaml: -------------------------------------------------------------------------------- 1 | name: Build System 2 | description: Changes that affect the build system or external dependencies 3 | title: "build: " 4 | labels: [build] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Describe what changes need to be done to the build system and why 11 | placeholder: "Describe the build system change." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/chore.yaml: -------------------------------------------------------------------------------- 1 | name: Chore 2 | description: Other changes that don't modify source or test files 3 | title: "chore: " 4 | labels: [chore] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Clearly describe what change is needed and why. If this changes code then please use another issue type. 11 | placeholder: "Provide a description of the chore." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] No functional changes to the code. 21 | - [ ] All CI/CD checks are passing. 22 | - [ ] There is no drop in the test coverage percentage. 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: additional-context 27 | attributes: 28 | label: Additional Context 29 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 30 | placeholder: "Provide context here." 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/ci.yaml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | description: Changes to the CI configuration files and scripts 3 | title: "ci: " 4 | labels: [ci] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Describe what changes need to be done to the CI/CD system and why. 11 | placeholder: "Provide a description of the changes that need to be done to the CI/CD system." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/documentation.yaml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | description: Improve the documentation so all collaborators have a common understanding 3 | title: "docs: " 4 | labels: [documentation] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Clearly describe what documentation you are looking to add or improve. 11 | placeholder: "Provide a description of the documentation changes." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] No functional changes to the code. 21 | - [ ] All CI/CD checks are passing. 22 | - [ ] There is no drop in the test coverage percentage. 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: additional-context 27 | attributes: 28 | label: Additional Context 29 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 30 | placeholder: "Provide context here." 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: Feature Request 2 | description: A new feature to be added to the project 3 | title: "feat: " 4 | labels: [feature] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Clearly describe what you are looking to add. The more business/user context the better. 11 | placeholder: "Provide a description of the feature." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/performance.yaml: -------------------------------------------------------------------------------- 1 | name: Performance Update 2 | description: A code change that improves performance 3 | title: "perf: " 4 | labels: [performance] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Clearly describe what code needs to be changed and what the performance impact is going to be. Bonus point's if you can tie this directly to user experience. 11 | placeholder: " Provide a description of the performance update." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/refactor.yaml: -------------------------------------------------------------------------------- 1 | name: Refactor 2 | description: A code change that neither fixes a bug nor adds a feature 3 | title: "refactor: " 4 | labels: [refactor] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Clearly describe what needs to be refactored and why. Please provide links to related issues (bugs or upcoming features) in order to help prioritize. 11 | placeholder: "Provide a description of the refactor." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/revert.yaml: -------------------------------------------------------------------------------- 1 | name: Revert 2 | description: Revert a previous commit 3 | title: "revert: " 4 | labels: [revert] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Provide a link to a PR/Commit that you are looking to revert and why. 11 | placeholder: "Provide a description of and link to the commit that needs to be reverted." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] Change has been reverted. 21 | - [ ] No change in unit/widget test coverage has happened. 22 | - [ ] A new ticket is created for any follow on work that needs to happen. 23 | validations: 24 | required: true 25 | - type: textarea 26 | id: additional-context 27 | attributes: 28 | label: Additional Context 29 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 30 | placeholder: "Provide context here." 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/style.yaml: -------------------------------------------------------------------------------- 1 | name: Style 2 | description: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) 3 | title: "style: " 4 | labels: [style] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: Clearly describe what you are looking to change and why. 11 | placeholder: "Provide a description of the style changes." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the unit or widget test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/test.yaml: -------------------------------------------------------------------------------- 1 | name: Test 2 | description: Adding missing tests or correcting existing tests 3 | title: "test: " 4 | labels: [test] 5 | body: 6 | - type: textarea 7 | id: description 8 | attributes: 9 | label: Description 10 | description: List out the tests that need to be added or changed. Please also include any information as to why this was not covered in the past. 11 | placeholder: "Provide a description of the tests that need to be added or changed." 12 | validations: 13 | required: true 14 | - type: textarea 15 | id: requirements 16 | attributes: 17 | label: Requirements 18 | description: The list of requirements that need to be met in order to consider the ticket to be completed. Please be as explicit as possible. 19 | value: | 20 | - [ ] All CI/CD checks are passing. 21 | - [ ] There is no drop in the test coverage percentage. 22 | validations: 23 | required: true 24 | - type: textarea 25 | id: additional-context 26 | attributes: 27 | label: Additional Context 28 | description: Add any other context, including links/screenshots/video recordings/etc about the problem here. 29 | placeholder: "Provide context here." 30 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | 9 | ## Status 10 | 11 | **READY/IN DEVELOPMENT/HOLD** 12 | 13 | ## Description 14 | 15 | 16 | 17 | ## Type of Change 18 | 19 | 20 | 21 | - [ ] ✨ New feature (non-breaking change which adds functionality) 22 | - [ ] 🛠️ Bug fix (non-breaking change which fixes an issue) 23 | - [ ] ❌ Breaking change (fix or feature that would cause existing functionality to change) 24 | - [ ] 🧹 Code refactor 25 | - [ ] ✅ Build configuration change 26 | - [ ] 📝 Documentation 27 | - [ ] 🗑️ Chore 28 | -------------------------------------------------------------------------------- /.github/cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2", 3 | "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", 4 | "dictionaries": [ 5 | "vgv_allowed", 6 | "vgv_forbidden" 7 | ], 8 | "dictionaryDefinitions": [ 9 | { 10 | "name": "vgv_allowed", 11 | "path": "https://raw.githubusercontent.com/verygoodopensource/very_good_dictionaries/main/allowed.txt", 12 | "description": "Allowed VGV Spellings" 13 | }, 14 | { 15 | "name": "vgv_forbidden", 16 | "path": "https://raw.githubusercontent.com/verygoodopensource/very_good_dictionaries/main/forbidden.txt", 17 | "description": "Forbidden VGV Spellings" 18 | } 19 | ], 20 | "useGitignore": true, 21 | "words": [ 22 | 23 | ] 24 | } -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | - package-ecosystem: "pub" 8 | directory: "/" 9 | schedule: 10 | interval: "daily" 11 | -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: pub_updater 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | on: 8 | push: 9 | branches: 10 | - main 11 | pull_request: 12 | branches: 13 | - main 14 | 15 | jobs: 16 | semantic-pull-request: 17 | uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/semantic_pull_request.yml@v1 18 | 19 | build: 20 | uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/dart_package.yml@v1 21 | 22 | spell-check: 23 | uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/spell_check.yml@v1 24 | with: 25 | includes: | 26 | **/*.{md,yaml} 27 | !.dart_tool/**/*.yaml 28 | .*/**/*.yml 29 | modified_files_only: false 30 | 31 | pana_score: 32 | uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/pana.yml@v1 33 | -------------------------------------------------------------------------------- /.github/workflows/pub_publish.yaml: -------------------------------------------------------------------------------- 1 | name: pub_publish 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v[0-9]+.[0-9]+.[0-9]+*" 7 | 8 | jobs: 9 | publish: 10 | permissions: 11 | id-token: write # Required for authentication using OIDC 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: 📚 Git Checkout 15 | uses: actions/checkout@v4 16 | - name: 🎯 Setup Dart 17 | uses: dart-lang/setup-dart@v1 18 | - name: 🐦 Setup Flutter 19 | uses: subosito/flutter-action@v2 20 | - name: 📦 Install Dependencies 21 | run: flutter pub get 22 | - name: 🌵 Dry Run 23 | run: dart pub publish --dry-run 24 | - name: 📢 Publish 25 | run: dart pub publish --force 26 | -------------------------------------------------------------------------------- /.github/workflows/sync_labels.yaml: -------------------------------------------------------------------------------- 1 | name: ♻️ Sync Labels 2 | 3 | on: 4 | push: 5 | paths: 6 | - .github/labels.yml 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | 11 | jobs: 12 | labels: 13 | name: ♻️ Sync labels 14 | runs-on: ubuntu-20.04 15 | steps: 16 | - name: ⤵️ Check out code from GitHub 17 | uses: actions/checkout@v4 18 | 19 | - name: 🚀 Run Label Sync 20 | uses: srealmoreno/label-sync-action@v2 21 | with: 22 | config-file: https://raw.githubusercontent.com/VeryGoodOpenSource/.github/main/.github/labels.yml 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://www.dartlang.org/guides/libraries/private-files 2 | 3 | # Files and directories created by pub 4 | .dart_tool/ 5 | .packages 6 | build/ 7 | pubspec.lock 8 | .test_coverage.dart 9 | coverage/ 10 | .idea/ 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.5.0 2 | 3 | - chore: tighten dependencies ([#62](https://github.com/VeryGoodOpenSource/pub_updater/pull/62)) 4 | 5 | # 0.4.0 6 | 7 | - fix!: activation of package on self-hosted url ([#46](https://github.com/VeryGoodOpenSource/pub_updater/pull/46)) 8 | - chore(deps): bump process from 4.2.4 to 5.0.0 ([#52](https://github.com/VeryGoodOpenSource/pub_updater/pull/52)) 9 | 10 | # [0.3.1](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.3.0...v0.3.1) (2023-06-19) 11 | 12 | # [0.3.0](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.2.4...v0.3.0) (2023-04-11) 13 | 14 | ### Bug Fixes 15 | 16 | - avoid false negatives when the current version is a pre-release and there is a prior stable release on pub ([#41](https://github.com/VeryGoodOpenSource/pub_updater/issues/41)) ([0a14ccd](https://github.com/VeryGoodOpenSource/pub_updater/commit/0a14ccdbedac8caa130cffeb3ea355483bce64d5)) 17 | 18 | # [0.2.4](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.2.3...v0.2.4) (2023-01-23) 19 | 20 | ### Features 21 | 22 | - add version constraints to update method ([#37](https://github.com/VeryGoodOpenSource/pub_updater/issues/37)) ([ec14539](https://github.com/VeryGoodOpenSource/pub_updater/commit/ec145392b76635123615556ad3e03c87e12a7fa4)) 23 | 24 | ## [0.2.3](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.2.2...v0.2.3) (2022-11-17) 25 | 26 | ### Features 27 | 28 | - add dependabot ([#26](https://github.com/VeryGoodOpenSource/pub_updater/issues/26)) ([3dca646](https://github.com/VeryGoodOpenSource/pub_updater/commit/3dca64625454fb18f2f4ff01b312b001d2d7d2e2)) 29 | - support custom base urls ([#33](https://github.com/VeryGoodOpenSource/pub_updater/issues/33)) ([682c6dd](https://github.com/VeryGoodOpenSource/pub_updater/commit/682c6dd424bc1d4dc8a128246f7212a89a24e99d)) 30 | 31 | ## [0.2.2](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.2.1...v0.2.2) (2021-11-16) 32 | 33 | ### Bug Fixes 34 | 35 | - widen dart compatibility ([#20](https://github.com/VeryGoodOpenSource/pub_updater/issues/20)) ([20358a3](https://github.com/VeryGoodOpenSource/pub_updater/commit/20358a3f263d6d7bb95600d2cf99cb35d103b319)) 36 | 37 | ## [0.2.1](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.2.0...v0.2.1) (2021-10-13) 38 | 39 | ### Bug Fixes 40 | 41 | - use /api/packages to fetch latest version ([#17](https://github.com/VeryGoodOpenSource/pub_updater/issues/17)) ([23dc699](https://github.com/VeryGoodOpenSource/pub_updater/commit/23dc699104ed137bd536daf99976a78462521fcd)) 42 | 43 | # [0.2.0](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.1.1...v0.2.0) (2021-10-12) 44 | 45 | ### Features 46 | 47 | - add getLatestVersion ([#14](https://github.com/VeryGoodOpenSource/pub_updater/issues/14)) ([b092f77](https://github.com/VeryGoodOpenSource/pub_updater/commit/b092f7709a9a1796d77bf4d265f385f420f1d4d6)) 48 | 49 | ## [0.1.1](https://github.com/VeryGoodOpenSource/pub_updater/compare/v0.1.0...v0.1.1) (2021-09-13) 50 | 51 | # [0.1.0](https://github.com/VeryGoodOpenSource/pub_updater/compare/adc13127067912e721849d56f334bfb7deaebde6...v0.1.0) (2021-09-13) 52 | 53 | ### Bug Fixes 54 | 55 | - use http.get when client is not provided ([#7](https://github.com/VeryGoodOpenSource/pub_updater/issues/7)) ([67ec60c](https://github.com/VeryGoodOpenSource/pub_updater/commit/67ec60c6d194e845af5af77f043fe76d67b87f3b)) 56 | 57 | ### Features 58 | 59 | - implement isUpToDate and update APIs ([#1](https://github.com/VeryGoodOpenSource/pub_updater/issues/1)) ([adc1312](https://github.com/VeryGoodOpenSource/pub_updater/commit/adc13127067912e721849d56f334bfb7deaebde6)) 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Very Good Ventures 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pub Updater 2 | 3 | [![Very Good Ventures][logo_white]][very_good_ventures_link_dark] 4 | [![Very Good Ventures][logo_black]][very_good_ventures_link_light] 5 | 6 | Developed with 💙 by [Very Good Ventures][very_good_ventures_link] 🦄 7 | 8 | [![Pub][pub_badge]][pub_link] 9 | [![build][ci_badge]][ci_link] 10 | [![coverage][coverage_badge]][ci_link] 11 | [![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] 12 | [![License: MIT][license_badge]][license_link] 13 | 14 | --- 15 | 16 | A Dart package which enables checking whether packages are up to date and supports updating them. 17 | 18 | Intended for use in CLIs for prompting users to auto-update. 19 | 20 | ## Usage 21 | 22 | ```dart 23 | import 'package:pub_updater/pub_updater.dart'; 24 | 25 | void main() async { 26 | // Create an instance of PubUpdater 27 | final pubUpdater = PubUpdater(); 28 | 29 | // Check whether or not version 0.1.0 is the latest version of my_package 30 | final isUpToDate = await pubUpdater.isUpToDate( 31 | packageName: 'my_package', 32 | currentVersion: '0.1.0', 33 | ); 34 | 35 | // Trigger an upgrade to the latest version if my_package is not up to date 36 | if (!isUpToDate) { 37 | await pubUpdater.update(packageName: 'my_package'); 38 | } 39 | 40 | // You can also query the latest version available for a specific package. 41 | final latestVersion = await pubUpdater.getLatestVersion('my_package'); 42 | } 43 | ``` 44 | 45 | [ci_badge]: https://github.com/VeryGoodOpenSource/pub_updater/actions/workflows/main.yaml/badge.svg 46 | [ci_link]: https://github.com/VeryGoodOpenSource/pub_updater/actions/workflows/main.yaml?query=branch%3Amain 47 | [coverage_badge]: https://raw.githubusercontent.com/VeryGoodOpenSource/pub_updater/main/coverage_badge.svg 48 | [logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only 49 | [logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only 50 | [license_badge]: https://img.shields.io/badge/license-MIT-blue.svg 51 | [license_link]: https://opensource.org/licenses/MIT 52 | [pub_badge]: https://img.shields.io/pub/v/pub_updater.svg 53 | [pub_link]: https://pub.dev/packages/pub_updater 54 | [very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg 55 | [very_good_analysis_link]: https://pub.dev/packages/very_good_analysis 56 | [very_good_ventures_link]: https://verygood.ventures 57 | [very_good_ventures_link_dark]: https://verygood.ventures#gh-dark-mode-only 58 | [very_good_ventures_link_light]: https://verygood.ventures#gh-light-mode-only 59 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:very_good_analysis/analysis_options.7.0.0.yaml 2 | -------------------------------------------------------------------------------- /build.yaml: -------------------------------------------------------------------------------- 1 | targets: 2 | $default: 3 | builders: 4 | source_gen|combining_builder: 5 | options: 6 | ignore_for_file: 7 | - document_ignores 8 | - implicit_dynamic_parameter 9 | - cast_nullable_to_non_nullable 10 | - require_trailing_commas 11 | - lines_longer_than_80_chars 12 | json_serializable: 13 | options: 14 | field_rename: snake 15 | create_to_json: false 16 | checked: true 17 | -------------------------------------------------------------------------------- /coverage_badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | coverage 16 | coverage 17 | 100% 18 | 100% 19 | 20 | 21 | -------------------------------------------------------------------------------- /example/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:developer'; 2 | 3 | import 'package:pub_updater/pub_updater.dart'; 4 | 5 | Future main() async { 6 | const packageName = 'my_package'; 7 | const currentVersion = '0.1.0'; 8 | 9 | // Initialize an instance of PubUpdater. 10 | final pubUpdater = PubUpdater(); 11 | 12 | // Check whether a package is up to date. 13 | final isUpToDate = await pubUpdater.isUpToDate( 14 | packageName: packageName, 15 | currentVersion: currentVersion, 16 | ); 17 | 18 | if (!isUpToDate) { 19 | // Upgrade to the latest version if not up to date. 20 | await pubUpdater.update(packageName: packageName); 21 | } 22 | 23 | // You can also query the latest version available for a specific package. 24 | final latestVersion = await pubUpdater.getLatestVersion(packageName); 25 | log(latestVersion); 26 | } 27 | -------------------------------------------------------------------------------- /lib/pub_updater.dart: -------------------------------------------------------------------------------- 1 | export 'src/pub_updater.dart'; 2 | -------------------------------------------------------------------------------- /lib/src/models/models.dart: -------------------------------------------------------------------------------- 1 | export 'package_info.dart'; 2 | -------------------------------------------------------------------------------- /lib/src/models/package_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'package_info.g.dart'; 4 | 5 | /// Class representing package information from pub.dev 6 | @JsonSerializable() 7 | class PackageInfo { 8 | /// Constructor for a [PackageInfo] object. 9 | /// Requires a name and list of versions. 10 | const PackageInfo({required this.name, required this.latest}); 11 | 12 | /// Constructor of PackageInfo object from JSON. 13 | factory PackageInfo.fromJson(Map json) => 14 | _$PackageInfoFromJson(json); 15 | 16 | /// The name of the package. 17 | final String name; 18 | 19 | /// The latest version of the package. 20 | @LatestVersionConverter() 21 | final String latest; 22 | } 23 | 24 | /// {@template latest_version_converter} 25 | /// A [JsonConverter] that handles (de)serializing the latest package version. 26 | /// {@endtemplate} 27 | class LatestVersionConverter 28 | implements JsonConverter> { 29 | /// {@macro latest_version_converter} 30 | const LatestVersionConverter(); 31 | 32 | @override 33 | String fromJson(Map json) => json['version'] as String; 34 | 35 | @override 36 | Map toJson(String object) { 37 | return {'version': object}; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/src/models/package_info.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | // ignore_for_file: document_ignores, implicit_dynamic_parameter, cast_nullable_to_non_nullable, require_trailing_commas, lines_longer_than_80_chars 4 | 5 | part of 'package_info.dart'; 6 | 7 | // ************************************************************************** 8 | // JsonSerializableGenerator 9 | // ************************************************************************** 10 | 11 | PackageInfo _$PackageInfoFromJson(Map json) => $checkedCreate( 12 | 'PackageInfo', 13 | json, 14 | ($checkedConvert) { 15 | final val = PackageInfo( 16 | name: $checkedConvert('name', (v) => v as String), 17 | latest: $checkedConvert( 18 | 'latest', 19 | (v) => const LatestVersionConverter() 20 | .fromJson(v as Map)), 21 | ); 22 | return val; 23 | }, 24 | ); 25 | -------------------------------------------------------------------------------- /lib/src/pub_updater.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | 4 | import 'package:http/http.dart' as http; 5 | import 'package:process/process.dart'; 6 | import 'package:pub_semver/pub_semver.dart'; 7 | import 'package:pub_updater/src/models/models.dart'; 8 | 9 | /// Exception thrown when the HTTP request fails. 10 | class PackageInfoRequestFailure implements Exception {} 11 | 12 | /// Exception thrown when the provided package information is not found. 13 | class PackageInfoNotFoundFailure implements Exception {} 14 | 15 | /// The pub.dev base url for querying package versions 16 | const _defaultBaseUrl = 'https://pub.dev'; 17 | 18 | /// The pub.dev api query path for querying packages 19 | const _pubPackagesPath = '/api/packages/'; 20 | 21 | /// {@template pub_update} 22 | /// A Dart package which enables checking whether a package is up to date. 23 | /// {@endtemplate} 24 | class PubUpdater { 25 | /// {@macro pub_update} 26 | PubUpdater([http.Client? client, String baseUrl = _defaultBaseUrl]) 27 | : _client = client, 28 | _baseUrl = baseUrl; 29 | 30 | final http.Client? _client; 31 | final String _baseUrl; 32 | 33 | Future _get(Uri uri) => _client?.get(uri) ?? http.get(uri); 34 | 35 | /// Checks whether or not [currentVersion] is the latest version 36 | /// for the package associated with [packageName] 37 | Future isUpToDate({ 38 | required String packageName, 39 | required String currentVersion, 40 | }) async { 41 | final latestVersion = await getLatestVersion(packageName); 42 | 43 | final currentVersionDesc = Version.parse(currentVersion); 44 | final latestVersionDesc = Version.parse(latestVersion); 45 | 46 | if (!latestVersionDesc.isPreRelease && currentVersionDesc.isPreRelease) { 47 | // If the current version is a pre-release but the latest isn't, 48 | // skip the version checking. 49 | return true; 50 | } 51 | 52 | return currentVersion == latestVersion; 53 | } 54 | 55 | /// Returns the latest published version of [packageName]. 56 | Future getLatestVersion(String packageName) async { 57 | final packageInfo = await _getPackageInfo(packageName); 58 | return packageInfo.latest; 59 | } 60 | 61 | /// Updates the package associated with [packageName] 62 | Future update({ 63 | required String packageName, 64 | ProcessManager processManager = const LocalProcessManager(), 65 | String? versionConstraint, 66 | }) { 67 | return processManager.run( 68 | [ 69 | 'dart', 70 | 'pub', 71 | 'global', 72 | 'activate', 73 | packageName, 74 | if (versionConstraint != null) versionConstraint, 75 | if (_baseUrl != _defaultBaseUrl) ...[ 76 | '--hosted-url', 77 | _baseUrl, 78 | '--source', 79 | 'hosted', 80 | ], 81 | ], 82 | ); 83 | } 84 | 85 | Future _getPackageInfo(String packageName) async { 86 | final uri = Uri.parse('$_baseUrl$_pubPackagesPath$packageName'); 87 | final response = await _get(uri); 88 | 89 | if (response.statusCode != HttpStatus.ok) throw PackageInfoRequestFailure(); 90 | 91 | return _decodePackageInfo(response.body); 92 | } 93 | 94 | PackageInfo _decodePackageInfo(String body) { 95 | final packageJson = jsonDecode(body) as Map; 96 | 97 | if (packageJson.isEmpty) throw PackageInfoNotFoundFailure(); 98 | 99 | return PackageInfo.fromJson(packageJson); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: pub_updater 2 | description: A Dart package which enables checking whether a package is up to date. 3 | version: 0.5.0 4 | repository: https://github.com/VeryGoodOpenSource/pub_updater 5 | issue_tracker: https://github.com/VeryGoodOpenSource/pub_updater/issues 6 | topics: [cli, pub, version] 7 | 8 | environment: 9 | sdk: ^3.5.0 10 | 11 | dependencies: 12 | http: ^1.2.2 13 | json_annotation: ^4.9.0 14 | process: ^5.0.2 15 | pub_semver: ^2.1.4 16 | 17 | dev_dependencies: 18 | build_runner: ^2.4.12 19 | json_serializable: ^6.8.0 20 | mocktail: ^1.0.4 21 | test: ^1.25.8 22 | very_good_analysis: ^7.0.0 23 | -------------------------------------------------------------------------------- /test/fixtures/fixtures.dart: -------------------------------------------------------------------------------- 1 | export 'pre_release_package_info_response.dart'; 2 | export 'valid_package_info_response.dart'; 3 | -------------------------------------------------------------------------------- /test/fixtures/pre_release_package_info_response.dart: -------------------------------------------------------------------------------- 1 | // Generated test file so these don't apply 2 | // ignore_for_file: prefer_single_quotes, lines_longer_than_80_chars 3 | // Generated from: https://pub.dev/api/packages/mason 4 | 5 | import 'dart:convert'; 6 | 7 | final preReleasePackageInfoResponseBody = json.encode( 8 | preReleasePackageInfoResponse, 9 | ); 10 | 11 | const preReleasePackageInfoResponse = { 12 | "name": "mason", 13 | "latest": { 14 | "version": "0.1.0-dev.48", 15 | "pubspec": { 16 | "name": "mason", 17 | "description": 18 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 19 | "version": "0.1.0-dev.48", 20 | "homepage": "https://github.com/felangel/mason", 21 | "repository": "https://github.com/felangel/mason", 22 | "issue_tracker": "https://github.com/felangel/mason/issues", 23 | "documentation": 24 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 25 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 26 | "dependencies": { 27 | "archive": "^3.1.11", 28 | "checked_yaml": "^2.0.1", 29 | "collection": "^1.15.0", 30 | "convert": "^3.1.0", 31 | "crypto": "^3.0.1", 32 | "http": "^0.13.3", 33 | "json_annotation": "^4.8.0", 34 | "mason_logger": "^0.2.5", 35 | "meta": "^1.7.0", 36 | "mustache_template": "^2.0.0", 37 | "path": "^1.8.0", 38 | "pool": "^1.5.1", 39 | "pub_semver": "^2.1.0", 40 | "recase": "^4.0.0", 41 | "yaml": "^3.1.0", 42 | }, 43 | "dev_dependencies": { 44 | "build_runner": "^2.0.0", 45 | "build_verify": "^3.0.0", 46 | "build_version": "^2.0.0", 47 | "json_serializable": "^6.0.0", 48 | "mocktail": "^0.3.0", 49 | "test": "^1.17.0", 50 | "very_good_analysis": "^4.0.0", 51 | }, 52 | }, 53 | "archive_url": 54 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.48.tar.gz", 55 | "archive_sha256": 56 | "d122e582f4c332b33d95289aafdea475ff5446e9939338b4b6330e2e488ed4e1", 57 | "published": "2023-03-24T04:15:07.809166Z", 58 | }, 59 | "versions": [ 60 | { 61 | "version": "0.1.0-dev.41", 62 | "pubspec": { 63 | "name": "mason", 64 | "description": 65 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 66 | "version": "0.1.0-dev.41", 67 | "homepage": "https://github.com/felangel/mason", 68 | "repository": "https://github.com/felangel/mason", 69 | "issue_tracker": "https://github.com/felangel/mason/issues", 70 | "documentation": 71 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 72 | "environment": {"sdk": ">=2.17.0 <3.0.0"}, 73 | "dependencies": { 74 | "archive": "^3.1.11", 75 | "checked_yaml": "^2.0.1", 76 | "collection": "^1.15.0", 77 | "convert": "^3.1.0", 78 | "crypto": "^3.0.1", 79 | "http": "^0.13.3", 80 | "json_annotation": "^4.4.0", 81 | "mason_logger": "^0.2.4", 82 | "meta": "^1.7.0", 83 | "mustache_template": "^2.0.0", 84 | "path": "^1.8.0", 85 | "pool": "^1.5.1", 86 | "pub_semver": "^2.1.0", 87 | "recase": "^4.0.0", 88 | "yaml": "^3.1.0", 89 | }, 90 | "dev_dependencies": { 91 | "build_runner": "^2.0.0", 92 | "build_verify": "^3.0.0", 93 | "build_version": "^2.0.0", 94 | "json_serializable": "^6.0.0", 95 | "mocktail": "^0.3.0", 96 | "test": "^1.17.0", 97 | "very_good_analysis": "^3.1.0", 98 | }, 99 | }, 100 | "archive_url": 101 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.41.tar.gz", 102 | "archive_sha256": 103 | "e7b919e7d1f300504017d168d0d4d253cd06ef812149561d984abd3af8ad3ee2", 104 | "published": "2023-01-30T05:01:34.751328Z", 105 | }, 106 | { 107 | "version": "0.1.0-dev.42", 108 | "pubspec": { 109 | "name": "mason", 110 | "description": 111 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 112 | "version": "0.1.0-dev.42", 113 | "homepage": "https://github.com/felangel/mason", 114 | "repository": "https://github.com/felangel/mason", 115 | "issue_tracker": "https://github.com/felangel/mason/issues", 116 | "documentation": 117 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 118 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 119 | "dependencies": { 120 | "archive": "^3.1.11", 121 | "checked_yaml": "^2.0.1", 122 | "collection": "^1.15.0", 123 | "convert": "^3.1.0", 124 | "crypto": "^3.0.1", 125 | "http": "^0.13.3", 126 | "json_annotation": "^4.4.0", 127 | "mason_logger": "^0.2.5", 128 | "meta": "^1.7.0", 129 | "mustache_template": "^2.0.0", 130 | "path": "^1.8.0", 131 | "pool": "^1.5.1", 132 | "pub_semver": "^2.1.0", 133 | "recase": "^4.0.0", 134 | "yaml": "^3.1.0", 135 | }, 136 | "dev_dependencies": { 137 | "build_runner": "^2.0.0", 138 | "build_verify": "^3.0.0", 139 | "build_version": "^2.0.0", 140 | "json_serializable": "^6.0.0", 141 | "mocktail": "^0.3.0", 142 | "test": "^1.17.0", 143 | "very_good_analysis": "^4.0.0", 144 | }, 145 | }, 146 | "archive_url": 147 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.42.tar.gz", 148 | "archive_sha256": 149 | "d955859f39414165bb226a805f6dfa3d254a4c80c1358e1acef168e2b69799f7", 150 | "published": "2023-02-14T05:17:31.153571Z", 151 | }, 152 | { 153 | "version": "0.1.0-dev.43", 154 | "pubspec": { 155 | "name": "mason", 156 | "description": 157 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 158 | "version": "0.1.0-dev.43", 159 | "homepage": "https://github.com/felangel/mason", 160 | "repository": "https://github.com/felangel/mason", 161 | "issue_tracker": "https://github.com/felangel/mason/issues", 162 | "documentation": 163 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 164 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 165 | "dependencies": { 166 | "archive": "^3.1.11", 167 | "checked_yaml": "^2.0.1", 168 | "collection": "^1.15.0", 169 | "convert": "^3.1.0", 170 | "crypto": "^3.0.1", 171 | "http": "^0.13.3", 172 | "json_annotation": "^4.4.0", 173 | "mason_logger": "^0.2.5", 174 | "meta": "^1.7.0", 175 | "mustache_template": "^2.0.0", 176 | "path": "^1.8.0", 177 | "pool": "^1.5.1", 178 | "pub_semver": "^2.1.0", 179 | "recase": "^4.0.0", 180 | "yaml": "^3.1.0", 181 | }, 182 | "dev_dependencies": { 183 | "build_runner": "^2.0.0", 184 | "build_verify": "^3.0.0", 185 | "build_version": "^2.0.0", 186 | "json_serializable": "^6.0.0", 187 | "mocktail": "^0.3.0", 188 | "test": "^1.17.0", 189 | "very_good_analysis": "^4.0.0", 190 | }, 191 | }, 192 | "archive_url": 193 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.43.tar.gz", 194 | "archive_sha256": 195 | "05aade552ea1ac9d8402ba5d1a5edd0ba66e908e4c9e911ff35954f21ac2efac", 196 | "published": "2023-02-22T03:39:28.752645Z", 197 | }, 198 | { 199 | "version": "0.1.0-dev.44", 200 | "pubspec": { 201 | "name": "mason", 202 | "description": 203 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 204 | "version": "0.1.0-dev.44", 205 | "homepage": "https://github.com/felangel/mason", 206 | "repository": "https://github.com/felangel/mason", 207 | "issue_tracker": "https://github.com/felangel/mason/issues", 208 | "documentation": 209 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 210 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 211 | "dependencies": { 212 | "archive": "^3.1.11", 213 | "checked_yaml": "^2.0.1", 214 | "collection": "^1.15.0", 215 | "convert": "^3.1.0", 216 | "crypto": "^3.0.1", 217 | "http": "^0.13.3", 218 | "json_annotation": "^4.4.0", 219 | "mason_logger": "^0.2.5", 220 | "meta": "^1.7.0", 221 | "mustache_template": "^2.0.0", 222 | "path": "^1.8.0", 223 | "pool": "^1.5.1", 224 | "pub_semver": "^2.1.0", 225 | "recase": "^4.0.0", 226 | "yaml": "^3.1.0", 227 | }, 228 | "dev_dependencies": { 229 | "build_runner": "^2.0.0", 230 | "build_verify": "^3.0.0", 231 | "build_version": "^2.0.0", 232 | "json_serializable": "^6.0.0", 233 | "mocktail": "^0.3.0", 234 | "test": "^1.17.0", 235 | "very_good_analysis": "^4.0.0", 236 | }, 237 | }, 238 | "archive_url": 239 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.44.tar.gz", 240 | "archive_sha256": 241 | "c0f91d86661712e54effed79e017304b54345f88e11f044beaa3d495cc706fd3", 242 | "published": "2023-02-23T04:05:55.180999Z", 243 | }, 244 | { 245 | "version": "0.1.0-dev.45", 246 | "pubspec": { 247 | "name": "mason", 248 | "description": 249 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 250 | "version": "0.1.0-dev.45", 251 | "homepage": "https://github.com/felangel/mason", 252 | "repository": "https://github.com/felangel/mason", 253 | "issue_tracker": "https://github.com/felangel/mason/issues", 254 | "documentation": 255 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 256 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 257 | "dependencies": { 258 | "archive": "^3.1.11", 259 | "checked_yaml": "^2.0.1", 260 | "collection": "^1.15.0", 261 | "convert": "^3.1.0", 262 | "crypto": "^3.0.1", 263 | "http": "^0.13.3", 264 | "json_annotation": "^4.4.0", 265 | "mason_logger": "^0.2.5", 266 | "meta": "^1.7.0", 267 | "mustache_template": "^2.0.0", 268 | "path": "^1.8.0", 269 | "pool": "^1.5.1", 270 | "pub_semver": "^2.1.0", 271 | "recase": "^4.0.0", 272 | "yaml": "^3.1.0", 273 | }, 274 | "dev_dependencies": { 275 | "build_runner": "^2.0.0", 276 | "build_verify": "^3.0.0", 277 | "build_version": "^2.0.0", 278 | "json_serializable": "^6.0.0", 279 | "mocktail": "^0.3.0", 280 | "test": "^1.17.0", 281 | "very_good_analysis": "^4.0.0", 282 | }, 283 | }, 284 | "archive_url": 285 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.45.tar.gz", 286 | "archive_sha256": 287 | "6ad83d2b3c1ffd56a61f059e7935f1878f77d4f2204efbf9127344da629bac4d", 288 | "published": "2023-02-23T05:34:13.243854Z", 289 | }, 290 | { 291 | "version": "0.1.0-dev.46", 292 | "pubspec": { 293 | "name": "mason", 294 | "description": 295 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 296 | "version": "0.1.0-dev.46", 297 | "homepage": "https://github.com/felangel/mason", 298 | "repository": "https://github.com/felangel/mason", 299 | "issue_tracker": "https://github.com/felangel/mason/issues", 300 | "documentation": 301 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 302 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 303 | "dependencies": { 304 | "archive": "^3.1.11", 305 | "checked_yaml": "^2.0.1", 306 | "collection": "^1.15.0", 307 | "convert": "^3.1.0", 308 | "crypto": "^3.0.1", 309 | "http": "^0.13.3", 310 | "json_annotation": "^4.8.0", 311 | "mason_logger": "^0.2.5", 312 | "meta": "^1.7.0", 313 | "mustache_template": "^2.0.0", 314 | "path": "^1.8.0", 315 | "pool": "^1.5.1", 316 | "pub_semver": "^2.1.0", 317 | "recase": "^4.0.0", 318 | "yaml": "^3.1.0", 319 | }, 320 | "dev_dependencies": { 321 | "build_runner": "^2.0.0", 322 | "build_verify": "^3.0.0", 323 | "build_version": "^2.0.0", 324 | "json_serializable": "^6.0.0", 325 | "mocktail": "^0.3.0", 326 | "test": "^1.17.0", 327 | "very_good_analysis": "^4.0.0", 328 | }, 329 | }, 330 | "archive_url": 331 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.46.tar.gz", 332 | "archive_sha256": 333 | "558e04e0b4541140b73b113148ffbb73e81710f61ff3f3b6f36e14bf7dbc0c71", 334 | "published": "2023-02-23T06:04:28.358762Z", 335 | }, 336 | { 337 | "version": "0.1.0-dev.47", 338 | "pubspec": { 339 | "name": "mason", 340 | "description": 341 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 342 | "version": "0.1.0-dev.47", 343 | "homepage": "https://github.com/felangel/mason", 344 | "repository": "https://github.com/felangel/mason", 345 | "issue_tracker": "https://github.com/felangel/mason/issues", 346 | "documentation": 347 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 348 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 349 | "dependencies": { 350 | "archive": "^3.1.11", 351 | "checked_yaml": "^2.0.1", 352 | "collection": "^1.15.0", 353 | "convert": "^3.1.0", 354 | "crypto": "^3.0.1", 355 | "http": "^0.13.3", 356 | "json_annotation": "^4.8.0", 357 | "mason_logger": "^0.2.5", 358 | "meta": "^1.7.0", 359 | "mustache_template": "^2.0.0", 360 | "path": "^1.8.0", 361 | "pool": "^1.5.1", 362 | "pub_semver": "^2.1.0", 363 | "recase": "^4.0.0", 364 | "yaml": "^3.1.0", 365 | }, 366 | "dev_dependencies": { 367 | "build_runner": "^2.0.0", 368 | "build_verify": "^3.0.0", 369 | "build_version": "^2.0.0", 370 | "json_serializable": "^6.0.0", 371 | "mocktail": "^0.3.0", 372 | "test": "^1.17.0", 373 | "very_good_analysis": "^4.0.0", 374 | }, 375 | }, 376 | "archive_url": 377 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.47.tar.gz", 378 | "archive_sha256": 379 | "b4030d8799f255caa914beb2604dcd749d0ebd815c3f0209ed223f9370098c10", 380 | "published": "2023-03-01T04:37:08.159381Z", 381 | }, 382 | { 383 | "version": "0.1.0-dev.48", 384 | "pubspec": { 385 | "name": "mason", 386 | "description": 387 | "A Dart template generator which helps teams generate files quickly and consistently.\n", 388 | "version": "0.1.0-dev.48", 389 | "homepage": "https://github.com/felangel/mason", 390 | "repository": "https://github.com/felangel/mason", 391 | "issue_tracker": "https://github.com/felangel/mason/issues", 392 | "documentation": 393 | "https://github.com/felangel/mason/tree/master/packages/mason_cli#readme", 394 | "environment": {"sdk": ">=2.19.0 <3.0.0"}, 395 | "dependencies": { 396 | "archive": "^3.1.11", 397 | "checked_yaml": "^2.0.1", 398 | "collection": "^1.15.0", 399 | "convert": "^3.1.0", 400 | "crypto": "^3.0.1", 401 | "http": "^0.13.3", 402 | "json_annotation": "^4.8.0", 403 | "mason_logger": "^0.2.5", 404 | "meta": "^1.7.0", 405 | "mustache_template": "^2.0.0", 406 | "path": "^1.8.0", 407 | "pool": "^1.5.1", 408 | "pub_semver": "^2.1.0", 409 | "recase": "^4.0.0", 410 | "yaml": "^3.1.0", 411 | }, 412 | "dev_dependencies": { 413 | "build_runner": "^2.0.0", 414 | "build_verify": "^3.0.0", 415 | "build_version": "^2.0.0", 416 | "json_serializable": "^6.0.0", 417 | "mocktail": "^0.3.0", 418 | "test": "^1.17.0", 419 | "very_good_analysis": "^4.0.0", 420 | }, 421 | }, 422 | "archive_url": 423 | "https://pub.dartlang.org/packages/mason/versions/0.1.0-dev.48.tar.gz", 424 | "archive_sha256": 425 | "d122e582f4c332b33d95289aafdea475ff5446e9939338b4b6330e2e488ed4e1", 426 | "published": "2023-03-24T04:15:07.809166Z", 427 | } 428 | ], 429 | }; 430 | -------------------------------------------------------------------------------- /test/fixtures/valid_package_info_response.dart: -------------------------------------------------------------------------------- 1 | // Generated test file so these don't apply 2 | // ignore_for_file: prefer_single_quotes, lines_longer_than_80_chars 3 | // Generated from: https://pub.dev/api/packages/very_good_cli 4 | 5 | import 'dart:convert'; 6 | 7 | final validPackageInfoResponseBody = json.encode(validPackageInfoResponse); 8 | 9 | const validPackageInfoResponse = { 10 | "name": "very_good_cli", 11 | "latest": { 12 | "version": "0.4.6", 13 | "pubspec": { 14 | "name": "very_good_cli", 15 | "description": 16 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 17 | "version": "0.4.6", 18 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 19 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 20 | "dependencies": { 21 | "args": "^2.1.0", 22 | "io": "^1.0.0", 23 | "mason": "^0.0.1-dev.51", 24 | "meta": "^1.3.0", 25 | "path": "^1.8.0", 26 | "pub_updater": "^0.1.0", 27 | "universal_io": "^2.0.4", 28 | "usage": "^4.0.2", 29 | "very_good_analysis": "^2.3.0", 30 | }, 31 | "dev_dependencies": { 32 | "build_runner": "^2.0.0", 33 | "build_verify": "^2.0.0", 34 | "build_version": "^2.0.0", 35 | "mocktail": "^0.1.1", 36 | "test": ">=1.17.0 <1.18.0", 37 | }, 38 | "executables": {"very_good": null}, 39 | }, 40 | "archive_url": 41 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.6.tar.gz", 42 | "published": "2021-10-07T21:23:42.789542Z", 43 | }, 44 | "versions": [ 45 | { 46 | "version": "0.1.0", 47 | "pubspec": { 48 | "name": "very_good_cli", 49 | "description": 50 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 51 | "version": "0.1.0", 52 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 53 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 54 | "dependencies": { 55 | "args": "^1.6.0", 56 | "io": "^0.3.4", 57 | "mason": "^0.0.1-dev.26", 58 | "meta": "^1.2.4", 59 | "path": "^1.7.0", 60 | "usage": "^3.4.2", 61 | "very_good_analysis": "^1.0.4", 62 | }, 63 | "dev_dependencies": { 64 | "coverage": "^0.13.4", 65 | "build_runner": "^1.10.0", 66 | "build_verify": "^1.1.1", 67 | "build_version": "^2.0.1", 68 | "mockito": "^4.0.0", 69 | "test": "^1.14.3", 70 | }, 71 | "executables": {"very_good": null}, 72 | }, 73 | "archive_url": 74 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.0.tar.gz", 75 | "published": "2021-02-16T23:08:13.514923Z", 76 | }, 77 | { 78 | "version": "0.1.1", 79 | "pubspec": { 80 | "name": "very_good_cli", 81 | "description": 82 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 83 | "version": "0.1.1", 84 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 85 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 86 | "dependencies": { 87 | "args": "^1.6.0", 88 | "io": "^0.3.4", 89 | "mason": "^0.0.1-dev.26", 90 | "meta": "^1.2.4", 91 | "path": "^1.7.0", 92 | "usage": "^3.4.2", 93 | "very_good_analysis": "^1.0.4", 94 | }, 95 | "dev_dependencies": { 96 | "coverage": "^0.13.4", 97 | "build_runner": "^1.10.0", 98 | "build_verify": "^1.1.1", 99 | "build_version": "^2.0.1", 100 | "mockito": "^4.0.0", 101 | "test": "^1.14.3", 102 | }, 103 | "executables": {"very_good": null}, 104 | }, 105 | "archive_url": 106 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.1.tar.gz", 107 | "published": "2021-02-16T23:18:19.290460Z", 108 | }, 109 | { 110 | "version": "0.1.2", 111 | "pubspec": { 112 | "name": "very_good_cli", 113 | "description": 114 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 115 | "version": "0.1.2", 116 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 117 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 118 | "dependencies": { 119 | "args": "^1.6.0", 120 | "io": "^0.3.4", 121 | "mason": "^0.0.1-dev.26", 122 | "meta": "^1.2.4", 123 | "path": "^1.7.0", 124 | "usage": "^3.4.2", 125 | "very_good_analysis": "^1.0.4", 126 | }, 127 | "dev_dependencies": { 128 | "coverage": "^0.13.4", 129 | "build_runner": "^1.10.0", 130 | "build_verify": "^1.1.1", 131 | "build_version": "^2.0.1", 132 | "mockito": "^4.0.0", 133 | "test": "^1.14.3", 134 | }, 135 | "executables": {"very_good": null}, 136 | }, 137 | "archive_url": 138 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.2.tar.gz", 139 | "published": "2021-02-22T23:35:02.618800Z", 140 | }, 141 | { 142 | "version": "0.1.3", 143 | "pubspec": { 144 | "name": "very_good_cli", 145 | "description": 146 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 147 | "version": "0.1.3", 148 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 149 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 150 | "dependencies": { 151 | "args": "^1.6.0", 152 | "io": "^0.3.4", 153 | "mason": "^0.0.1-dev.26", 154 | "meta": "^1.2.4", 155 | "path": "^1.7.0", 156 | "usage": "^3.4.2", 157 | "very_good_analysis": "^1.0.4", 158 | }, 159 | "dev_dependencies": { 160 | "coverage": "^0.13.4", 161 | "build_runner": "^1.10.0", 162 | "build_verify": "^1.1.1", 163 | "build_version": "^2.0.1", 164 | "mockito": "^4.0.0", 165 | "test": "^1.14.3", 166 | }, 167 | "executables": {"very_good": null}, 168 | }, 169 | "archive_url": 170 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.3.tar.gz", 171 | "published": "2021-03-03T21:32:24.349564Z", 172 | }, 173 | { 174 | "version": "0.1.4", 175 | "pubspec": { 176 | "name": "very_good_cli", 177 | "description": 178 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 179 | "version": "0.1.4", 180 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 181 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 182 | "dependencies": { 183 | "args": "^1.6.0", 184 | "io": "^0.3.4", 185 | "mason": "^0.0.1-dev.26", 186 | "meta": "^1.2.4", 187 | "path": "^1.7.0", 188 | "usage": "^3.4.2", 189 | "very_good_analysis": "^1.0.4", 190 | }, 191 | "dev_dependencies": { 192 | "coverage": "^0.13.4", 193 | "build_runner": "^1.10.0", 194 | "build_verify": "^1.1.1", 195 | "build_version": "^2.0.1", 196 | "mockito": "^4.0.0", 197 | "test": "^1.14.3", 198 | }, 199 | "executables": {"very_good": null}, 200 | }, 201 | "archive_url": 202 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.4.tar.gz", 203 | "published": "2021-03-09T22:23:36.871091Z", 204 | }, 205 | { 206 | "version": "0.1.5", 207 | "pubspec": { 208 | "name": "very_good_cli", 209 | "description": 210 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 211 | "version": "0.1.5", 212 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 213 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 214 | "dependencies": { 215 | "args": "^1.6.0", 216 | "io": "^0.3.4", 217 | "mason": "^0.0.1-dev.26", 218 | "meta": "^1.2.4", 219 | "path": "^1.7.0", 220 | "usage": "^3.4.2", 221 | "very_good_analysis": "^1.0.4", 222 | }, 223 | "dev_dependencies": { 224 | "coverage": "^0.13.4", 225 | "build_runner": "^1.10.0", 226 | "build_verify": "^1.1.1", 227 | "build_version": "^2.0.1", 228 | "mockito": "^4.0.0", 229 | "test": "^1.14.3", 230 | }, 231 | "executables": {"very_good": null}, 232 | }, 233 | "archive_url": 234 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.5.tar.gz", 235 | "published": "2021-03-12T05:20:37.441168Z", 236 | }, 237 | { 238 | "version": "0.1.6", 239 | "pubspec": { 240 | "name": "very_good_cli", 241 | "description": 242 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 243 | "version": "0.1.6", 244 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 245 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 246 | "dependencies": { 247 | "args": "^1.6.0", 248 | "io": "^0.3.4", 249 | "mason": "^0.0.1-dev.26", 250 | "meta": "^1.2.4", 251 | "path": "^1.7.0", 252 | "usage": "^3.4.2", 253 | "very_good_analysis": "^1.0.4", 254 | }, 255 | "dev_dependencies": { 256 | "coverage": "^0.13.4", 257 | "build_runner": "^1.10.0", 258 | "build_verify": "^1.1.1", 259 | "build_version": "^2.0.1", 260 | "mockito": "^4.0.0", 261 | "test": "^1.14.3", 262 | }, 263 | "executables": {"very_good": null}, 264 | }, 265 | "archive_url": 266 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.6.tar.gz", 267 | "published": "2021-03-18T16:00:33.661957Z", 268 | }, 269 | { 270 | "version": "0.1.7", 271 | "pubspec": { 272 | "name": "very_good_cli", 273 | "description": 274 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 275 | "version": "0.1.7", 276 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 277 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 278 | "dependencies": { 279 | "args": "^1.6.0", 280 | "io": "^0.3.4", 281 | "mason": "^0.0.1-dev.26", 282 | "meta": "^1.2.4", 283 | "path": "^1.7.0", 284 | "usage": "^3.4.2", 285 | "very_good_analysis": "^1.0.4", 286 | }, 287 | "dev_dependencies": { 288 | "coverage": "^0.13.4", 289 | "build_runner": "^1.10.0", 290 | "build_verify": "^1.1.1", 291 | "build_version": "^2.0.1", 292 | "mockito": "^4.0.0", 293 | "test": "^1.14.3", 294 | }, 295 | "executables": {"very_good": null}, 296 | }, 297 | "archive_url": 298 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.7.tar.gz", 299 | "published": "2021-04-01T17:48:32.315320Z", 300 | }, 301 | { 302 | "version": "0.1.8", 303 | "pubspec": { 304 | "name": "very_good_cli", 305 | "description": 306 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 307 | "version": "0.1.8", 308 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 309 | "environment": {"sdk": ">=2.10.0 <3.0.0"}, 310 | "dependencies": { 311 | "args": "^1.6.0", 312 | "io": "^0.3.4", 313 | "mason": "^0.0.1-dev.26", 314 | "meta": "^1.2.4", 315 | "path": "^1.7.0", 316 | "usage": "^3.4.2", 317 | "very_good_analysis": "^1.0.4", 318 | }, 319 | "dev_dependencies": { 320 | "coverage": "^0.13.4", 321 | "build_runner": "^1.10.0", 322 | "build_verify": "^1.1.1", 323 | "build_version": "^2.0.1", 324 | "mockito": "^4.0.0", 325 | "test": "^1.14.3", 326 | }, 327 | "executables": {"very_good": null}, 328 | }, 329 | "archive_url": 330 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.1.8.tar.gz", 331 | "published": "2021-05-21T21:33:07.243329Z", 332 | }, 333 | { 334 | "version": "0.2.0", 335 | "pubspec": { 336 | "name": "very_good_cli", 337 | "description": 338 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 339 | "version": "0.2.0", 340 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 341 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 342 | "dependencies": { 343 | "args": "^2.1.0", 344 | "io": "^1.0.0", 345 | "mason": "^0.0.1-dev.29", 346 | "meta": "^1.3.0", 347 | "path": "^1.8.0", 348 | "universal_io": "^2.0.4", 349 | "usage": "^4.0.2", 350 | "very_good_analysis": "^2.0.3", 351 | }, 352 | "dev_dependencies": { 353 | "build_runner": "^2.0.0", 354 | "build_verify": "^2.0.0", 355 | "build_version": "^2.0.0", 356 | "mocktail": "^0.1.1", 357 | "test": "^1.17.0", 358 | }, 359 | "executables": {"very_good": null}, 360 | }, 361 | "archive_url": 362 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.2.0.tar.gz", 363 | "published": "2021-05-25T17:39:13.155424Z", 364 | }, 365 | { 366 | "version": "0.2.1", 367 | "pubspec": { 368 | "name": "very_good_cli", 369 | "description": 370 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 371 | "version": "0.2.1", 372 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 373 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 374 | "dependencies": { 375 | "args": "^2.1.0", 376 | "io": "^1.0.0", 377 | "mason": "^0.0.1-dev.30", 378 | "meta": "^1.3.0", 379 | "path": "^1.8.0", 380 | "universal_io": "^2.0.4", 381 | "usage": "^4.0.2", 382 | "very_good_analysis": "^2.0.3", 383 | }, 384 | "dev_dependencies": { 385 | "build_runner": "^2.0.0", 386 | "build_verify": "^2.0.0", 387 | "build_version": "^2.0.0", 388 | "mocktail": "^0.1.1", 389 | "test": "^1.17.0", 390 | }, 391 | "executables": {"very_good": null}, 392 | }, 393 | "archive_url": 394 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.2.1.tar.gz", 395 | "published": "2021-05-26T18:10:14.293879Z", 396 | }, 397 | { 398 | "version": "0.2.2", 399 | "pubspec": { 400 | "name": "very_good_cli", 401 | "description": 402 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 403 | "version": "0.2.2", 404 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 405 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 406 | "dependencies": { 407 | "args": "^2.1.0", 408 | "io": "^1.0.0", 409 | "mason": "^0.0.1-dev.30", 410 | "meta": "^1.3.0", 411 | "path": "^1.8.0", 412 | "universal_io": "^2.0.4", 413 | "usage": "^4.0.2", 414 | "very_good_analysis": "^2.1.0", 415 | }, 416 | "dev_dependencies": { 417 | "build_runner": "^2.0.0", 418 | "build_verify": "^2.0.0", 419 | "build_version": "^2.0.0", 420 | "mocktail": "^0.1.1", 421 | "test": "^1.17.0", 422 | }, 423 | "executables": {"very_good": null}, 424 | }, 425 | "archive_url": 426 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.2.2.tar.gz", 427 | "published": "2021-06-10T15:03:36.752106Z", 428 | }, 429 | { 430 | "version": "0.2.3", 431 | "pubspec": { 432 | "name": "very_good_cli", 433 | "description": 434 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 435 | "version": "0.2.3", 436 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 437 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 438 | "dependencies": { 439 | "args": "^2.1.0", 440 | "io": "^1.0.0", 441 | "mason": "^0.0.1-dev.41", 442 | "meta": "^1.3.0", 443 | "path": "^1.8.0", 444 | "universal_io": "^2.0.4", 445 | "usage": "^4.0.2", 446 | "very_good_analysis": "^2.1.0", 447 | }, 448 | "dev_dependencies": { 449 | "build_runner": "^2.0.0", 450 | "build_verify": "^2.0.0", 451 | "build_version": "^2.0.0", 452 | "mocktail": "^0.1.1", 453 | "test": "^1.17.0", 454 | }, 455 | "executables": {"very_good": null}, 456 | }, 457 | "archive_url": 458 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.2.3.tar.gz", 459 | "published": "2021-06-15T17:32:35.612405Z", 460 | }, 461 | { 462 | "version": "0.2.4", 463 | "pubspec": { 464 | "name": "very_good_cli", 465 | "description": 466 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 467 | "version": "0.2.4", 468 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 469 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 470 | "dependencies": { 471 | "args": "^2.1.0", 472 | "io": "^1.0.0", 473 | "mason": "^0.0.1-dev.41", 474 | "meta": "^1.3.0", 475 | "path": "^1.8.0", 476 | "universal_io": "^2.0.4", 477 | "usage": "^4.0.2", 478 | "very_good_analysis": "^2.1.0", 479 | }, 480 | "dev_dependencies": { 481 | "build_runner": "^2.0.0", 482 | "build_verify": "^2.0.0", 483 | "build_version": "^2.0.0", 484 | "mocktail": "^0.1.1", 485 | "test": "^1.17.0", 486 | }, 487 | "executables": {"very_good": null}, 488 | }, 489 | "archive_url": 490 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.2.4.tar.gz", 491 | "published": "2021-07-14T16:05:09.865060Z", 492 | }, 493 | { 494 | "version": "0.2.5", 495 | "pubspec": { 496 | "name": "very_good_cli", 497 | "description": 498 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 499 | "version": "0.2.5", 500 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 501 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 502 | "dependencies": { 503 | "args": "^2.1.0", 504 | "io": "^1.0.0", 505 | "mason": "^0.0.1-dev.41", 506 | "meta": "^1.3.0", 507 | "path": "^1.8.0", 508 | "universal_io": "^2.0.4", 509 | "usage": "^4.0.2", 510 | "very_good_analysis": "^2.1.0", 511 | }, 512 | "dev_dependencies": { 513 | "build_runner": "^2.0.0", 514 | "build_verify": "^2.0.0", 515 | "build_version": "^2.0.0", 516 | "mocktail": "^0.1.1", 517 | "test": "^1.17.0", 518 | }, 519 | "executables": {"very_good": null}, 520 | }, 521 | "archive_url": 522 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.2.5.tar.gz", 523 | "published": "2021-07-16T04:12:40.244890Z", 524 | }, 525 | { 526 | "version": "0.3.0", 527 | "pubspec": { 528 | "name": "very_good_cli", 529 | "description": 530 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 531 | "version": "0.3.0", 532 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 533 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 534 | "dependencies": { 535 | "args": "^2.1.0", 536 | "io": "^1.0.0", 537 | "mason": "^0.0.1-dev.45", 538 | "meta": "^1.3.0", 539 | "path": "^1.8.0", 540 | "universal_io": "^2.0.4", 541 | "usage": "^4.0.2", 542 | "very_good_analysis": "^2.1.0", 543 | }, 544 | "dev_dependencies": { 545 | "build_runner": "^2.0.0", 546 | "build_verify": "^2.0.0", 547 | "build_version": "^2.0.0", 548 | "mocktail": "^0.1.1", 549 | "test": "^1.17.0", 550 | }, 551 | "executables": {"very_good": null}, 552 | }, 553 | "archive_url": 554 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.3.0.tar.gz", 555 | "published": "2021-07-23T18:32:11.491388Z", 556 | }, 557 | { 558 | "version": "0.3.1", 559 | "pubspec": { 560 | "name": "very_good_cli", 561 | "description": 562 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 563 | "version": "0.3.1", 564 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 565 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 566 | "dependencies": { 567 | "args": "^2.1.0", 568 | "io": "^1.0.0", 569 | "mason": "^0.0.1-dev.45", 570 | "meta": "^1.3.0", 571 | "path": "^1.8.0", 572 | "universal_io": "^2.0.4", 573 | "usage": "^4.0.2", 574 | "very_good_analysis": "^2.1.0", 575 | }, 576 | "dev_dependencies": { 577 | "build_runner": "^2.0.0", 578 | "build_verify": "^2.0.0", 579 | "build_version": "^2.0.0", 580 | "mocktail": "^0.1.1", 581 | "test": "^1.17.0", 582 | }, 583 | "executables": {"very_good": null}, 584 | }, 585 | "archive_url": 586 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.3.1.tar.gz", 587 | "published": "2021-07-27T22:24:21.642339Z", 588 | }, 589 | { 590 | "version": "0.3.2", 591 | "pubspec": { 592 | "name": "very_good_cli", 593 | "description": 594 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 595 | "version": "0.3.2", 596 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 597 | "environment": {"sdk": ">=2.12.0 <3.0.0"}, 598 | "dependencies": { 599 | "args": "^2.1.0", 600 | "io": "^1.0.0", 601 | "mason": "^0.0.1-dev.45", 602 | "meta": "^1.3.0", 603 | "path": "^1.8.0", 604 | "universal_io": "^2.0.4", 605 | "usage": "^4.0.2", 606 | "very_good_analysis": "^2.3.0", 607 | }, 608 | "dev_dependencies": { 609 | "build_runner": "^2.0.0", 610 | "build_verify": "^2.0.0", 611 | "build_version": "^2.0.0", 612 | "mocktail": "^0.1.1", 613 | "test": "^1.17.0", 614 | }, 615 | "executables": {"very_good": null}, 616 | }, 617 | "archive_url": 618 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.3.2.tar.gz", 619 | "published": "2021-08-03T19:15:48.395987Z", 620 | }, 621 | { 622 | "version": "0.3.3", 623 | "pubspec": { 624 | "name": "very_good_cli", 625 | "description": 626 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 627 | "version": "0.3.3", 628 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 629 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 630 | "dependencies": { 631 | "args": "^2.1.0", 632 | "io": "^1.0.0", 633 | "mason": "^0.0.1-dev.45", 634 | "meta": "^1.3.0", 635 | "path": "^1.8.0", 636 | "universal_io": "^2.0.4", 637 | "usage": "^4.0.2", 638 | "very_good_analysis": "^2.3.0", 639 | }, 640 | "dev_dependencies": { 641 | "build_runner": "^2.0.0", 642 | "build_verify": "^2.0.0", 643 | "build_version": "^2.0.0", 644 | "mocktail": "^0.1.1", 645 | "test": "^1.17.0", 646 | }, 647 | "executables": {"very_good": null}, 648 | }, 649 | "archive_url": 650 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.3.3.tar.gz", 651 | "published": "2021-08-18T15:55:12.372532Z", 652 | }, 653 | { 654 | "version": "0.4.0", 655 | "pubspec": { 656 | "name": "very_good_cli", 657 | "description": 658 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 659 | "version": "0.4.0", 660 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 661 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 662 | "dependencies": { 663 | "args": "^2.1.0", 664 | "io": "^1.0.0", 665 | "mason": "^0.0.1-dev.46", 666 | "meta": "^1.3.0", 667 | "path": "^1.8.0", 668 | "universal_io": "^2.0.4", 669 | "usage": "^4.0.2", 670 | "very_good_analysis": "^2.3.0", 671 | }, 672 | "dev_dependencies": { 673 | "build_runner": "^2.0.0", 674 | "build_verify": "^2.0.0", 675 | "build_version": "^2.0.0", 676 | "mocktail": "^0.1.1", 677 | "test": "^1.17.0", 678 | }, 679 | "executables": {"very_good": null}, 680 | }, 681 | "archive_url": 682 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.0.tar.gz", 683 | "published": "2021-08-20T20:00:26.652709Z", 684 | }, 685 | { 686 | "version": "0.4.1", 687 | "pubspec": { 688 | "name": "very_good_cli", 689 | "description": 690 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 691 | "version": "0.4.1", 692 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 693 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 694 | "dependencies": { 695 | "args": "^2.1.0", 696 | "io": "^1.0.0", 697 | "mason": "^0.0.1-dev.46", 698 | "meta": "^1.3.0", 699 | "path": "^1.8.0", 700 | "universal_io": "^2.0.4", 701 | "usage": "^4.0.2", 702 | "very_good_analysis": "^2.3.0", 703 | }, 704 | "dev_dependencies": { 705 | "build_runner": "^2.0.0", 706 | "build_verify": "^2.0.0", 707 | "build_version": "^2.0.0", 708 | "mocktail": "^0.1.1", 709 | "test": "^1.17.0", 710 | }, 711 | "executables": {"very_good": null}, 712 | }, 713 | "archive_url": 714 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.1.tar.gz", 715 | "published": "2021-08-23T19:31:41.015334Z", 716 | }, 717 | { 718 | "version": "0.4.2", 719 | "pubspec": { 720 | "name": "very_good_cli", 721 | "description": 722 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 723 | "version": "0.4.2", 724 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 725 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 726 | "dependencies": { 727 | "args": "^2.1.0", 728 | "io": "^1.0.0", 729 | "mason": "^0.0.1-dev.46", 730 | "meta": "^1.3.0", 731 | "path": "^1.8.0", 732 | "universal_io": "^2.0.4", 733 | "usage": "^4.0.2", 734 | "very_good_analysis": "^2.3.0", 735 | }, 736 | "dev_dependencies": { 737 | "build_runner": "^2.0.0", 738 | "build_verify": "^2.0.0", 739 | "build_version": "^2.0.0", 740 | "mocktail": "^0.1.1", 741 | "test": "^1.17.0", 742 | }, 743 | "executables": {"very_good": null}, 744 | }, 745 | "archive_url": 746 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.2.tar.gz", 747 | "published": "2021-09-01T18:37:57.115714Z", 748 | }, 749 | { 750 | "version": "0.4.3", 751 | "pubspec": { 752 | "name": "very_good_cli", 753 | "description": 754 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 755 | "version": "0.4.3", 756 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 757 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 758 | "dependencies": { 759 | "args": "^2.1.0", 760 | "io": "^1.0.0", 761 | "mason": "^0.0.1-dev.46", 762 | "meta": "^1.3.0", 763 | "path": "^1.8.0", 764 | "universal_io": "^2.0.4", 765 | "usage": "^4.0.2", 766 | "very_good_analysis": "^2.3.0", 767 | }, 768 | "dev_dependencies": { 769 | "build_runner": "^2.0.0", 770 | "build_verify": "^2.0.0", 771 | "build_version": "^2.0.0", 772 | "mocktail": "^0.1.1", 773 | "test": "^1.17.0", 774 | }, 775 | "executables": {"very_good": null}, 776 | }, 777 | "archive_url": 778 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.3.tar.gz", 779 | "published": "2021-09-17T18:33:25.908706Z", 780 | }, 781 | { 782 | "version": "0.4.4", 783 | "pubspec": { 784 | "name": "very_good_cli", 785 | "description": 786 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 787 | "version": "0.4.4", 788 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 789 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 790 | "dependencies": { 791 | "args": "^2.1.0", 792 | "io": "^1.0.0", 793 | "mason": "^0.0.1-dev.48", 794 | "meta": "^1.3.0", 795 | "path": "^1.8.0", 796 | "pub_updater": "^0.1.0", 797 | "universal_io": "^2.0.4", 798 | "usage": "^4.0.2", 799 | "very_good_analysis": "^2.3.0", 800 | }, 801 | "dev_dependencies": { 802 | "build_runner": "^2.0.0", 803 | "build_verify": "^2.0.0", 804 | "build_version": "^2.0.0", 805 | "mocktail": "^0.1.1", 806 | "test": "^1.17.0", 807 | }, 808 | "executables": {"very_good": null}, 809 | }, 810 | "archive_url": 811 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.4.tar.gz", 812 | "published": "2021-09-23T22:38:16.542740Z", 813 | }, 814 | { 815 | "version": "0.4.5", 816 | "pubspec": { 817 | "name": "very_good_cli", 818 | "description": 819 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 820 | "version": "0.4.5", 821 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 822 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 823 | "dependencies": { 824 | "args": "^2.1.0", 825 | "io": "^1.0.0", 826 | "mason": "^0.0.1-dev.51", 827 | "meta": "^1.3.0", 828 | "path": "^1.8.0", 829 | "pub_updater": "^0.1.0", 830 | "universal_io": "^2.0.4", 831 | "usage": "^4.0.2", 832 | "very_good_analysis": "^2.3.0", 833 | }, 834 | "dev_dependencies": { 835 | "build_runner": "^2.0.0", 836 | "build_verify": "^2.0.0", 837 | "build_version": "^2.0.0", 838 | "mocktail": "^0.1.1", 839 | "test": ">=1.17.0 <1.18.0", 840 | }, 841 | "executables": {"very_good": null}, 842 | }, 843 | "archive_url": 844 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.5.tar.gz", 845 | "published": "2021-09-30T21:13:51.007085Z", 846 | }, 847 | { 848 | "version": "0.4.6", 849 | "pubspec": { 850 | "name": "very_good_cli", 851 | "description": 852 | "A Very Good Command Line Interface for Dart created by Very Good Ventures.", 853 | "version": "0.4.6", 854 | "homepage": "https://github.com/VeryGoodOpenSource/very_good_cli", 855 | "environment": {"sdk": ">=2.13.0 <3.0.0"}, 856 | "dependencies": { 857 | "args": "^2.1.0", 858 | "io": "^1.0.0", 859 | "mason": "^0.0.1-dev.51", 860 | "meta": "^1.3.0", 861 | "path": "^1.8.0", 862 | "pub_updater": "^0.1.0", 863 | "universal_io": "^2.0.4", 864 | "usage": "^4.0.2", 865 | "very_good_analysis": "^2.3.0", 866 | }, 867 | "dev_dependencies": { 868 | "build_runner": "^2.0.0", 869 | "build_verify": "^2.0.0", 870 | "build_version": "^2.0.0", 871 | "mocktail": "^0.1.1", 872 | "test": ">=1.17.0 <1.18.0", 873 | }, 874 | "executables": {"very_good": null}, 875 | }, 876 | "archive_url": 877 | "https://pub.dartlang.org/packages/very_good_cli/versions/0.4.6.tar.gz", 878 | "published": "2021-10-07T21:23:42.789542Z", 879 | } 880 | ], 881 | }; 882 | -------------------------------------------------------------------------------- /test/pub_update_test.dart: -------------------------------------------------------------------------------- 1 | // Not required for test files 2 | // ignore_for_file: prefer_const_constructors 3 | import 'dart:io'; 4 | 5 | import 'package:http/http.dart' show Client, Response; 6 | import 'package:mocktail/mocktail.dart'; 7 | import 'package:process/process.dart'; 8 | import 'package:pub_updater/pub_updater.dart'; 9 | import 'package:test/test.dart'; 10 | 11 | import 'fixtures/fixtures.dart'; 12 | 13 | class MockClient extends Mock implements Client {} 14 | 15 | class MockResponse extends Mock implements Response {} 16 | 17 | class MockProcessManager extends Mock implements ProcessManager {} 18 | 19 | const emptyResponseBody = '{}'; 20 | 21 | const command = [ 22 | 'dart', 23 | 'pub', 24 | 'global', 25 | 'activate', 26 | 'very_good_cli', 27 | ]; 28 | const commandWithCustomBaseUrl = [ 29 | 'dart', 30 | 'pub', 31 | 'global', 32 | 'activate', 33 | 'very_good_cli', 34 | '--hosted-url', 35 | customBaseUrl, 36 | '--source', 37 | 'hosted', 38 | ]; 39 | const commandWithConstraint = [ 40 | 'dart', 41 | 'pub', 42 | 'global', 43 | 'activate', 44 | 'very_good_cli', 45 | '>=0.4.0', 46 | ]; 47 | const commandWithConstraintAndCustomBaseUrl = [ 48 | 'dart', 49 | 'pub', 50 | 'global', 51 | 'activate', 52 | 'very_good_cli', 53 | '>=0.4.0', 54 | '--hosted-url', 55 | customBaseUrl, 56 | '--source', 57 | 'hosted', 58 | ]; 59 | 60 | const customBaseUrl = 'https://custom-domain.com'; 61 | 62 | void main() { 63 | group('PubUpdater', () { 64 | late Client client; 65 | late Response response; 66 | late PubUpdater pubUpdater; 67 | late ProcessManager processManager; 68 | 69 | setUpAll(() { 70 | registerFallbackValue(Uri()); 71 | }); 72 | 73 | setUp(() { 74 | client = MockClient(); 75 | response = MockResponse(); 76 | pubUpdater = PubUpdater(client); 77 | processManager = MockProcessManager(); 78 | 79 | when(() => client.get(any())).thenAnswer((_) async => response); 80 | when(() => response.statusCode).thenReturn(HttpStatus.ok); 81 | when(() => response.body).thenReturn(validPackageInfoResponseBody); 82 | 83 | when(() => processManager.run(any())) 84 | .thenAnswer((_) => Future.value(ProcessResult(42, 0, '', ''))); 85 | }); 86 | 87 | test('can be instantiated without an explicit http client', () { 88 | expect(PubUpdater(), isNotNull); 89 | }); 90 | 91 | test('can be instantiated with a custom base url', () { 92 | expect(PubUpdater(null, customBaseUrl), isNotNull); 93 | }); 94 | 95 | group('isUpToDate', () { 96 | test('makes correct http request', () async { 97 | when(() => response.body).thenReturn(emptyResponseBody); 98 | 99 | try { 100 | await pubUpdater.isUpToDate( 101 | packageName: 'very_good_cli', 102 | currentVersion: '0.3.3', 103 | ); 104 | } on Exception catch (_) {} 105 | 106 | verify( 107 | () => client.get( 108 | Uri.https( 109 | 'pub.dev', 110 | '/api/packages/very_good_cli', 111 | ), 112 | ), 113 | ).called(1); 114 | }); 115 | 116 | test('makes correct http request with a custom base url', () async { 117 | when(() => response.body).thenReturn(emptyResponseBody); 118 | pubUpdater = PubUpdater(client, customBaseUrl); 119 | 120 | try { 121 | await pubUpdater.isUpToDate( 122 | packageName: 'very_good_cli', 123 | currentVersion: '0.3.3', 124 | ); 125 | } on Exception catch (_) {} 126 | 127 | verify( 128 | () => client.get( 129 | Uri.parse('$customBaseUrl/api/packages/very_good_cli'), 130 | ), 131 | ).called(1); 132 | }); 133 | 134 | test('returns false when currentVersion < latestVersion', () async { 135 | expect( 136 | await pubUpdater.isUpToDate( 137 | packageName: 'very_good_cli', 138 | currentVersion: '3.0.0', 139 | ), 140 | false, 141 | ); 142 | }); 143 | 144 | test('returns true when currentVersion == latestVersion', () async { 145 | expect( 146 | await pubUpdater.isUpToDate( 147 | packageName: 'very_good_cli', 148 | currentVersion: '0.4.6', 149 | ), 150 | true, 151 | ); 152 | }); 153 | 154 | test( 155 | '''returns true when currentVersion is pre release and latestVersion is stable''', 156 | () async { 157 | expect( 158 | await pubUpdater.isUpToDate( 159 | packageName: 'very_good_cli', 160 | currentVersion: '0.4.0-dev.1', 161 | ), 162 | true, 163 | ); 164 | }, 165 | ); 166 | 167 | group('pre releases', () { 168 | setUp(() { 169 | client = MockClient(); 170 | response = MockResponse(); 171 | pubUpdater = PubUpdater(client); 172 | processManager = MockProcessManager(); 173 | 174 | when(() => client.get(any())).thenAnswer((_) async => response); 175 | when(() => response.statusCode).thenReturn(HttpStatus.ok); 176 | when(() => response.body) 177 | .thenReturn(preReleasePackageInfoResponseBody); 178 | 179 | when(() => processManager.run(any())) 180 | .thenAnswer((_) => Future.value(ProcessResult(42, 0, '', ''))); 181 | }); 182 | 183 | test('returns false when currentVersion < latestVersion', () async { 184 | expect( 185 | await pubUpdater.isUpToDate( 186 | packageName: 'mason', 187 | currentVersion: '0.1.0-dev.47', 188 | ), 189 | false, 190 | ); 191 | }); 192 | 193 | test('returns true when currentVersion == latestVersion', () async { 194 | expect( 195 | await pubUpdater.isUpToDate( 196 | packageName: 'mason', 197 | currentVersion: '0.1.0-dev.48', 198 | ), 199 | true, 200 | ); 201 | }); 202 | }); 203 | 204 | test('throws PackageInfoRequestFailure on non-200 response', () async { 205 | when(() => response.statusCode).thenReturn(HttpStatus.notFound); 206 | await expectLater( 207 | pubUpdater.isUpToDate( 208 | packageName: 'very_good_cli', 209 | currentVersion: '3.0.0', 210 | ), 211 | throwsA(isA()), 212 | ); 213 | }); 214 | 215 | test('throws PackageInfoNotFoundFailure when response body is empty', 216 | () async { 217 | when(() => response.body).thenReturn(emptyResponseBody); 218 | await expectLater( 219 | pubUpdater.isUpToDate( 220 | packageName: 'very_good_cli', 221 | currentVersion: '3.0.0', 222 | ), 223 | throwsA(isA()), 224 | ); 225 | }); 226 | }); 227 | 228 | group('getLatestVersion', () { 229 | test('makes correct http request', () async { 230 | when(() => response.body).thenReturn(emptyResponseBody); 231 | 232 | try { 233 | await pubUpdater.getLatestVersion('very_good_cli'); 234 | } on Exception catch (_) {} 235 | 236 | verify( 237 | () => client.get( 238 | Uri.https( 239 | 'pub.dev', 240 | '/api/packages/very_good_cli', 241 | ), 242 | ), 243 | ).called(1); 244 | }); 245 | 246 | test('makes correct http request with a custom base url', () async { 247 | when(() => response.body).thenReturn(emptyResponseBody); 248 | pubUpdater = PubUpdater(client, customBaseUrl); 249 | 250 | try { 251 | await pubUpdater.getLatestVersion('very_good_cli'); 252 | } on Exception catch (_) {} 253 | 254 | verify( 255 | () => client.get( 256 | Uri.parse('$customBaseUrl/api/packages/very_good_cli'), 257 | ), 258 | ).called(1); 259 | }); 260 | 261 | test('returns correct version', () async { 262 | when(() => response.body).thenReturn(validPackageInfoResponseBody); 263 | expect( 264 | await pubUpdater.getLatestVersion('very_good_cli'), 265 | equals('0.4.6'), 266 | ); 267 | }); 268 | 269 | test('throws PackageInfoRequestFailure on non-200 response', () async { 270 | when(() => response.statusCode).thenReturn(HttpStatus.notFound); 271 | await expectLater( 272 | pubUpdater.getLatestVersion('very_good_cli'), 273 | throwsA(isA()), 274 | ); 275 | }); 276 | 277 | test('throws PackageInfoNotFoundFailure when response body is empty', 278 | () async { 279 | when(() => response.body).thenReturn(emptyResponseBody); 280 | await expectLater( 281 | pubUpdater.getLatestVersion('very_good_cli'), 282 | throwsA(isA()), 283 | ); 284 | }); 285 | }); 286 | 287 | group('update', () { 288 | test('makes correct call to process.run', () async { 289 | await pubUpdater.update( 290 | packageName: 'very_good_cli', 291 | processManager: processManager, 292 | ); 293 | verify(() => processManager.run(command)).called(1); 294 | }); 295 | test('makes correct call to process.run with customBaseUrl', () async { 296 | pubUpdater = PubUpdater(client, customBaseUrl); 297 | await pubUpdater.update( 298 | packageName: 'very_good_cli', 299 | processManager: processManager, 300 | ); 301 | verify(() => processManager.run(commandWithCustomBaseUrl)).called(1); 302 | }); 303 | 304 | test('makes correct call to process.run with version constraint', 305 | () async { 306 | await pubUpdater.update( 307 | packageName: 'very_good_cli', 308 | processManager: processManager, 309 | versionConstraint: '>=0.4.0', 310 | ); 311 | verify(() => processManager.run(commandWithConstraint)).called(1); 312 | }); 313 | 314 | test('makes correct call to process.run with version constraint', 315 | () async { 316 | pubUpdater = PubUpdater(client, customBaseUrl); 317 | await pubUpdater.update( 318 | packageName: 'very_good_cli', 319 | processManager: processManager, 320 | versionConstraint: '>=0.4.0', 321 | ); 322 | verify(() => processManager.run(commandWithConstraintAndCustomBaseUrl)) 323 | .called(1); 324 | }); 325 | }); 326 | }); 327 | } 328 | -------------------------------------------------------------------------------- /test/src/models/package_info_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:pub_updater/src/models/models.dart'; 2 | import 'package:test/test.dart'; 3 | 4 | void main() { 5 | group('LatestVersionConverter', () { 6 | test('to/from json works', () { 7 | const converter = LatestVersionConverter(); 8 | final latestVersion = {'version': '1.0.0'}; 9 | expect( 10 | converter.toJson(converter.fromJson(latestVersion)), 11 | equals(latestVersion), 12 | ); 13 | }); 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /tool/release_ready.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Ensures that the package is ready for a release. 4 | # 5 | # Will update the version.dart file and update the CHANGELOG.md. 6 | # 7 | # Set it up for a new version: 8 | # `sh tool/release_ready.sh ` 9 | 10 | # Check if current directory is usable for this script, if so we assume it is correctly set up. 11 | if [ ! -f "pubspec.yaml" ]; then 12 | echo "$(pwd) is not a valid Dart package." 13 | exit 1 14 | fi 15 | 16 | currentBranch=$(git symbolic-ref --short -q HEAD) 17 | if [[ ! $currentBranch == "main" ]]; then 18 | echo "Releasing is only supported on the main branch." 19 | exit 1 20 | fi 21 | 22 | # Get information 23 | old_version="" 24 | if [ -f "pubspec.yaml" ]; then 25 | old_version=$(dart pub deps --json | pcregrep -o1 -i '"version": "(.*?)"' | head -1) 26 | fi 27 | 28 | if [ -z "$old_version" ]; then 29 | echo "Current version was not resolved." 30 | exit 1 31 | fi 32 | 33 | # Get new version 34 | new_version="$1"; 35 | 36 | if [[ "$new_version" == "" ]]; then 37 | echo "No new version supplied, please provide one" 38 | exit 1 39 | fi 40 | 41 | if [[ "$new_version" == "$old_version" ]]; then 42 | echo "Current version is $old_version, can't update." 43 | exit 1 44 | fi 45 | 46 | # Retrieving all the commits in the current directory since the last tag. 47 | previousTag="v${old_version}" 48 | raw_commits="$(git log --pretty=format:"%s" --no-merges --reverse $previousTag..HEAD -- .)" 49 | markdown_commits=$(echo "$raw_commits" | sed -En "s/\(#([0-9]+)\)/([#\1](https:\/\/github.com\/VeryGoodOpenSource\/pub_updater\/pull\/\1))/p") 50 | 51 | if [[ "$markdown_commits" == "" ]]; then 52 | echo "No commits since last tag, can't update." 53 | exit 0 54 | fi 55 | commits=$(echo "$markdown_commits" | sed -En "s/^/- /p") 56 | 57 | echo "Updating version to $new_version" 58 | if [ -f "pubspec.yaml" ]; then 59 | sed -i '' "s/version: $old_version/version: $new_version/g" pubspec.yaml 60 | fi 61 | 62 | # Update dart file with new version. 63 | dart run build_runner build --delete-conflicting-outputs > /dev/null 64 | 65 | if grep -q v$new_version "CHANGELOG.md"; then 66 | echo "CHANGELOG already contains version $new_version." 67 | exit 1 68 | fi 69 | 70 | # Add a new version entry with the found commits to the CHANGELOG.md. 71 | echo "# ${new_version} \n\n ${commits}\n\n$(cat CHANGELOG.md)" > CHANGELOG.md 72 | echo "CHANGELOG generated, validate entries here: $(pwd)/CHANGELOG.md" 73 | 74 | echo "Creating git branch for pub_updater@$new_version" 75 | git checkout -b "chore/$new_version" > /dev/null 76 | 77 | git add pubspec.yaml CHANGELOG.md 78 | if [ -f lib/src/version.dart ]; then 79 | git add lib/src/version.dart 80 | fi 81 | 82 | echo "" 83 | echo "Run the following command if you wish to commit the changes:" 84 | echo "git commit -m \"chore: v$new_version\"" --------------------------------------------------------------------------------