Scan a Github organization for usage of a package.
Package Probe can help you answer questions such as "Which repositories in my organization are using React?" or "Which version of internal dependency X are my organization's projects using?"
$ npm install -g package-probe
Package Probe uses the Github API to scan for a package. If you want to search in a private Github organization, you'll need to create a Github Personal Access Token that has access to your organization and set it as an environment variable when running package-probe
.
If you are scanning public organizations/owners, you can skip this step.
- Generate a Github Personal access token in your Github profile developer settings
- Grant the
repo
scope to the token (Package Probe reads information and does not store any of your data) - Add it to your environment as
GITHUB_TOKEN
orGH_TOKEN
. (e.g.export GITHUB_TOKEN=<your token>
)
$ package-probe --help
Usage: package-probe [options]
Options:
--json output results as json (default output is a table)
--owner <owner> Github owner/organization to scan (required)
--partial-matches return results for partial matches of the search term
--search-term <searchTerm> search term (required)
-V, --version output the version number
-h, --help output usage information
Package probe will automatically use a Github Personal Access Token defined in the GITHUB_TOKEN
or GH_TOKEN
environment variable.
While the CLI provides quick use, you have more control through the advanced options available in the JavaScript interface.
probe(options)
type Options = {
// Github Personal Access Token. Only necessary if scanning a private organization/owner.
accessToken?: string
// Function that adds fields to return along with the repository name and matched version
appendFieldsToOutput: AppendFieldsToOutputFunction
// Don't return results that match ANY of the provided filter functions
exclude?: RepoFilterFunction[]
// Only return results that match ALL the provided filter functions
include?: RepoFilterFunction[]
// The Github owner or organization to search in
owner: string
// **Required**. If true, will match packages that partially match the provided search term. Otherwise, only exact matches will be returned. This option can be used to search for multiple packages that follow a naming schema.
partialMatches?: boolean
// **Required**. The package name to search for. Must be the full name of the package, including the owner, unless you use the `partialMatches` option.
searchTerm: string
}
// See Github REST API documentation (https://developer.github.com/v3/repos/#get) for available fields
type RepoFilterFunction = (githubRepo: Octokit.ReposGetResponse) => boolean
// See Github REST API documentation (https://developer.github.com/v3/repos/#get) for available fields
type AppendFieldsToOutputFunction = (githubRepo: Octokit.ReposGetResponse) => {
[fieldName: string]: any
}
import probe from 'package-probe'
const accessToken = process.env.GITHUB_TOKEN
const results = await probe({
accessToken,
owner: 'my-company',
searchTerm: '@my-company/my-package',
})
console.log(results)
const isArchived = (githubRepo: Octokit.ReposGetResponse) => githubRepo.archived
const results = await probe({
accessToken: '...',
owner: 'my-company',
searchTerm: '@my-company/my-package',
exclude: [isArchived],
})
const appendFieldsToOutput = (githubRepo: Octokit.ReposGetResponse) => ({
description: githubRepo.description,
lastCommit: new Date(githubRepo.pushed_at).toLocaleDateString(),
})
const results = await probe({
accessToken: '...',
owner: 'my-company',
searchTerm: '@my-company/my-package',
appendFieldsToOutput,
})
Searching my Github repositories for usage of React.
$ package-probe --search-term react --owner ryanoglesby08
π°οΈ Scanning...
β¨ Found 15 matches!
ββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββ
β Repository name β Package/app name β Version β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β the-eod-machine β @the-eod-machine/ui β ^16.4.1 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β movie-night β movie-night β ^16.7.0-alpha.2 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β email-autocomplete β email-autocomplete β ^16.5.2 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β exposing-css-hidden-complexities β exposing-css-hidden-complexities β ^16.1.1 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β splitit β splitit β ^15.3.2 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β react-dashboard β react-bare-app β ^15.5.4 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β react-quizzer β react-quizzer β ^15.1.0 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β ssr-media-queries β ssr-media-queries β ^16.2.0 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β javascript-workshop β react-workshop-webpack β ^15.4.1 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β react-bare-app β react-bare-app β ^15.5.4 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β javascript-workshop β react-workshop-real-server β ^15.4.1 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β javascript-workshop β react-workshop-real-server β ^15.4.1 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β the-eod-machine β @the-eod-machine/emailer β ^16.4.2 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β javascript-workshop β react-workshop-real-server β ^15.4.1 β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββΌββββββββββββββββββ€
β css-playground β js-hide-instead-of-by-class β ^15.4.2 β
ββββββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββ