Skip to content

Commit

Permalink
chore(W-17237970): Improve buildpacks:index for fir apps
Browse files Browse the repository at this point in the history
  • Loading branch information
justinwilaby committed Feb 19, 2025
1 parent 01c9b33 commit 5e2dc7c
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 19 deletions.
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. For Fir apps, buildpacks are retrieved from the latest release\'s OCI image data. For Cedar apps, buildpacks are retrieved from the classic buildpack registry.'

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 latest release OCI image)`
} else {
header += ` Classic ${pluralizedBuildpacks} (from buildpack registry)`
}

ux.styledHeader(header)
buildpacksCommand.display(buildpacks, '')
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default class Logs extends Command {
tail: flags.boolean({
char: 't',
default: false,
description: 'continually stream logs (defaults to true for Fir generation apps)',
description: 'continually stream logs (always enabled for Fir-generation apps)',
}),
'process-type': flags.string({
char: 'p',
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. For Fir apps, buildpacks are retrieved from the latest release's OCI image data. For Cedar apps, buildpacks are retrieved from the classic buildpack registry.
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 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 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 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 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 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 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 latest release 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 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`)
})
})

0 comments on commit 5e2dc7c

Please sign in to comment.