Skip to content

Commit 62736f7

Browse files
committed
bufo print action
1 parent 80883ea commit 62736f7

8 files changed

Lines changed: 225 additions & 5 deletions

File tree

.vscode/launch.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
8+
{
9+
"name": "Launch Package",
10+
"type": "go",
11+
"request": "launch",
12+
"mode": "auto",
13+
"program": "${workspaceFolder}",
14+
"args": ["-debug"]
15+
}
16+
]
17+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
terraform {
2+
required_providers {
3+
bufo = {
4+
source = "austinvalle/bufo"
5+
}
6+
}
7+
}
8+
9+
resource "terraform_data" "test" {
10+
lifecycle {
11+
action_trigger {
12+
events = [after_create]
13+
actions = [action.bufo_print.success]
14+
}
15+
}
16+
}
17+
18+
action "bufo_print" "success" {
19+
config {
20+
name = "bufo-the-builder"
21+
}
22+
}

go.mod

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ module github.com/austinvalle/terraform-provider-bufo
22

33
go 1.23.7
44

5-
require github.com/hashicorp/terraform-plugin-framework v1.16.0-alpha.1.0.20250728185851-cca5c5aac673
5+
require (
6+
github.com/hashicorp/terraform-plugin-framework v1.16.0-alpha.1.0.20250728185851-cca5c5aac673
7+
github.com/qeesung/image2ascii v1.0.1
8+
)
69

710
require (
11+
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 // indirect
812
github.com/fatih/color v1.16.0 // indirect
913
github.com/golang/protobuf v1.5.4 // indirect
1014
github.com/hashicorp/go-hclog v1.6.3 // indirect
@@ -18,11 +22,13 @@ require (
1822
github.com/mattn/go-colorable v0.1.13 // indirect
1923
github.com/mattn/go-isatty v0.0.20 // indirect
2024
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
25+
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
2126
github.com/oklog/run v1.0.0 // indirect
2227
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
2328
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
29+
github.com/wayneashleyberry/terminal-dimensions v1.1.0 // indirect
2430
golang.org/x/net v0.41.0 // indirect
25-
golang.org/x/sys v0.33.0 // indirect
31+
golang.org/x/sys v0.34.0 // indirect
2632
golang.org/x/text v0.26.0 // indirect
2733
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
2834
google.golang.org/grpc v1.73.0 // indirect

go.sum

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo=
2+
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
13
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
24
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
35
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -47,10 +49,15 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
4749
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
4850
github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
4951
github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
52+
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
53+
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
5054
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
5155
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
5256
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5357
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
58+
github.com/qeesung/image2ascii v1.0.1 h1:Fe5zTnX/v/qNC3OC4P/cfASOXS501Xyw2UUcgrLgtp4=
59+
github.com/qeesung/image2ascii v1.0.1/go.mod h1:kZKhyX0h2g/YXa/zdJR3JnLnJ8avHjZ3LrvEKSYyAyU=
60+
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
5461
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5562
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
5663
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
@@ -59,6 +66,8 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU
5966
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
6067
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
6168
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
69+
github.com/wayneashleyberry/terminal-dimensions v1.1.0 h1:EB7cIzBdsOzAgmhTUtTTQXBByuPheP/Zv1zL2BRPY6g=
70+
github.com/wayneashleyberry/terminal-dimensions v1.1.0/go.mod h1:2lc/0eWCObmhRczn2SdGSQtgBooLUzIotkkEGXqghyg=
6271
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
6372
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
6473
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
@@ -80,8 +89,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
8089
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
8190
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
8291
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
83-
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
84-
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
92+
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
93+
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
8594
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
8695
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
8796
google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=

internal/provider/bufo_print.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"image"
7+
"math/rand"
8+
9+
"github.com/hashicorp/terraform-plugin-framework/action"
10+
"github.com/hashicorp/terraform-plugin-framework/action/schema"
11+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
"github.com/qeesung/image2ascii/convert"
14+
)
15+
16+
var (
17+
_ action.Action = (*printBufo)(nil)
18+
)
19+
20+
func NewPrintBufo() action.Action {
21+
return &printBufo{}
22+
}
23+
24+
type printBufo struct{}
25+
26+
func (a *printBufo) Metadata(ctx context.Context, req action.MetadataRequest, resp *action.MetadataResponse) {
27+
resp.TypeName = req.ProviderTypeName + "_print"
28+
}
29+
30+
func (a *printBufo) Schema(ctx context.Context, req action.SchemaRequest, resp *action.SchemaResponse) {
31+
resp.Schema = schema.UnlinkedSchema{
32+
Description: "Prints an ASCII bufo",
33+
Attributes: map[string]schema.Attribute{
34+
"name": schema.StringAttribute{
35+
Description: "Name of the bufo to print, see: https://bufo.zone/. If no name is provided, a random bufo will be selected!",
36+
Optional: true,
37+
Validators: []validator.String{
38+
ValidBufoName(),
39+
},
40+
},
41+
"ratio": schema.Float64Attribute{
42+
Description: "The ratio to scale the width/height of the bufo from the original, defaults to 0.5",
43+
Optional: true,
44+
},
45+
},
46+
}
47+
}
48+
49+
func (a *printBufo) Invoke(ctx context.Context, req action.InvokeRequest, resp *action.InvokeResponse) {
50+
var config printBufoModel
51+
52+
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
53+
if resp.Diagnostics.HasError() {
54+
return
55+
}
56+
57+
var bufoFileName string
58+
if config.Name.IsNull() {
59+
// Choose a random bufo
60+
bufoEntries, err := bufos.ReadDir("bufos")
61+
if err != nil {
62+
resp.Diagnostics.AddError(
63+
"Failed to select a random bufo",
64+
fmt.Sprintf("There was an issue finding a random bufo: %s", err),
65+
)
66+
return
67+
}
68+
69+
randomBufoIdx := rand.Intn(len(bufoEntries))
70+
bufoFileName = bufoEntries[randomBufoIdx].Name()
71+
} else {
72+
bufoFileName = fmt.Sprintf("%s.png", config.Name.ValueString())
73+
}
74+
75+
bufoLocation := fmt.Sprintf("bufos/%s", bufoFileName)
76+
77+
bufoFile, err := bufos.Open(bufoLocation)
78+
if err != nil {
79+
resp.Diagnostics.AddError(
80+
"Failed to retrieve bufo",
81+
fmt.Sprintf("There was an issue finding bufo at %q: %s", bufoFileName, err),
82+
)
83+
return
84+
}
85+
86+
converter := convert.NewImageConverter()
87+
img, _, err := image.Decode(bufoFile)
88+
if err != nil {
89+
resp.Diagnostics.AddError(
90+
"Failed to decode bufo",
91+
fmt.Sprintf("There was an issue decoding bufo at %q: %s", bufoFileName, err),
92+
)
93+
return
94+
}
95+
96+
ratio := 0.5
97+
if !config.Ratio.IsNull() {
98+
ratio = config.Ratio.ValueFloat64()
99+
}
100+
101+
bufoAscii := converter.Image2ASCIIString(img, &convert.Options{
102+
Ratio: ratio,
103+
FixedWidth: -1,
104+
FixedHeight: -1,
105+
})
106+
107+
resp.SendProgress(action.InvokeProgressEvent{
108+
Message: fmt.Sprintf("\n\nBufo: %q\n\n%s", bufoFileName, bufoAscii),
109+
})
110+
}
111+
112+
type printBufoModel struct {
113+
Name types.String `tfsdk:"name"`
114+
Ratio types.Float64 `tfsdk:"ratio"`
115+
}

internal/provider/bufos_embed.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package provider
2+
3+
import "embed"
4+
5+
//go:embed bufos/*.png
6+
var bufos embed.FS

internal/provider/provider.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ func (p *BufoProvider) Resources(ctx context.Context) []func() resource.Resource
3131
}
3232

3333
func (p *BufoProvider) Actions(ctx context.Context) []func() action.Action {
34-
return []func() action.Action{}
34+
return []func() action.Action{
35+
NewPrintBufo,
36+
}
3537
}
3638

3739
func (p *BufoProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
8+
)
9+
10+
var _ validator.String = validBufoName{}
11+
12+
type validBufoName struct{}
13+
14+
func (validator validBufoName) Description(_ context.Context) string {
15+
return `value must contain "bufo"`
16+
}
17+
18+
func (validator validBufoName) MarkdownDescription(ctx context.Context) string {
19+
return validator.Description(ctx)
20+
}
21+
22+
func (v validBufoName) ValidateString(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
23+
if req.ConfigValue.IsNull() || req.ConfigValue.IsUnknown() {
24+
return
25+
}
26+
27+
bufoFileName := fmt.Sprintf("%s.png", req.ConfigValue.ValueString())
28+
bufoLocation := fmt.Sprintf("bufos/%s", bufoFileName)
29+
30+
_, err := bufos.Open(bufoLocation)
31+
if err != nil {
32+
resp.Diagnostics.AddAttributeError(
33+
req.Path,
34+
"Invalid Bufo Name",
35+
fmt.Sprintf("No bufo was found for %q, check out the full list at: https://github.com/knobiknows/all-the-bufo/tree/main/all-the-bufo", bufoFileName),
36+
)
37+
return
38+
}
39+
}
40+
41+
func ValidBufoName() validBufoName {
42+
return validBufoName{}
43+
}

0 commit comments

Comments
 (0)