René's URL Explorer Experiment


Title: Add Tool.default_command() to eliminate duplication in CI steps and help messages by Copilot · Pull Request #1088 · usethis-python/usethis-python · GitHub

Open Graph Title: Add Tool.default_command() to eliminate duplication in CI steps and help messages by Copilot · Pull Request #1088 · usethis-python/usethis-python

X Title: Add Tool.default_command() to eliminate duplication in CI steps and help messages by Copilot · Pull Request #1088 · usethis-python/usethis-python

Description: The get_bitbucket_steps() methods across tool implementations contained significant duplication, repeating the same command strings used in help messages. This PR introduces Tool.default_command() to define commands once and enables a default get_bitbucket_steps() implementation. Changes Core Protocol Method Added default_command() -> str to Tool protocol that returns backend-dependent command strings Returns "uv run [args]" when uv backend is active with uv.lock present Returns " [args]" for none backend or uv without lock file Raises NoDefaultToolCommand exception by default for tools without commands (instead of returning None) Custom Exception Added NoDefaultToolCommand exception in src/usethis/errors.py for tools that don't have associated commands Base get_bitbucket_steps() implementation uses try-except to handle tools without commands Default Implementation Added default get_bitbucket_steps() implementation in base Tool class that uses default_command() Automatically generates appropriate Bitbucket pipeline steps with correct caching and anchors Can be overridden for complex cases (e.g., pytest with multiple Python versions, Ruff with separate linter/formatter) Tool Updates Implemented default_command() in 5 tools: CodespellTool: "codespell" PyprojectFmtTool: "pyproject-fmt pyproject.toml" DeptryTool: "deptry {src_dir}" (dynamic) ImportLinterTool: "lint-imports" PytestTool: "pytest" Note: RuffTool was intentionally excluded as it doesn't have a single default command (has separate linter and formatter commands). Refactored print_how_to_use() methods to use default_command() instead of duplicating command strings. Code Reduction Removed ~160 lines of duplicated get_bitbucket_steps() implementations from simple tools (CodespellTool, PyprojectFmtTool, DeptryTool, ImportLinterTool) that now inherit the default implementation. Example Before: def print_how_to_use(self): if backend is BackendEnum.uv and is_uv_used(): how_print("Run 'uv run codespell' to run the Codespell spellchecker.") else: how_print("Run 'codespell' to run the Codespell spellchecker.") def get_bitbucket_steps(self): if backend is BackendEnum.uv: return [BitbucketStep(script=["uv run codespell"])] # ... duplicated command logic After: def default_command(self) -> str: backend = get_backend() if backend is BackendEnum.uv and is_uv_used(): return "uv run codespell" return "codespell" def print_how_to_use(self): cmd = self.default_command() how_print(f"Run '{cmd}' to run the Codespell spellchecker.") # get_bitbucket_steps() now inherited from base class Fixes #1077 Original prompt This section details on the original issue you should resolve Create a Tool.default_command method To avoid duplication between (and within) get_bitbucket_steps methods for CI, and probably help messages, etc. This would be backend dependent. By default, it should return None, since not all tools have commands. Otherwise, return a string. The individual tool implementations (Tool subclassses), for tools which associated with commands, should provide an implementation. We should use the method anywhere where the default command is used, e.g. help messages, but certainly get_bitbucket_steps methods. Comments on the Issue (you are @copilot in this section) @nathanjmcdougall This will also enable default implementations for `get_bitbucket_steps` methods Fixes #1077 ✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Open Graph Description: The get_bitbucket_steps() methods across tool implementations contained significant duplication, repeating the same command strings used in help messages. This PR introduces Tool.default_command() ...

X Description: The get_bitbucket_steps() methods across tool implementations contained significant duplication, repeating the same command strings used in help messages. This PR introduces Tool.default_command() ...

Opengraph URL: https://github.com/usethis-python/usethis-python/pull/1088

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:c6ebf7f5-e08d-51f6-be5e-e40aa0b19037
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-idC38C:3F3E75:4C3A4:66F77:6A4D78FF
html-safe-nonce5cef7817e2ff10ea19201c2e066f544093a1284fadfceebd33fd09153ac21391
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDMzhDOjNGM0U3NTo0QzNBNDo2NkY3Nzo2QTRENzhGRiIsInZpc2l0b3JfaWQiOiI4MzIyNDUxMjUwNDI4NjA2NzE5IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0=
visitor-hmac054853867133c07f95e0336001d1d268bb39a9af5d2508cc48db63d19ce0da27
hovercard-subject-tagpull_request:2979859840
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/usethis-python/usethis-python/pull/1088/files
twitter:imagehttps://avatars.githubusercontent.com/in/1143301?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/in/1143301?s=400&v=4
og:image:altThe get_bitbucket_steps() methods across tool implementations contained significant duplication, repeating the same command strings used in help messages. This PR introduces Tool.default_command() ...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
None7f8e15305e2ab58890ca84b830615e375f5df303cf471cafcba0c08272981be3
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/usethis-python/usethis-python git https://github.com/usethis-python/usethis-python.git
octolytics-dimension-user_id216362695
octolytics-dimension-user_loginusethis-python
octolytics-dimension-repository_id842189705
octolytics-dimension-repository_nwousethis-python/usethis-python
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id842189705
octolytics-dimension-repository_network_root_nwousethis-python/usethis-python
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release8608b0750fc35e283e5ec5b094bff942d7a0e197
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/usethis-python/usethis-python/pull/1088/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fusethis-python%2Fusethis-python%2Fpull%2F1088%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fusethis-python%2Fusethis-python%2Fpull%2F1088%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=usethis-python%2Fusethis-python
Reloadhttps://github.com/usethis-python/usethis-python/pull/1088/files
Reloadhttps://github.com/usethis-python/usethis-python/pull/1088/files
Reloadhttps://github.com/usethis-python/usethis-python/pull/1088/files
Please reload this pagehttps://github.com/usethis-python/usethis-python/pull/1088/files
usethis-python https://github.com/usethis-python
usethis-pythonhttps://github.com/usethis-python/usethis-python
Notifications https://github.com/login?return_to=%2Fusethis-python%2Fusethis-python
Fork 5 https://github.com/login?return_to=%2Fusethis-python%2Fusethis-python
Star 19 https://github.com/login?return_to=%2Fusethis-python%2Fusethis-python
Code https://github.com/usethis-python/usethis-python
Issues 163 https://github.com/usethis-python/usethis-python/issues
Pull requests 4 https://github.com/usethis-python/usethis-python/pulls
Actions https://github.com/usethis-python/usethis-python/actions
Security and quality 0 https://github.com/usethis-python/usethis-python/security
Insights https://github.com/usethis-python/usethis-python/pulse
Code https://github.com/usethis-python/usethis-python
Issues https://github.com/usethis-python/usethis-python/issues
Pull requests https://github.com/usethis-python/usethis-python/pulls
Actions https://github.com/usethis-python/usethis-python/actions
Security and quality https://github.com/usethis-python/usethis-python/security
Insights https://github.com/usethis-python/usethis-python/pulse
Sign up for GitHub https://github.com/signup?return_to=%2Fusethis-python%2Fusethis-python%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2Fusethis-python%2Fusethis-python%2Fissues%2Fnew%2Fchoose
nathanjmcdougallhttps://github.com/nathanjmcdougall
mainhttps://github.com/usethis-python/usethis-python/tree/main
copilot/create-tool-default-command-methodhttps://github.com/usethis-python/usethis-python/tree/copilot/create-tool-default-command-method
Conversation 8 https://github.com/usethis-python/usethis-python/pull/1088
Commits 8 https://github.com/usethis-python/usethis-python/pull/1088/commits
Checks 20 https://github.com/usethis-python/usethis-python/pull/1088/checks
Files changed https://github.com/usethis-python/usethis-python/pull/1088/files
Please reload this pagehttps://github.com/usethis-python/usethis-python/pull/1088/files
Add Tool.default_command() to eliminate duplication in CI steps and help messages https://github.com/usethis-python/usethis-python/pull/1088/files#top
Show all changes 8 commits https://github.com/usethis-python/usethis-python/pull/1088/files
806bf24 Initial plan Copilot Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/806bf247249e17b56236f9399f14aa41783d5e19
8e3a83e Add default_command method to Tool protocol and implement in tool sub… Copilot Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/8e3a83eea24544b2a94a517a8766ff8697026fb0
915adb4 Add tests for default_command method Copilot Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/915adb425f525680651bf8ce7b4a0c90f50a6d07
4a43658 Add default get_bitbucket_steps implementation using default_command Copilot Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/4a43658829033abed1e98ffb01f271fb70456056
ba484ae Change default_command to raise NoDefaultToolCommand instead of retur… Copilot Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/ba484ae32517593f57e578354a77c7d9fe989828
c6a5f82 Run formatter nathanjmcdougall Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/c6a5f828435e1b1c25a6597a757a27c6501f6316
1b5cb3d Merge branch 'main' into copilot/create-tool-default-command-method nathanjmcdougall Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/1b5cb3dd88c7adf69db1561e2bb106a4e0e6fa01
ee1c148 Comply with import layout rules nathanjmcdougall Nov 5, 2025 https://github.com/usethis-python/usethis-python/pull/1088/commits/ee1c1489de73c2cc5e1ec4dde1573d7755b14ba2
Clear filters https://github.com/usethis-python/usethis-python/pull/1088/files
Please reload this pagehttps://github.com/usethis-python/usethis-python/pull/1088/files
Please reload this pagehttps://github.com/usethis-python/usethis-python/pull/1088/files
base.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
codespell.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
deptry.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
import_linter.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
pyproject_fmt.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-9d1669a8085dbc449b13766d39205b2a8c08549be9454c2e633ca67f25cba154
pytest.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-106585e3a4943ee7a16be8239ff48b99ed16380491cb2c4b4c19e40c59e837bd
errors.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-b065b4d6c05e2599b7ae1caf37104a728bc4e18fddd9c21ea4302ab6e6c760aa
test_codespell.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-e48bcb97bb38374dd946bc3cfaf7876d75d9422e353e49cb0a0f8f683155b735
test_pytest.py https://github.com/usethis-python/usethis-python/pull/1088/files#diff-8d10513eecca04fb6838fe0877688207406880583f2c2496159c5863db5dab8e
src/usethis/_tool/base.pyhttps://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
View file https://github.com/usethis-python/usethis-python/blob/ee1c1489de73c2cc5e1ec4dde1573d7755b14ba2/src/usethis/_tool/base.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/usethis-python/usethis-python/pull/1088/{{ revealButtonHref }}
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-5d6bc423e5b313d5aeba5e063fcde573c808a3df7738ed68bb94d82b92a005d7
src/usethis/_tool/impl/codespell.pyhttps://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
View file https://github.com/usethis-python/usethis-python/blob/ee1c1489de73c2cc5e1ec4dde1573d7755b14ba2/src/usethis/_tool/impl/codespell.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/usethis-python/usethis-python/pull/1088/{{ revealButtonHref }}
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-df0e40aa268796973e7191cefd7a52ce1e6f6bf0db388c0dc8c05adcb7915404
src/usethis/_tool/impl/deptry.pyhttps://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
View file https://github.com/usethis-python/usethis-python/blob/ee1c1489de73c2cc5e1ec4dde1573d7755b14ba2/src/usethis/_tool/impl/deptry.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/usethis-python/usethis-python/pull/1088/{{ revealButtonHref }}
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-39f4517248dc16dbdb3d408d2e6ac9abb203439f413502f712bc27f81cef9330
src/usethis/_tool/impl/import_linter.pyhttps://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
View file https://github.com/usethis-python/usethis-python/blob/ee1c1489de73c2cc5e1ec4dde1573d7755b14ba2/src/usethis/_tool/impl/import_linter.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/usethis-python/usethis-python/pull/1088/{{ revealButtonHref }}
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
https://github.com/usethis-python/usethis-python/pull/1088/files#diff-c780da7264554200cd02554371d271f75f184f1af7937b61e51ad37ad7e41764
Please reload this pagehttps://github.com/usethis-python/usethis-python/pull/1088/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.