Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(W-17237970): Improve buildpacks:index for fir apps #3227

Merged
merged 8 commits into from
Feb 19, 2025
15 changes: 12 additions & 3 deletions packages/cli/src/commands/buildpacks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {BuildpackCommand} from '../../lib/buildpacks/buildpacks'
import {getGeneration} from '../../lib/apps/generation'

export default class Index extends Command {
static description = 'display the buildpacks for an app'
static description = 'list the buildpacks on an app'

static flags = {
app: Flags.app({required: true}),
Expand All @@ -22,11 +22,20 @@ export default class Index extends Command {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
})
const buildpacks = await buildpacksCommand.fetch(flags.app, getGeneration(app) === 'fir')
const isFirApp = getGeneration(app) === 'fir'
const buildpacks = await buildpacksCommand.fetch(flags.app, isFirApp)
if (buildpacks.length === 0) {
this.log(`${color.app(flags.app)} has no Buildpacks.`)
} else {
ux.styledHeader(`${color.app(flags.app)} Buildpack${buildpacks.length > 1 ? 's' : ''}`)
const pluralizedBuildpacks = buildpacks.length > 1 ? 'Buildpacks' : 'Buildpack'
let header = `${color.app(flags.app)}`
if (isFirApp) {
header += ` Cloud Native ${pluralizedBuildpacks} (from the latest release's OCI image)`
} else {
header += ` Classic ${pluralizedBuildpacks} (from the Heroku Buildpack Registry)`
}

ux.styledHeader(header)
buildpacksCommand.display(buildpacks, '')
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/test/acceptance/commands-output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ authorizations:revoke revoke OAuth authorization
authorizations:rotate updates an OAuth authorization token
authorizations:update updates an OAuth authorization
autocomplete display autocomplete installation instructions
buildpacks display the buildpacks for an app
buildpacks list the buildpacks on an app
buildpacks:add add new app buildpack, inserting into list of buildpacks if necessary
buildpacks:clear clear all buildpacks set on the app
buildpacks:info fetch info about a buildpack
Expand Down
77 changes: 63 additions & 14 deletions packages/cli/test/unit/commands/buildpacks/index.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ describe('buildpacks', function () {
.it('# displays the buildpack URL', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${cedarApp.name} Buildpack
=== ⬢ ${cedarApp.name} Classic Buildpack (from the Heroku Buildpack Registry)

https://github.com/heroku/heroku-buildpack-ruby
`))
Expand All @@ -148,7 +148,7 @@ describe('buildpacks', function () {
.it('# maps buildpack urns to names', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${cedarApp.name} Buildpack
=== ⬢ ${cedarApp.name} Classic Buildpack (from the Heroku Buildpack Registry)

heroku/ruby
`))
Expand All @@ -165,7 +165,7 @@ describe('buildpacks', function () {
.it('# does not map buildpack s3 to names', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${cedarApp.name} Buildpack
=== ⬢ ${cedarApp.name} Classic Buildpack (from the Heroku Buildpack Registry)

https://codon-buildpacks.s3.amazonaws.com/buildpacks/heroku/ruby.tgz
`))
Expand Down Expand Up @@ -200,7 +200,7 @@ describe('buildpacks', function () {
.it('# with two buildpack URLs set displays the buildpack URL', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${cedarApp.name} Buildpacks
=== ⬢ ${cedarApp.name} Classic Buildpacks (from the Heroku Buildpack Registry)

1. https://github.com/heroku/heroku-buildpack-java
2. https://github.com/heroku/heroku-buildpack-ruby
Expand All @@ -221,13 +221,30 @@ describe('buildpacks', function () {
.it('# returns the buildpack registry name back', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${cedarApp.name} Buildpacks
=== ⬢ ${cedarApp.name} Classic Buildpacks (from the Heroku Buildpack Registry)

1. heroku/java
2. rust-lang/rust
`))
})

test
.nock('https://api.heroku.com', (api: nock.Scope) => {
api.get(`/apps/${cedarApp.name}`).reply(200, cedarApp)
Stubber.get(api, ['https://github.com/heroku/heroku-buildpack-ruby'])
})
.stdout()
.stderr()
.command(['buildpacks', '-a', cedarApp.name])
.it('# displays the buildpack URL with classic buildpack source', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${cedarApp.name} Classic Buildpack (from the Heroku Buildpack Registry)

https://github.com/heroku/heroku-buildpack-ruby
`))
})

test
.nock('https://api.heroku.com', {
reqheaders: {accept: 'application/vnd.heroku+json; version=3.sdk'},
Expand All @@ -238,14 +255,48 @@ describe('buildpacks', function () {
})
.stdout()
.stderr()
.command(['buildpacks', '-a', firApp.name])
.it('# returns cnb buildpack ids for fir apps with OCI source', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${firApp.name} Cloud Native Buildpack (from the latest release's OCI image)

heroku/ruby
`))
})

test
.nock('https://api.heroku.com', (api: nock.Scope) => {
api.get(`/apps/${cedarApp.name}`).reply(200, cedarApp)
Stubber.get(api, [
'https://github.com/heroku/heroku-buildpack-java',
'https://github.com/heroku/heroku-buildpack-ruby',
])
})
.stdout()
.stderr()
.command(['buildpacks', '-a', cedarApp.name])
.it('# returns cnb buildpack ids for fir apps', ctx => {
.it('# with multiple buildpack URLs shows plural form and source', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
=== ⬢ ${firApp.name} Buildpack
=== ⬢ ${cedarApp.name} Classic Buildpacks (from the Heroku Buildpack Registry)

heroku/ruby
`))
1. https://github.com/heroku/heroku-buildpack-java
2. https://github.com/heroku/heroku-buildpack-ruby
`))
})

test
.nock('https://api.heroku.com', (api: nock.Scope) => {
api.get(`/apps/${cedarApp.name}`).reply(200, cedarApp)
Stubber.get(api)
})
.stdout()
.stderr()
.command(['buildpacks', '-a', cedarApp.name])
.it('# with no buildpack URL set shows appropriate message', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(`⬢ ${cedarApp.name} has no Buildpacks.\n`)
})

test
Expand All @@ -257,11 +308,9 @@ describe('buildpacks', function () {
})
.stdout()
.stderr()
.command(['buildpacks', '-a', cedarApp.name])
.it('# returns nothing when no releases', ctx => {
.command(['buildpacks', '-a', firApp.name])
.it('# returns nothing when no releases for fir app', ctx => {
expect(ctx.stderr).to.equal('')
expect(ctx.stdout).to.equal(heredoc(`
⬢ ${cedarApp.name} has no Buildpacks.
`))
expect(ctx.stdout).to.equal(`⬢ ${firApp.name} has no Buildpacks.\n`)
})
})
Loading