├── .gitignore ├── cli.go ├── internal ├── genny │ ├── build │ │ ├── apkg_test.go │ │ ├── build_deps.go │ │ ├── templates │ │ │ ├── a │ │ │ │ ├── embed.go.plush │ │ │ │ └── aa.go.plush │ │ │ └── migrations │ │ │ │ ├── embed.go.plush │ │ │ │ └── dot-pop-tmp.md │ │ ├── options_test.go │ │ ├── events.go │ │ ├── build_deps_test.go │ │ ├── transform_main.go │ │ ├── transform_main_test.go │ │ ├── cleanup.go │ │ ├── apkg.go │ │ ├── cleanup_test.go │ │ └── validate_test.go │ ├── info │ │ ├── templates │ │ │ ├── module │ │ │ │ └── go.mod │ │ │ └── config │ │ │ │ ├── buffalo-app.toml │ │ │ │ └── buffalo-plugins.toml │ │ ├── options_test.go │ │ ├── info_test.go │ │ ├── options.go │ │ ├── pkg.go │ │ ├── config.go │ │ ├── pkg_test.go │ │ ├── app_test.go │ │ ├── config_test.go │ │ ├── app.go │ │ └── info.go │ ├── newapp │ │ ├── api │ │ │ ├── options_test.go │ │ │ ├── templates │ │ │ │ ├── locales │ │ │ │ │ ├── all.en-us.yaml.tmpl │ │ │ │ │ └── embed.go.tmpl │ │ │ │ └── actions │ │ │ │ │ ├── render.go.tmpl │ │ │ │ │ ├── home_test.go.tmpl │ │ │ │ │ └── home.go.tmpl │ │ │ ├── options.go │ │ │ └── api.go │ │ ├── web │ │ │ ├── options_test.go │ │ │ ├── templates │ │ │ │ ├── public │ │ │ │ │ ├── robots.txt.tmpl │ │ │ │ │ └── embed.go.tmpl │ │ │ │ ├── locales │ │ │ │ │ ├── all.en-us.yaml.tmpl │ │ │ │ │ └── embed.go.tmpl │ │ │ │ ├── actions │ │ │ │ │ ├── home_test.go.tmpl │ │ │ │ │ ├── home.go.tmpl │ │ │ │ │ └── render.go.tmpl │ │ │ │ └── templates │ │ │ │ │ ├── embed.go.tmpl │ │ │ │ │ ├── _flash.plush.html.tmpl │ │ │ │ │ └── application.plush.html.tmpl │ │ │ └── options.go │ │ └── core │ │ │ ├── templates │ │ │ ├── inflections.json.tmpl │ │ │ ├── grifts │ │ │ │ └── init.go.tmpl │ │ │ ├── actions │ │ │ │ ├── render.go.tmpl │ │ │ │ ├── home_test.go.tmpl │ │ │ │ ├── home.go.tmpl │ │ │ │ └── actions_test.go.tmpl │ │ │ ├── dot-env.tmpl │ │ │ ├── dot-codeclimate.yml.tmpl │ │ │ ├── fixtures │ │ │ │ └── sample.toml.tmpl │ │ │ ├── cmd │ │ │ │ └── app │ │ │ │ │ └── main.go.tmpl │ │ │ └── README.md.tmpl │ │ │ └── options_test.go │ ├── assets │ │ ├── webpack │ │ │ ├── templates │ │ │ │ ├── public │ │ │ │ │ └── assets │ │ │ │ │ │ └── keep.tmpl │ │ │ │ ├── dot-babelrc.tmpl │ │ │ │ ├── postcss.config.js.tmpl │ │ │ │ ├── assets │ │ │ │ │ ├── images │ │ │ │ │ │ └── favicon.ico.tmpl │ │ │ │ │ ├── css │ │ │ │ │ │ └── application.scss.tmpl │ │ │ │ │ └── js │ │ │ │ │ │ └── application.js.tmpl │ │ │ │ └── package.json.tmpl │ │ │ └── options.go │ │ └── standard │ │ │ ├── templates │ │ │ └── public │ │ │ │ └── assets │ │ │ │ ├── application.css.tmpl │ │ │ │ ├── application.js.tmpl │ │ │ │ └── images │ │ │ │ └── favicon.ico.tmpl │ │ │ ├── options.go │ │ │ ├── standard.go │ │ │ └── standard_test.go │ ├── fix │ │ ├── _fixtures │ │ │ ├── buffaloPre0_18web │ │ │ │ ├── public │ │ │ │ │ ├── assets │ │ │ │ │ │ └── .keep │ │ │ │ │ └── robots.txt │ │ │ │ ├── config │ │ │ │ │ ├── buffalo-plugins.toml │ │ │ │ │ └── buffalo-app.toml │ │ │ │ ├── assets │ │ │ │ │ ├── images │ │ │ │ │ │ └── favicon.ico │ │ │ │ │ ├── css │ │ │ │ │ │ └── application.scss │ │ │ │ │ └── js │ │ │ │ │ │ └── application.js │ │ │ │ ├── locales │ │ │ │ │ └── all.en-us.yaml │ │ │ │ ├── grifts │ │ │ │ │ ├── init.go │ │ │ │ │ └── db.go │ │ │ │ ├── actions │ │ │ │ │ ├── home_test.go │ │ │ │ │ ├── home.go │ │ │ │ │ ├── actions_test.go │ │ │ │ │ └── render.go │ │ │ │ ├── .buffalo.dev.yml │ │ │ │ ├── models │ │ │ │ │ ├── models.go │ │ │ │ │ └── models_test.go │ │ │ │ ├── templates │ │ │ │ │ ├── _flash.plush.html │ │ │ │ │ └── application.plush.html │ │ │ │ ├── fixtures │ │ │ │ │ └── sample.toml │ │ │ │ └── main.go │ │ │ ├── buffaloPre0_18api │ │ │ │ ├── config │ │ │ │ │ ├── buffalo-plugins.toml │ │ │ │ │ └── buffalo-app.toml │ │ │ │ ├── locales │ │ │ │ │ └── all.en-us.yaml │ │ │ │ ├── grifts │ │ │ │ │ ├── init.go │ │ │ │ │ └── db.go │ │ │ │ ├── actions │ │ │ │ │ ├── home_test.go │ │ │ │ │ ├── render.go │ │ │ │ │ ├── home.go │ │ │ │ │ └── actions_test.go │ │ │ │ ├── .buffalo.dev.yml │ │ │ │ ├── models │ │ │ │ │ ├── models.go │ │ │ │ │ └── models_test.go │ │ │ │ ├── vendor │ │ │ │ │ └── models_test.go │ │ │ │ ├── fixtures │ │ │ │ │ └── sample.toml │ │ │ │ └── main.go │ │ │ └── buffalo0_11 │ │ │ │ ├── main.go │ │ │ │ └── .buffalo.dev.yml │ │ ├── options_test.go │ │ ├── events.go │ │ ├── tools.go │ │ ├── options.go │ │ ├── apptoml.go │ │ ├── docker_test.go │ │ ├── tools_test.go │ │ ├── action.go │ │ ├── fix_helpers.go │ │ ├── apptoml_test.go │ │ ├── action_test.go │ │ ├── refresh_test.go │ │ ├── movemain_test.go │ │ ├── embed_test.go │ │ ├── embed.go │ │ ├── docker.go │ │ ├── plush.go │ │ └── webpack_test.go │ ├── actions │ │ ├── templates │ │ │ ├── tests_header.go.tmpl │ │ │ ├── view.plush.html.tmpl │ │ │ ├── actions_header.go.tmpl │ │ │ ├── test.go.tmpl │ │ │ └── actions.go.tmpl │ │ ├── _fixtures │ │ │ ├── inputs │ │ │ │ ├── existing │ │ │ │ │ ├── templates │ │ │ │ │ │ └── user │ │ │ │ │ │ │ └── edit.plush.html │ │ │ │ │ └── actions │ │ │ │ │ │ ├── user_test.go.tmpl │ │ │ │ │ │ ├── user.go.tmpl │ │ │ │ │ │ └── app.go.tmpl │ │ │ │ └── clean │ │ │ │ │ └── actions │ │ │ │ │ └── app.go │ │ │ └── outputs │ │ │ │ ├── existing │ │ │ │ ├── templates │ │ │ │ │ └── user │ │ │ │ │ │ ├── edit.plush.html │ │ │ │ │ │ └── show.plush.html │ │ │ │ └── actions │ │ │ │ │ ├── user_test.go.tmpl │ │ │ │ │ ├── app.go.tmpl │ │ │ │ │ └── user.go.tmpl │ │ │ │ ├── multi │ │ │ │ ├── templates │ │ │ │ │ └── user │ │ │ │ │ │ ├── edit.plush.html │ │ │ │ │ │ └── show.plush.html │ │ │ │ └── actions │ │ │ │ │ ├── user_test.go.tmpl │ │ │ │ │ ├── user.go.tmpl │ │ │ │ │ └── app.go.tmpl │ │ │ │ └── clean │ │ │ │ ├── templates │ │ │ │ └── user │ │ │ │ │ └── index.plush.html │ │ │ │ └── actions │ │ │ │ ├── user_test.go.tmpl │ │ │ │ ├── user.go.tmpl │ │ │ │ └── app.go.tmpl │ │ ├── presenter.go │ │ ├── options_test.go │ │ ├── options.go │ │ └── build_templates.go │ ├── mail │ │ ├── init │ │ │ └── templates │ │ │ │ ├── templates │ │ │ │ └── mail │ │ │ │ │ └── layout.plush.html.tmpl │ │ │ │ └── mailers │ │ │ │ └── mailers.go.tmpl │ │ └── options.go │ ├── docker │ │ ├── templates │ │ │ ├── dot-dockerignore.tmpl │ │ │ └── Dockerfile.tmpl │ │ ├── options_test.go │ │ ├── options.go │ │ ├── docker_test.go │ │ └── docker.go │ ├── resource │ │ ├── _fixtures │ │ │ ├── default │ │ │ │ ├── templates │ │ │ │ │ └── widgets │ │ │ │ │ │ ├── _form.plush.html │ │ │ │ │ │ ├── new.plush.html │ │ │ │ │ │ ├── edit.plush.html │ │ │ │ │ │ ├── show.plush.html │ │ │ │ │ │ └── index.plush.html │ │ │ │ ├── locales │ │ │ │ │ └── widgets.en-us.yaml │ │ │ │ └── actions │ │ │ │ │ └── widgets_test.go.tmpl │ │ │ └── nested │ │ │ │ ├── templates │ │ │ │ └── admin │ │ │ │ │ └── widgets │ │ │ │ │ ├── _form.plush.html │ │ │ │ │ ├── new.plush.html │ │ │ │ │ ├── edit.plush.html │ │ │ │ │ ├── show.plush.html │ │ │ │ │ └── index.plush.html │ │ │ │ ├── locales │ │ │ │ └── admin │ │ │ │ │ └── widgets.en-us.yaml │ │ │ │ └── actions │ │ │ │ └── admin_widgets_test.go.tmpl │ │ ├── templates │ │ │ ├── use_model │ │ │ │ └── actions │ │ │ │ │ └── resource-name_test.go.tmpl │ │ │ ├── standard │ │ │ │ └── actions │ │ │ │ │ ├── resource-name_test.go.tmpl │ │ │ │ │ └── resource-name.go.tmpl │ │ │ └── core │ │ │ │ ├── locales │ │ │ │ └── folder-name.en-us.yaml.tmpl │ │ │ │ └── templates │ │ │ │ └── folder-name │ │ │ │ ├── new.plush.html.tmpl │ │ │ │ ├── _form.plush.html.tmpl │ │ │ │ ├── edit.plush.html.tmpl │ │ │ │ └── show.plush.html.tmpl │ │ ├── presenter.go │ │ ├── options_test.go │ │ ├── models.go │ │ ├── options.go │ │ └── actions.go │ ├── add │ │ ├── options_test.go │ │ ├── add.go │ │ ├── options.go │ │ └── add_test.go │ ├── plugins │ │ └── install │ │ │ ├── options_test.go │ │ │ └── options.go │ ├── refresh │ │ ├── options.go │ │ ├── templates │ │ │ └── dot-buffalo.dev.yml.plush │ │ ├── refresh_test.go │ │ └── refresh.go │ ├── vcs │ │ ├── options_test.go │ │ ├── templates │ │ │ └── ignore.tmpl │ │ ├── options.go │ │ ├── vcs.go │ │ └── vcs_test.go │ ├── ci │ │ ├── options_test.go │ │ ├── templates │ │ │ ├── dot-travis.yml.tmpl │ │ │ ├── dot-gitlab-ci-no-pop.yml.tmpl │ │ │ ├── dot-github │ │ │ │ └── workflows │ │ │ │ │ └── test.yml.tmpl │ │ │ ├── dot-circleci │ │ │ │ └── config.yml.tmpl │ │ │ └── dot-gitlab-ci.yml.tmpl │ │ └── options.go │ ├── grift │ │ ├── grift.go │ │ ├── templates.go │ │ ├── options.go │ │ └── grift_test.go │ └── testrunner │ │ └── generators.go ├── runtime │ ├── version.go │ └── build.go ├── plugins │ ├── log.go │ ├── log_debug.go │ ├── plugdeps │ │ ├── command.go │ │ ├── plugins_test.go │ │ └── plugin.go │ ├── command.go │ ├── plugcmds │ │ ├── plug_map_test.go │ │ └── available_test.go │ └── plugins_test.go ├── cmd │ ├── generate │ │ ├── resource_model_migration.json │ │ ├── generate_resource_irregular.json │ │ ├── generate_underscore.json │ │ ├── generate_plain_task.json │ │ ├── generate_nested_task.json │ │ ├── generate_action_skip_template.json │ │ ├── cmd.go │ │ ├── resource_skip_model.json │ │ ├── generate_action_with_method.json │ │ ├── generate_resource_nested_api.json │ │ ├── resource_use_model.json │ │ ├── generate_resource_nested_model_name_api.json │ │ ├── generate_action_all.json │ │ ├── generate_action_existing.json │ │ ├── generate_resource_plural.json │ │ ├── generate_resource_singular.json │ │ ├── generate_mailer.json │ │ ├── generate_resource_nested_model_name_web.json │ │ ├── goth.json │ │ ├── generate_resource_nested_web.json │ │ ├── task.go │ │ └── mailer.go │ ├── destroy │ │ ├── destroy_model_all.json │ │ ├── destroy_action_all.json │ │ ├── destroy_mailer_all.json │ │ ├── cmd.go │ │ ├── destroy_resource_all.json │ │ ├── action.go │ │ └── mailer.go │ ├── popinstructions.txt │ ├── test │ │ ├── cmd.go │ │ └── test_test.go │ ├── setup │ │ ├── test.go │ │ ├── setupdescription.txt │ │ └── cmd.go │ ├── routes │ │ └── cmd.go │ ├── plugins │ │ ├── internal │ │ │ └── cache │ │ │ │ ├── clean.go │ │ │ │ ├── build.go │ │ │ │ └── list.go │ │ ├── cache.go │ │ ├── encode.go │ │ ├── available.go │ │ ├── listen.go │ │ ├── list.go │ │ ├── remove.go │ │ └── add.go │ ├── task │ │ └── cmd.go │ ├── version │ │ ├── version.go │ │ ├── cmd.go │ │ └── version_test.go │ ├── fix │ │ ├── fix.go │ │ └── cmd.go │ ├── info │ │ ├── cmd.go │ │ └── info.go │ ├── plugins.go │ └── dev │ │ └── cmd.go ├── defaults │ ├── defaults.go │ └── defaults_test.go └── testhelpers │ └── tmpfolder.go ├── .github ├── CODEOWNERS └── workflows │ ├── standard-stale.yml │ ├── standard-go-test.yml │ └── release.yml ├── cmd └── buffalo │ └── main.go ├── .golangci.yml ├── Dockerfile.slim.build ├── README.md ├── Dockerfile.build └── .goreleaser.yml /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | dist/ 3 | -------------------------------------------------------------------------------- /cli.go: -------------------------------------------------------------------------------- 1 | // This is the Buffalo CLI 2 | package cli 3 | -------------------------------------------------------------------------------- /internal/genny/build/apkg_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | -------------------------------------------------------------------------------- /internal/genny/info/templates/module/go.mod: -------------------------------------------------------------------------------- 1 | module foo -------------------------------------------------------------------------------- /internal/genny/info/templates/config/buffalo-app.toml: -------------------------------------------------------------------------------- 1 | app -------------------------------------------------------------------------------- /internal/genny/newapp/api/options_test.go: -------------------------------------------------------------------------------- 1 | package api 2 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/options_test.go: -------------------------------------------------------------------------------- 1 | package web 2 | -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/public/assets/keep.tmpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/public/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/genny/info/templates/config/buffalo-plugins.toml: -------------------------------------------------------------------------------- 1 | plugins -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Default owner 2 | * @gobuffalo/core-managers -------------------------------------------------------------------------------- /internal/genny/actions/templates/tests_header.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | -------------------------------------------------------------------------------- /internal/genny/assets/standard/templates/public/assets/application.css.tmpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/genny/assets/standard/templates/public/assets/application.js.tmpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/inflections.json.tmpl: -------------------------------------------------------------------------------- 1 | { 2 | "singular": "plural" 3 | } -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/public/robots.txt.tmpl: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/inputs/existing/templates/user/edit.plush.html: -------------------------------------------------------------------------------- 1 |

User#Edit

-------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/existing/templates/user/edit.plush.html: -------------------------------------------------------------------------------- 1 |

User#Edit

-------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/existing/templates/user/show.plush.html: -------------------------------------------------------------------------------- 1 |

User#Show

-------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/multi/templates/user/edit.plush.html: -------------------------------------------------------------------------------- 1 |

User#Edit

-------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/multi/templates/user/show.plush.html: -------------------------------------------------------------------------------- 1 |

User#Show

-------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/clean/templates/user/index.plush.html: -------------------------------------------------------------------------------- 1 |

User#Index

2 | -------------------------------------------------------------------------------- /internal/genny/actions/templates/view.plush.html.tmpl: -------------------------------------------------------------------------------- 1 |

{{.name.Pascalize}}#{{.action.Pascalize}}

2 | -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/dot-babelrc.tmpl: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /internal/genny/mail/init/templates/templates/mail/layout.plush.html.tmpl: -------------------------------------------------------------------------------- 1 |

templates/mail/layout.plush.html

2 | 3 | <%= yield %> 4 | -------------------------------------------------------------------------------- /internal/runtime/version.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | // Version is the current version of the buffalo binary 4 | var Version = "v0.18.14" 5 | -------------------------------------------------------------------------------- /internal/plugins/log.go: -------------------------------------------------------------------------------- 1 | //+build !debug 2 | 3 | package plugins 4 | 5 | func log(_ string, fn func() error) error { 6 | return fn() 7 | } 8 | -------------------------------------------------------------------------------- /internal/genny/assets/standard/options.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | // Options for generating a new standard set of assets 4 | type Options struct{} 5 | -------------------------------------------------------------------------------- /internal/genny/actions/templates/actions_header.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/postcss.config.js.tmpl: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('autoprefixer') 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /cmd/buffalo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/gobuffalo/cli/internal/cmd" 5 | ) 6 | 7 | func main() { 8 | cmd.Execute() 9 | } 10 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/config/buffalo-plugins.toml: -------------------------------------------------------------------------------- 1 | [[plugin]] 2 | binary = "buffalo-pop" 3 | go_get = "github.com/gobuffalo/buffalo-pop/v2" 4 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/config/buffalo-plugins.toml: -------------------------------------------------------------------------------- 1 | [[plugin]] 2 | binary = "buffalo-pop" 3 | go_get = "github.com/gobuffalo/buffalo-pop/v2" 4 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/clean/actions/user_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_User_Index() { 4 | as.Fail("Not Implemented!") 5 | } 6 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters-settings: 2 | errcheck: 3 | exclude-functions: 4 | - events.Emit 5 | - events.EmitPayload 6 | - events.EmitError 7 | - events.NamedListen 8 | -------------------------------------------------------------------------------- /internal/cmd/generate/resource_model_migration.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "models/user.go", 4 | "contains": [ 5 | "type User struct {" 6 | ] 7 | } 8 | ] -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/assets/images/favicon.ico.tmpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gobuffalo/cli/HEAD/internal/genny/assets/webpack/templates/assets/images/favicon.ico.tmpl -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gobuffalo/cli/HEAD/internal/genny/fix/_fixtures/buffaloPre0_18web/assets/images/favicon.ico -------------------------------------------------------------------------------- /internal/genny/assets/standard/templates/public/assets/images/favicon.ico.tmpl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gobuffalo/cli/HEAD/internal/genny/assets/standard/templates/public/assets/images/favicon.ico.tmpl -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/assets/css/application.scss.tmpl: -------------------------------------------------------------------------------- 1 | @import "~bootstrap/scss/bootstrap.scss"; 2 | @import "~@fortawesome/fontawesome-free/css/all.min.css"; 3 | 4 | @import "buffalo"; 5 | -------------------------------------------------------------------------------- /internal/cmd/destroy/destroy_model_all.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "models/ouch.go", 4 | "absent": true 5 | }, 6 | { 7 | "path": "models/ouch_test.go", 8 | "absent": true 9 | } 10 | ] -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/inputs/existing/actions/user_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_User_Edit() { 4 | // custom test work 5 | as.Fail("Not Implemented!") 6 | } 7 | -------------------------------------------------------------------------------- /internal/genny/actions/templates/test.go.tmpl: -------------------------------------------------------------------------------- 1 | {{ range $action := .actions}} 2 | func (as *ActionSuite) Test_{{$.name.Pascalize}}_{{$action.Pascalize}}() { 3 | as.Fail("Not Implemented!") 4 | } 5 | {{end}} 6 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/assets/css/application.scss: -------------------------------------------------------------------------------- 1 | @import "~bootstrap/scss/bootstrap.scss"; 2 | @import "~@fortawesome/fontawesome-free/css/all.min.css"; 3 | 4 | @import "buffalo"; 5 | -------------------------------------------------------------------------------- /internal/cmd/destroy/destroy_action_all.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/ouch.go", 4 | "absent": true 5 | }, 6 | { 7 | "path": "actions/ouch_test.go", 8 | "absent": true 9 | } 10 | ] -------------------------------------------------------------------------------- /internal/genny/docker/templates/dot-dockerignore.tmpl: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .pnp.* 3 | .yarn/* 4 | !.yarn/patches 5 | !.yarn/plugins 6 | !.yarn/releases 7 | !.yarn/sdks 8 | !.yarn/versions 9 | *.log 10 | bin/ 11 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/templates/widgets/_form.plush.html: -------------------------------------------------------------------------------- 1 | <%= f.InputTag("Name") %> 2 | <%= f.TextAreaTag("Desc", {rows: 10}) %> 3 | 4 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_irregular.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/people.go", 4 | "contains": [ 5 | "type PeopleResource struct", 6 | "func (v PeopleResource)" 7 | ] 8 | } 9 | ] -------------------------------------------------------------------------------- /internal/genny/newapp/api/templates/locales/all.en-us.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # For more information on using i18n see: https://github.com/nicksnyder/go-i18n 2 | - id: welcome_greeting 3 | translation: "Welcome to Buffalo (EN)" 4 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/locales/all.en-us.yaml.tmpl: -------------------------------------------------------------------------------- 1 | # For more information on using i18n see: https://github.com/nicksnyder/go-i18n 2 | - id: welcome_greeting 3 | translation: "Welcome to Buffalo (EN)" 4 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/templates/admin/widgets/_form.plush.html: -------------------------------------------------------------------------------- 1 | <%= f.InputTag("Name") %> 2 | <%= f.TextAreaTag("Desc", {rows: 10}) %> 3 | 4 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/locales/all.en-us.yaml: -------------------------------------------------------------------------------- 1 | # For more information on using i18n see: https://github.com/nicksnyder/go-i18n 2 | - id: welcome_greeting 3 | translation: "Welcome to Buffalo (EN)" 4 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/locales/all.en-us.yaml: -------------------------------------------------------------------------------- 1 | # For more information on using i18n see: https://github.com/nicksnyder/go-i18n 2 | - id: welcome_greeting 3 | translation: "Welcome to Buffalo (EN)" 4 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/grifts/init.go: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "coke/actions" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | func init() { 10 | buffalo.Grifts(actions.App()) 11 | } 12 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/grifts/init.go: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "coke/actions" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | func init() { 10 | buffalo.Grifts(actions.App()) 11 | } 12 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/grifts/init.go.tmpl: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "{{ .opts.App.ActionsPkg }}" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | func init() { 10 | buffalo.Grifts(actions.App()) 11 | } 12 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/actions/render.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo/render" 5 | ) 6 | 7 | var r *render.Engine 8 | 9 | func init() { 10 | r = render.New(render.Options{}) 11 | } 12 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_underscore.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/person_events.go", 4 | "contains": [ 5 | "c.Render(http.StatusOK, r.Auto(c, personEvents))", 6 | "c.Render(http.StatusOK, r.Auto(c, personEvent))" 7 | ] 8 | } 9 | ] -------------------------------------------------------------------------------- /internal/genny/build/build_deps.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "github.com/gobuffalo/genny/v2" 5 | ) 6 | 7 | func buildDeps(opts *Options) (*genny.Generator, error) { 8 | g := genny.New() 9 | err := opts.Validate() 10 | return g, err 11 | } 12 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/assets/js/application.js: -------------------------------------------------------------------------------- 1 | require("expose-loader?$!expose-loader?jQuery!jquery"); 2 | require("bootstrap/dist/js/bootstrap.bundle.js"); 3 | require("@fortawesome/fontawesome-free/js/all.js"); 4 | 5 | $(() => { 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffalo0_11/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/gobuffalo/envy" 7 | ) 8 | 9 | func main() { 10 | port := envy.Get("PORT", "3000") 11 | app := actions.App() 12 | log.Fatal(app.Start(port)) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/use_model/actions/resource-name_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | {{ range $a := .actions }} 4 | func (as *ActionSuite) Test_{{$.opts.Name.Resource}}Resource_{{ $a.Pascalize }}() { 5 | as.Fail("Not Implemented!") 6 | } 7 | {{ end }} 8 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/multi/actions/user_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_User_Show() { 4 | as.Fail("Not Implemented!") 5 | } 6 | 7 | func (as *ActionSuite) Test_User_Edit() { 8 | as.Fail("Not Implemented!") 9 | } 10 | -------------------------------------------------------------------------------- /internal/genny/build/templates/a/embed.go.plush: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/buffalo" 8 | ) 9 | 10 | //go:embed * 11 | var files embed.FS 12 | 13 | func FS() fs.FS { 14 | return buffalo.NewFS(files, "a") 15 | } 16 | -------------------------------------------------------------------------------- /internal/plugins/log_debug.go: -------------------------------------------------------------------------------- 1 | //+build debug 2 | 3 | package plugins 4 | 5 | import ( 6 | "fmt" 7 | "time" 8 | ) 9 | 10 | func log(name string, fn func() error) error { 11 | start := time.Now() 12 | defer fmt.Println(name, time.Now().Sub(start)) 13 | return fn() 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/standard-stale.yml: -------------------------------------------------------------------------------- 1 | name: Standard Autocloser 2 | 3 | on: 4 | schedule: 5 | - cron: "30 1 * * *" 6 | 7 | jobs: 8 | call-standard-autocloser: 9 | name: Autocloser 10 | uses: gobuffalo/.github/.github/workflows/stale.yml@v1 11 | secrets: inherit 12 | -------------------------------------------------------------------------------- /.github/workflows/standard-go-test.yml: -------------------------------------------------------------------------------- 1 | name: Standard Test 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | 8 | jobs: 9 | call-standard-test: 10 | name: Test 11 | uses: gobuffalo/.github/.github/workflows/go-test.yml@v1.6 12 | secrets: inherit 13 | -------------------------------------------------------------------------------- /internal/genny/build/options_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | r.NoError(opts.Validate()) 14 | } 15 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/public/embed.go.tmpl: -------------------------------------------------------------------------------- 1 | package public 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/buffalo" 8 | ) 9 | 10 | //go:embed * 11 | var files embed.FS 12 | 13 | func FS() fs.FS { 14 | return buffalo.NewFS(files, "public") 15 | } 16 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_plain_task.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "grifts/plain_task.go", 4 | "contains": [ 5 | "var _ = Desc(\"plain_task\", \"Task Description\")", 6 | "var _ = Add(\"plain_task\", func(c *Context) error {", 7 | "return nil" 8 | ] 9 | } 10 | ] -------------------------------------------------------------------------------- /internal/genny/actions/presenter.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "github.com/gobuffalo/flect/name" 4 | 5 | type data map[string]interface{} 6 | 7 | type presenter struct { 8 | Name name.Ident 9 | Actions []name.Ident 10 | Helpers data 11 | Data data 12 | Options *Options 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/assets/js/application.js.tmpl: -------------------------------------------------------------------------------- 1 | require("expose-loader?exposes=$,jQuery!jquery"); 2 | require("bootstrap/dist/js/bootstrap.bundle.js"); 3 | require("@fortawesome/fontawesome-free/js/all.js"); 4 | require("jquery-ujs/src/rails.js"); 5 | 6 | $(() => { 7 | 8 | }); 9 | -------------------------------------------------------------------------------- /internal/genny/newapp/api/templates/actions/render.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo/render" 5 | ) 6 | 7 | var r *render.Engine 8 | 9 | func init() { 10 | r = render.New(render.Options{ 11 | DefaultContentType: "application/json", 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /internal/cmd/destroy/destroy_mailer_all.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "mailers/ouch.go", 4 | "absent": true 5 | }, 6 | { 7 | "path": "templates/mail/ouch.html", 8 | "absent": true 9 | }, 10 | { 11 | "path": "templates/mail/ouch.plush.html", 12 | "absent": true 13 | } 14 | ] -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/existing/actions/user_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_User_Edit() { 4 | // custom test work 5 | as.Fail("Not Implemented!") 6 | } 7 | 8 | func (as *ActionSuite) Test_User_Show() { 9 | as.Fail("Not Implemented!") 10 | } 11 | -------------------------------------------------------------------------------- /internal/genny/add/options_test.go: -------------------------------------------------------------------------------- 1 | package add 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.NoError(err) 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/build/templates/migrations/embed.go.plush: -------------------------------------------------------------------------------- 1 | package migrations 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/buffalo" 8 | ) 9 | 10 | //go:embed * 11 | var files embed.FS 12 | 13 | func FS() fs.FS { 14 | return buffalo.NewFS(files, "migrations") 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/fix/options_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.NoError(err) 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/newapp/api/templates/actions/home_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "net/http" 4 | 5 | func (as *ActionSuite) Test_HomeHandler() { 6 | res := as.JSON("/").Get() 7 | 8 | as.Equal(http.StatusOK, res.Code) 9 | as.Contains(res.Body.String(), "Welcome to Buffalo") 10 | } 11 | -------------------------------------------------------------------------------- /internal/genny/newapp/api/templates/locales/embed.go.tmpl: -------------------------------------------------------------------------------- 1 | package locales 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/buffalo" 8 | ) 9 | 10 | //go:embed *.yaml 11 | var files embed.FS 12 | 13 | func FS() fs.FS { 14 | return buffalo.NewFS(files, "locales") 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/actions/home_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "net/http" 4 | 5 | func (as *ActionSuite) Test_HomeHandler() { 6 | res := as.HTML("/").Get() 7 | 8 | as.Equal(http.StatusOK, res.Code) 9 | as.Contains(res.Body.String(), "Welcome to Buffalo") 10 | } 11 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/actions/home_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "net/http" 4 | 5 | func (as *ActionSuite) Test_HomeHandler() { 6 | res := as.HTML("/").Get() 7 | 8 | as.Equal(http.StatusOK, res.Code) 9 | as.Contains(res.Body.String(), "Welcome to Buffalo") 10 | } 11 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/locales/embed.go.tmpl: -------------------------------------------------------------------------------- 1 | package locales 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/buffalo" 8 | ) 9 | 10 | //go:embed *.yaml 11 | var files embed.FS 12 | 13 | func FS() fs.FS { 14 | return buffalo.NewFS(files, "locales") 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/actions/home_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "net/http" 4 | 5 | func (as *ActionSuite) Test_HomeHandler() { 6 | res := as.JSON("/").Get() 7 | 8 | as.Equal(http.StatusOK, res.Code) 9 | as.Contains(res.Body.String(), "Welcome to Buffalo") 10 | } 11 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/actions/render.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo/render" 5 | ) 6 | 7 | var r *render.Engine 8 | 9 | func init() { 10 | r = render.New(render.Options{ 11 | DefaultContentType: "application/json", 12 | }) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/actions/home_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import "net/http" 4 | 5 | func (as *ActionSuite) Test_HomeHandler() { 6 | res := as.HTML("/").Get() 7 | 8 | as.Equal(http.StatusOK, res.Code) 9 | as.Contains(res.Body.String(), "Welcome to Buffalo") 10 | } 11 | -------------------------------------------------------------------------------- /internal/genny/info/options_test.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.NoError(err) 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/templates/embed.go.tmpl: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/buffalo" 8 | ) 9 | 10 | //go:embed * */* 11 | var files embed.FS 12 | 13 | func FS() fs.FS { 14 | return buffalo.NewFS(files, "templates") 15 | } 16 | -------------------------------------------------------------------------------- /internal/cmd/popinstructions.txt: -------------------------------------------------------------------------------- 1 | Pop support has been moved to the https://github.com/gobuffalo/buffalo-pop plugin. 2 | 3 | !! PLEASE READ PLUGIN DOCUMENTATION - https://gobuffalo.io/en/docs/plugins 4 | 5 | Buffalo Plugins Installation: 6 | 7 | $ buffalo plugins install github.com/gobuffalo/buffalo-pop/v3@latest 8 | -------------------------------------------------------------------------------- /internal/genny/docker/options_test.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.NoError(err) 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/resource/presenter.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "github.com/gobuffalo/attrs" 5 | "github.com/gobuffalo/flect/name" 6 | "github.com/gobuffalo/meta" 7 | ) 8 | 9 | type presenter struct { 10 | App meta.App 11 | Name name.Ident 12 | Model name.Ident 13 | Attrs attrs.Attrs 14 | } 15 | -------------------------------------------------------------------------------- /internal/genny/plugins/install/options_test.go: -------------------------------------------------------------------------------- 1 | package install 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.NoError(err) 15 | } 16 | -------------------------------------------------------------------------------- /internal/genny/actions/templates/actions.go.tmpl: -------------------------------------------------------------------------------- 1 | {{ range $action := .actions }} 2 | // {{$.name.Pascalize}}{{$action.Pascalize}} default implementation. 3 | func {{$.name.Pascalize}}{{$action.Pascalize}}(c buffalo.Context) error { 4 | return c.Render(http.StatusOK, r.HTML("{{$.name.File}}/{{$action.File}}.html")) 5 | } 6 | {{end}} 7 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/clean/actions/user.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // UserIndex default implementation. 10 | func UserIndex(c buffalo.Context) error { 11 | return c.Render(http.StatusOK, r.HTML("user/index.html")) 12 | } 13 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/locales/widgets.en-us.yaml: -------------------------------------------------------------------------------- 1 | - id: "widget.created.success" 2 | translation: "Widget was successfully created." 3 | - id: "widget.updated.success" 4 | translation: "Widget was successfully updated." 5 | - id: "widget.destroyed.success" 6 | translation: "Widget was successfully destroyed." 7 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/locales/admin/widgets.en-us.yaml: -------------------------------------------------------------------------------- 1 | - id: "widget.created.success" 2 | translation: "Widget was successfully created." 3 | - id: "widget.updated.success" 4 | translation: "Widget was successfully updated." 5 | - id: "widget.destroyed.success" 6 | translation: "Widget was successfully destroyed." 7 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/config/buffalo-app.toml: -------------------------------------------------------------------------------- 1 | name = "coke" 2 | bin = "bin/coke" 3 | vcs = "git" 4 | with_pop = true 5 | with_sqlite = false 6 | with_dep = false 7 | with_webpack = false 8 | with_nodejs = false 9 | with_yarn = false 10 | with_docker = true 11 | with_grifts = true 12 | as_web = false 13 | as_api = true 14 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/config/buffalo-app.toml: -------------------------------------------------------------------------------- 1 | name = "coke" 2 | bin = "bin/coke" 3 | vcs = "git" 4 | with_pop = true 5 | with_sqlite = false 6 | with_dep = false 7 | with_webpack = true 8 | with_nodejs = true 9 | with_yarn = true 10 | with_docker = true 11 | with_grifts = true 12 | as_web = true 13 | as_api = false 14 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_nested_task.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "grifts/now.go", 4 | "contains": [ 5 | "var _ = Namespace(\"nested\", func() {", 6 | "Namespace(\"task\", func() {", 7 | "Desc(\"now\", \"Task Description\")", 8 | "Add(\"now\", func(c *Context) error {", 9 | "return nil" 10 | ] 11 | } 12 | ] -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/actions/home.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // HomeHandler is a default handler to serve up 10 | // a home page. 11 | func HomeHandler(c buffalo.Context) error { 12 | return c.Render(http.StatusOK, r.HTML("index.html")) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/fix/events.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | const ( 4 | // EvtFixStart is emitted when fixing starts 5 | EvtFixStart = "buffalo:fix:start" 6 | // EvtFixStop is emitted when fixing stops 7 | EvtFixStop = "buffalo:fix:stop" 8 | // EvtFixStopErr is emitted when fixing is stopped due to an error 9 | EvtFixStopErr = "buffalo:fix:stop:err" 10 | ) 11 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/inputs/existing/actions/user.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // UserEdit default implementation. 10 | func UserEdit(c buffalo.Context) error { 11 | // custom existing work 12 | return c.Render(http.StatusOK, r.HTML("user/edit.html")) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/grifts/db.go: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "github.com/markbates/grift/grift" 5 | ) 6 | 7 | var _ = grift.Namespace("db", func() { 8 | grift.Desc("seed", "Seeds a database") 9 | grift.Add("seed", func(c *grift.Context) error { 10 | // Add DB seeding stuff here 11 | return nil 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/grifts/db.go: -------------------------------------------------------------------------------- 1 | package grifts 2 | 3 | import ( 4 | "github.com/markbates/grift/grift" 5 | ) 6 | 7 | var _ = grift.Namespace("db", func() { 8 | grift.Desc("seed", "Seeds a database") 9 | grift.Add("seed", func(c *grift.Context) error { 10 | // Add DB seeding stuff here 11 | return nil 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/actions/home.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // HomeHandler is a default handler to serve up 10 | // a home page. 11 | func HomeHandler(c buffalo.Context) error { 12 | return c.Render(http.StatusOK, r.String("Hello from Buffalo")) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/actions/home.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // HomeHandler is a default handler to serve up 10 | // a home page. 11 | func HomeHandler(c buffalo.Context) error { 12 | return c.Render(http.StatusOK, r.HTML("home/index.plush.html")) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/standard/actions/resource-name_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | {{ range $a := .actions }} 9 | func (as *ActionSuite) Test_{{$.opts.Name.Resource}}Resource_{{ $a.Pascalize }}() { 10 | as.Fail("Not Implemented!") 11 | } 12 | {{ end }} 13 | -------------------------------------------------------------------------------- /internal/genny/refresh/options.go: -------------------------------------------------------------------------------- 1 | package refresh 2 | 3 | import "github.com/gobuffalo/meta" 4 | 5 | // Options for creating a new refresh config 6 | type Options struct { 7 | App meta.App 8 | } 9 | 10 | // Validate options 11 | func (opts *Options) Validate() error { 12 | if opts.App.IsZero() { 13 | opts.App = meta.New(".") 14 | } 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /internal/genny/assets/webpack/options.go: -------------------------------------------------------------------------------- 1 | package webpack 2 | 3 | import ( 4 | "github.com/gobuffalo/meta" 5 | ) 6 | 7 | // Options for creating a new webpack setup 8 | type Options struct { 9 | meta.App 10 | } 11 | 12 | // Validate options 13 | func (opts *Options) Validate() error { 14 | if opts.App.IsZero() { 15 | opts.App = meta.New(".") 16 | } 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /internal/genny/build/events.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | const ( 4 | // EvtBuildStart is emitted when building starts 5 | EvtBuildStart = "buffalo:build:start" 6 | // EvtBuildStop is emitted when building stops 7 | EvtBuildStop = "buffalo:build:stop" 8 | // EvtBuildStopErr is emitted when building is stopped due to an error 9 | EvtBuildStopErr = "buffalo:build:stop:err" 10 | ) 11 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_action_skip_template.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/users.go", 4 | "contains": [ 5 | "func UsersCreate(c buffalo.Context) error {" 6 | ] 7 | }, 8 | { 9 | "path": "templates/users/create.html", 10 | "absent": true 11 | }, 12 | { 13 | "path": "templates/users/create.plush.html", 14 | "absent": true 15 | } 16 | ] -------------------------------------------------------------------------------- /internal/cmd/test/cmd.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import "github.com/spf13/cobra" 4 | 5 | func Cmd() *cobra.Command { 6 | cmd := &cobra.Command{ 7 | Use: "test", 8 | Short: "Run the tests for the Buffalo app. Use --force-migrations to skip schema load.", 9 | DisableFlagParsing: true, 10 | RunE: runE, 11 | } 12 | 13 | return cmd 14 | } 15 | -------------------------------------------------------------------------------- /internal/genny/newapp/api/templates/actions/home.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // HomeHandler is a default handler to serve up 10 | // a home page. 11 | func HomeHandler(c buffalo.Context) error { 12 | return c.Render(http.StatusOK, r.JSON(map[string]string{"message": "Welcome to Buffalo!"})) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/templates/widgets/new.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

New Widget

3 |
4 | 5 | <%= formFor(widget, {action: widgetsPath(), method: "POST"}) { %> 6 | <%= partial("widgets/form.html") %> 7 | <%= linkTo(widgetsPath(), {class: "btn btn-warning", "data-confirm": "Are you sure?", body: "Cancel"}) %> 8 | <% } %> 9 | -------------------------------------------------------------------------------- /internal/genny/vcs/options_test.go: -------------------------------------------------------------------------------- 1 | package vcs 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.Error(err) 15 | 16 | opts.Provider = "git" 17 | 18 | err = opts.Validate() 19 | r.NoError(err) 20 | } 21 | -------------------------------------------------------------------------------- /internal/cmd/setup/test.go: -------------------------------------------------------------------------------- 1 | package setup 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | 7 | "github.com/gobuffalo/meta" 8 | ) 9 | 10 | func testCheck(meta.App) error { 11 | err := run(exec.Command("buffalo", "test")) 12 | if err != nil { 13 | return fmt.Errorf("We encountered the following error when trying to run your applications tests:\n%s", err) 14 | } 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/actions/home.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // HomeHandler is a default handler to serve up 10 | // a home page. 11 | func HomeHandler(c buffalo.Context) error { 12 | return c.Render(http.StatusOK, r.JSON(map[string]string{"message": "Welcome to Buffalo!"})) 13 | } 14 | -------------------------------------------------------------------------------- /internal/genny/resource/options_test.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.Error(err) 15 | 16 | opts.Name = "coke" 17 | 18 | err = opts.Validate() 19 | r.NoError(err) 20 | } 21 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/templates/admin/widgets/new.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

New Widget

3 |
4 | 5 | <%= formFor(widget, {action: adminWidgetsPath(), method: "POST"}) { %> 6 | <%= partial("admin/widgets/form.html") %> 7 | <%= linkTo(adminWidgetsPath(), {class: "btn btn-warning", "data-confirm": "Are you sure?", body: "Cancel"}) %> 8 | <% } %> 9 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffalo0_11/.buffalo.dev.yml: -------------------------------------------------------------------------------- 1 | app_root: . 2 | ignored_folders: 3 | - vendor 4 | - log 5 | - logs 6 | - assets 7 | - public 8 | - grifts 9 | - tmp 10 | - bin 11 | - node_modules 12 | - .sass-cache 13 | included_extensions: 14 | - .go 15 | - .env 16 | build_path: tmp 17 | build_delay: 200ns 18 | binary_name: app-build 19 | command_flags: [] 20 | enable_colors: true 21 | log_name: buffalo 22 | -------------------------------------------------------------------------------- /internal/genny/ci/options_test.go: -------------------------------------------------------------------------------- 1 | package ci 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.Error(err) 15 | 16 | opts.Provider = "travis-ci" 17 | opts.DBType = "postgres" 18 | 19 | err = opts.Validate() 20 | r.NoError(err) 21 | } 22 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/.buffalo.dev.yml: -------------------------------------------------------------------------------- 1 | app_root: . 2 | ignored_folders: 3 | - vendor 4 | - log 5 | - logs 6 | - assets 7 | - public 8 | - grifts 9 | - tmp 10 | - bin 11 | - node_modules 12 | - .sass-cache 13 | included_extensions: 14 | - .go 15 | - .env 16 | build_path: tmp 17 | build_delay: 200ns 18 | binary_name: app-build 19 | command_flags: [] 20 | enable_colors: true 21 | log_name: buffalo 22 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/.buffalo.dev.yml: -------------------------------------------------------------------------------- 1 | app_root: . 2 | ignored_folders: 3 | - vendor 4 | - log 5 | - logs 6 | - assets 7 | - public 8 | - grifts 9 | - tmp 10 | - bin 11 | - node_modules 12 | - .sass-cache 13 | included_extensions: 14 | - .go 15 | - .env 16 | build_path: tmp 17 | build_delay: 200ns 18 | binary_name: app-build 19 | command_flags: [] 20 | enable_colors: true 21 | log_name: buffalo 22 | -------------------------------------------------------------------------------- /internal/genny/newapp/api/options.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "github.com/gobuffalo/cli/internal/genny/newapp/core" 5 | ) 6 | 7 | // Options for API applications 8 | type Options struct { 9 | *core.Options 10 | } 11 | 12 | // Validate that options are usuable 13 | func (opts *Options) Validate() error { 14 | if opts.Options == nil { 15 | opts.Options = &core.Options{} 16 | } 17 | return opts.Options.Validate() 18 | } 19 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/templates/widgets/edit.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

Edit Widget

3 |
4 | 5 | <%= formFor(widget, {action: widgetPath({ widget_id: widget.ID }), method: "PUT"}) { %> 6 | <%= partial("widgets/form.html") %> 7 | <%= linkTo(widgetPath({ widget_id: widget.ID }), {class: "btn btn-warning", "data-confirm": "Are you sure?", body: "Cancel"}) %> 8 | <% } %> 9 | -------------------------------------------------------------------------------- /internal/cmd/generate/cmd.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | ) 6 | 7 | func Cmd() *cobra.Command { 8 | cmd := &cobra.Command{ 9 | Use: "generate", 10 | Short: "Generate application components", 11 | Aliases: []string{"g"}, 12 | } 13 | 14 | cmd.AddCommand(ResourceCmd) 15 | cmd.AddCommand(ActionCmd) 16 | cmd.AddCommand(TaskCmd) 17 | cmd.AddCommand(MailCmd) 18 | 19 | return cmd 20 | } 21 | -------------------------------------------------------------------------------- /internal/cmd/routes/cmd.go: -------------------------------------------------------------------------------- 1 | package routes 2 | 3 | import ( 4 | grifts "github.com/gobuffalo/grift/cmd" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | func Cmd() *cobra.Command { 9 | cmd := &cobra.Command{ 10 | Use: "routes", 11 | Short: "Print all defined routes", 12 | RunE: func(c *cobra.Command, args []string) error { 13 | return grifts.Run("buffalo task", []string{"routes"}) 14 | }, 15 | } 16 | 17 | return cmd 18 | } 19 | -------------------------------------------------------------------------------- /internal/cmd/generate/resource_skip_model.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "models/admin.go", 4 | "absent": true 5 | }, 6 | { 7 | "path": "models/admin_test.go", 8 | "absent": true 9 | }, 10 | { 11 | "path": "migrations/*_create_admins.up.fizz", 12 | "absent": true 13 | }, 14 | { 15 | "path": "migrations/*_create_admins.down.fizz", 16 | "absent": true 17 | } 18 | ] -------------------------------------------------------------------------------- /internal/cmd/plugins/internal/cache/clean.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/gobuffalo/cli/internal/plugins" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | // CleanCmd cleans the plugins cache 11 | var CleanCmd = &cobra.Command{ 12 | Use: "clean", 13 | Short: "cleans the plugins cache", 14 | RunE: func(cmd *cobra.Command, args []string) error { 15 | os.RemoveAll(plugins.CachePath) 16 | return nil 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/dot-env.tmpl: -------------------------------------------------------------------------------- 1 | # This .env file was generated by buffalo, add here the env variables you need 2 | # buffalo to load into the ENV on application startup so your application works correctly. 3 | # To add variables use KEY=VALUE format, you can later retrieve this in your application 4 | # by using os.Getenv("KEY"). 5 | # 6 | # Example: 7 | # DATABASE_PASSWORD=XXXXXXXXX 8 | # SESSION_SECRET=XXXXXXXXX 9 | # SMTP_SERVER=XXXXXXXXX 10 | -------------------------------------------------------------------------------- /internal/genny/refresh/templates/dot-buffalo.dev.yml.plush: -------------------------------------------------------------------------------- 1 | app_root: . 2 | ignored_folders: 3 | - vendor 4 | - log 5 | - logs 6 | - assets 7 | - public 8 | - grifts 9 | - tmp 10 | - bin 11 | - node_modules 12 | - .sass-cache 13 | included_extensions: 14 | - .go 15 | - .env 16 | build_path: tmp 17 | build_delay: 200ns 18 | build_target_path: "./cmd/app" 19 | binary_name: <%= app.Name %>-build 20 | command_flags: [] 21 | enable_colors: true 22 | log_name: buffalo 23 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/templates/admin/widgets/edit.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

Edit Widget

3 |
4 | 5 | <%= formFor(widget, {action: adminWidgetPath({ admin_widget_id: widget.ID }), method: "PUT"}) { %> 6 | <%= partial("admin/widgets/form.html") %> 7 | <%= linkTo(adminWidgetPath({ admin_widget_id: widget.ID }), {class: "btn btn-warning", "data-confirm": "Are you sure?", body: "Cancel"}) %> 8 | <% } %> 9 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/inputs/existing/actions/app.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo" 5 | ) 6 | 7 | var app *buffalo.App 8 | 9 | func App() *buffalo.App { 10 | if app == nil { 11 | app = buffalo.New(buffalo.Options{}) 12 | app.GET("/", HomeHandler) 13 | 14 | app.GET("/user/edit", UserEdit) 15 | app.ServeFiles("/", assetsBox) // serve files from the public directory 16 | } 17 | 18 | return app 19 | } 20 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/core/locales/folder-name.en-us.yaml.tmpl: -------------------------------------------------------------------------------- 1 | - id: "{{.opts.Model.Singularize.Underscore}}.created.success" 2 | translation: "{{.opts.Model.Proper}} was successfully created." 3 | - id: "{{.opts.Model.Singularize.Underscore}}.updated.success" 4 | translation: "{{.opts.Model.Proper}} was successfully updated." 5 | - id: "{{.opts.Model.Singularize.Underscore}}.destroyed.success" 6 | translation: "{{.opts.Model.Proper}} was successfully destroyed." 7 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/core/templates/folder-name/new.plush.html.tmpl: -------------------------------------------------------------------------------- 1 |
2 |

New {{.opts.Model.Proper}}

3 |
4 | 5 | <%= formFor({{.opts.Model.VarCaseSingle}}, {action: {{.opts.Name.VarCasePlural}}Path(), method: "POST"}) { %> 6 | <%= partial("{{.folder}}/form.html") %> 7 | <%= linkTo({{.opts.Name.VarCasePlural}}Path(), {class: "btn btn-warning", "data-confirm": "Are you sure?", body: "Cancel"}) %> 8 | <% } %> 9 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/multi/actions/user.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // UserShow default implementation. 10 | func UserShow(c buffalo.Context) error { 11 | return c.Render(http.StatusOK, r.HTML("user/show.html")) 12 | } 13 | 14 | // UserEdit default implementation. 15 | func UserEdit(c buffalo.Context) error { 16 | return c.Render(http.StatusOK, r.HTML("user/edit.html")) 17 | } 18 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/inputs/clean/actions/app.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | var ( 10 | app *buffalo.App 11 | appOnce sync.Once 12 | ) 13 | 14 | func App() *buffalo.App { 15 | appOnce.Do(func() { 16 | app = buffalo.New(buffalo.Options{}) 17 | app.GET("/", HomeHandler) 18 | 19 | app.ServeFiles("/", assetsBox) // serve files from the public directory 20 | }) 21 | 22 | return app 23 | } 24 | -------------------------------------------------------------------------------- /internal/genny/actions/options_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/require" 7 | ) 8 | 9 | func Test_Options_Validate(t *testing.T) { 10 | r := require.New(t) 11 | 12 | opts := &Options{} 13 | err := opts.Validate() 14 | r.Error(err) 15 | 16 | opts.Name = "user" 17 | 18 | err = opts.Validate() 19 | r.Error(err) 20 | 21 | opts.Actions = []string{"index", "show"} 22 | err = opts.Validate() 23 | r.NoError(err) 24 | } 25 | -------------------------------------------------------------------------------- /internal/cmd/plugins/internal/cache/build.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/gobuffalo/cli/internal/plugins" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | // BuildCmd rebuilds the plugins cache 11 | var BuildCmd = &cobra.Command{ 12 | Use: "build", 13 | Short: "rebuilds the plugins cache", 14 | RunE: func(cmd *cobra.Command, args []string) error { 15 | os.RemoveAll(plugins.CachePath) 16 | _, err := plugins.Available() 17 | return err 18 | }, 19 | } 20 | -------------------------------------------------------------------------------- /internal/genny/info/info_test.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2/gentest" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func Test_New(t *testing.T) { 11 | r := require.New(t) 12 | 13 | g, err := New(&Options{}) 14 | r.NoError(err) 15 | 16 | run := gentest.NewRunner() 17 | r.NoError(run.With(g)) 18 | r.NoError(run.Run()) 19 | 20 | res := run.Results() 21 | 22 | r.Len(res.Commands, 0) 23 | r.Len(res.Files, 0) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/dot-codeclimate.yml.tmpl: -------------------------------------------------------------------------------- 1 | version: "2" 2 | checks: 3 | method-lines: 4 | config: 5 | threshold: 100 6 | plugins: 7 | fixme: 8 | enabled: true 9 | gofmt: 10 | enabled: true 11 | golint: 12 | enabled: true 13 | govet: 14 | enabled: true 15 | exclude_patterns: 16 | - grifts/**/* 17 | - "**/*_test.go" 18 | - "*_test.go" 19 | - "**_test.go" 20 | - logs/* 21 | - public/* 22 | - templates/* 23 | - "**/node_modules/" 24 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/templates/_flash.plush.html.tmpl: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= for (k, messages) in flash { %> 4 | <%= for (msg) in messages { %> 5 | 9 | <% } %> 10 | <% } %> 11 |
12 |
13 | -------------------------------------------------------------------------------- /internal/cmd/destroy/cmd.go: -------------------------------------------------------------------------------- 1 | package destroy 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | ) 6 | 7 | func Cmd() *cobra.Command { 8 | cmd := &cobra.Command{ 9 | Use: "destroy", 10 | Short: "Destroy generated components", 11 | Aliases: []string{"d"}, 12 | } 13 | 14 | cmd.AddCommand(resourceCmd) 15 | cmd.AddCommand(actionCmd) 16 | cmd.AddCommand(mailerCmd) 17 | 18 | cmd.PersistentFlags().BoolVarP(&yesToAll, "yes", "y", false, "confirms all beforehand") 19 | 20 | return cmd 21 | } 22 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/actions/actions_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/gobuffalo/suite/v4" 8 | ) 9 | 10 | type ActionSuite struct { 11 | *suite.Action 12 | } 13 | 14 | func Test_ActionSuite(t *testing.T) { 15 | action, err := suite.NewActionWithFixtures(App(), os.DirFS("../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ActionSuite{ 21 | Action: action, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/existing/actions/app.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo" 5 | ) 6 | 7 | var app *buffalo.App 8 | 9 | func App() *buffalo.App { 10 | if app == nil { 11 | app = buffalo.New(buffalo.Options{}) 12 | app.GET("/", HomeHandler) 13 | 14 | app.GET("/user/edit", UserEdit) 15 | app.GET("/user/show", UserShow) 16 | app.ServeFiles("/", assetsBox) // serve files from the public directory 17 | } 18 | 19 | return app 20 | } 21 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/core/templates/folder-name/_form.plush.html.tmpl: -------------------------------------------------------------------------------- 1 | {{ range $p := .opts.Attrs -}} 2 | {{ if eq $p.CommonType "text" -}} 3 | <%= f.TextAreaTag("{{$p.Name.Pascalize}}", {rows: 10}) %> 4 | {{ else -}} 5 | {{ if eq $p.CommonType "bool" -}} 6 | <%= f.CheckboxTag("{{$p.Name.Pascalize}}", {unchecked: false}) %> 7 | {{ else -}} 8 | <%= f.InputTag("{{$p.Name.Pascalize}}") %> 9 | {{ end -}} 10 | {{ end -}} 11 | {{ end -}} 12 | 13 | 14 | -------------------------------------------------------------------------------- /internal/cmd/task/cmd.go: -------------------------------------------------------------------------------- 1 | package task 2 | 3 | import ( 4 | grifts "github.com/gobuffalo/grift/cmd" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | func Cmd() *cobra.Command { 9 | cmd := &cobra.Command{ 10 | Use: "task", 11 | Aliases: []string{"t", "tasks"}, 12 | Short: "Run grift tasks", 13 | DisableFlagParsing: true, 14 | RunE: func(c *cobra.Command, args []string) error { 15 | return grifts.Run("buffalo task", args) 16 | }, 17 | } 18 | 19 | return cmd 20 | } 21 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/existing/actions/user.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | // UserEdit default implementation. 10 | func UserEdit(c buffalo.Context) error { 11 | // custom existing work 12 | return c.Render(http.StatusOK, r.HTML("user/edit.html")) 13 | } 14 | 15 | // UserShow default implementation. 16 | func UserShow(c buffalo.Context) error { 17 | return c.Render(http.StatusOK, r.HTML("user/show.html")) 18 | } 19 | -------------------------------------------------------------------------------- /internal/genny/vcs/templates/ignore.tmpl: -------------------------------------------------------------------------------- 1 | vendor/ 2 | **/*.log 3 | **/*.sqlite 4 | .idea/ 5 | bin/ 6 | tmp/ 7 | node_modules/ 8 | .sass-cache/ 9 | public/assets/ 10 | .vscode/ 11 | .grifter/ 12 | .env 13 | **/.DS_Store 14 | *.pid 15 | coverage 16 | coverage.data 17 | .svn 18 | .console_history 19 | .sass-cache/* 20 | .jhw-cache/ 21 | jhw.* 22 | *.sublime* 23 | dist/ 24 | generated/ 25 | .vendor/ 26 | .pnp.* 27 | .yarn/* 28 | !.yarn/patches 29 | !.yarn/plugins 30 | !.yarn/releases 31 | !.yarn/sdks 32 | !.yarn/versions 33 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_action_with_method.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/users.go", 4 | "contains": [ 5 | "func UsersCreate(c buffalo.Context) error {" 6 | ] 7 | }, 8 | { 9 | "path": "templates/users/update.html", 10 | "absent": true 11 | }, 12 | { 13 | "path": "templates/users/update.plush.html", 14 | "absent": true 15 | }, 16 | { 17 | "path": "actions/app.go", 18 | "contains": [ 19 | "app.POST(\"/users/update\", UsersUpdate)" 20 | ] 21 | } 22 | ] -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/models/models.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/gobuffalo/envy" 7 | "github.com/gobuffalo/pop/v5" 8 | ) 9 | 10 | // DB is a connection to your database to be used 11 | // throughout your application. 12 | var DB *pop.Connection 13 | 14 | func init() { 15 | var err error 16 | env := envy.Get("GO_ENV", "development") 17 | DB, err = pop.Connect(env) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | pop.Debug = env == "development" 22 | } 23 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/models/models.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/gobuffalo/envy" 7 | "github.com/gobuffalo/pop/v5" 8 | ) 9 | 10 | // DB is a connection to your database to be used 11 | // throughout your application. 12 | var DB *pop.Connection 13 | 14 | func init() { 15 | var err error 16 | env := envy.Get("GO_ENV", "development") 17 | DB, err = pop.Connect(env) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | pop.Debug = env == "development" 22 | } 23 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/clean/actions/app.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | var ( 10 | app *buffalo.App 11 | appOnce sync.Once 12 | ) 13 | 14 | func App() *buffalo.App { 15 | appOnce.Do(func() { 16 | app = buffalo.New(buffalo.Options{}) 17 | app.GET("/", HomeHandler) 18 | 19 | app.GET("/user/index", UserIndex) 20 | app.ServeFiles("/", assetsBox) // serve files from the public directory 21 | }) 22 | 23 | return app 24 | } 25 | -------------------------------------------------------------------------------- /internal/plugins/plugdeps/command.go: -------------------------------------------------------------------------------- 1 | package plugdeps 2 | 3 | import "encoding/json" 4 | 5 | // Command is the plugin command you want to control further 6 | type Command struct { 7 | Name string `toml:"name" json:"name"` 8 | Flags []string `toml:"flags,omitempty" json:"flags,omitempty"` 9 | Commands []Command `toml:"command,omitempty" json:"commands,omitempty"` 10 | } 11 | 12 | // String implementation of fmt.Stringer 13 | func (p Command) String() string { 14 | b, _ := json.Marshal(p) 15 | return string(b) 16 | } 17 | -------------------------------------------------------------------------------- /internal/genny/docker/options.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import ( 4 | "github.com/gobuffalo/cli/internal/runtime" 5 | "github.com/gobuffalo/meta" 6 | ) 7 | 8 | type Options struct { 9 | App meta.App `json:"app"` 10 | Version string `json:"version"` 11 | } 12 | 13 | // Validate that options are usuable 14 | func (opts *Options) Validate() error { 15 | if opts.App.IsZero() { 16 | opts.App = meta.New(".") 17 | } 18 | 19 | if len(opts.Version) == 0 { 20 | opts.Version = runtime.Version 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /internal/cmd/setup/setupdescription.txt: -------------------------------------------------------------------------------- 1 | Setup runs through checklist to make sure dependencies are setup correctly. 2 | 3 | Asset Pipeline (if used): 4 | * Runs "npm install" or "yarn install" to install asset dependencies. 5 | 6 | Database (if used): 7 | * Runs "buffalo db create -a" to create databases. 8 | * Runs "buffalo db migrate" to run database migrations. 9 | * Runs "buffalo task db:seed" to seed the database (if the task exists). 10 | 11 | Tests: 12 | * Runs "buffalo test" to confirm the application's tests are running properly. 13 | -------------------------------------------------------------------------------- /internal/genny/build/build_deps_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2/gentest" 7 | "github.com/gobuffalo/meta" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_buildDeps(t *testing.T) { 12 | r := require.New(t) 13 | 14 | opts := &Options{ 15 | Tags: meta.BuildTags{"foo"}, 16 | } 17 | 18 | run := gentest.NewRunner() 19 | r.NoError(run.WithNew(buildDeps(opts))) 20 | r.NoError(run.Run()) 21 | 22 | res := run.Results() 23 | r.Len(res.Commands, 0) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/models/models_test.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/packr/v2" 7 | "github.com/gobuffalo/suite" 8 | ) 9 | 10 | type ModelSuite struct { 11 | *suite.Model 12 | } 13 | 14 | func Test_ModelSuite(t *testing.T) { 15 | model, err := suite.NewModelWithFixtures(packr.New("app:models:test:fixtures", "../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ModelSuite{ 21 | Model: model, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/vendor/models_test.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/packr/v2" 7 | "github.com/gobuffalo/suite" 8 | ) 9 | 10 | type ModelSuite struct { 11 | *suite.Model 12 | } 13 | 14 | func Test_ModelSuite(t *testing.T) { 15 | model, err := suite.NewModelWithFixtures(packr.New("app:models:test:fixtures", "../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ModelSuite{ 21 | Model: model, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/models/models_test.go: -------------------------------------------------------------------------------- 1 | package models 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/packr/v2" 7 | "github.com/gobuffalo/suite" 8 | ) 9 | 10 | type ModelSuite struct { 11 | *suite.Model 12 | } 13 | 14 | func Test_ModelSuite(t *testing.T) { 15 | model, err := suite.NewModelWithFixtures(packr.New("app:models:test:fixtures", "../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ModelSuite{ 21 | Model: model, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/templates/_flash.plush.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= for (k, messages) in flash { %> 4 | <%= for (msg) in messages { %> 5 | 11 | <% } %> 12 | <% } %> 13 |
14 |
15 | -------------------------------------------------------------------------------- /internal/genny/info/options.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/gobuffalo/clara/v2/genny/rx" 7 | "github.com/gobuffalo/meta" 8 | ) 9 | 10 | // Options for the info generator 11 | type Options struct { 12 | App meta.App 13 | Out rx.Writer 14 | } 15 | 16 | // Validate that options are usuable 17 | func (opts *Options) Validate() error { 18 | if opts.App.IsZero() { 19 | opts.App = meta.New(".") 20 | } 21 | if opts.Out.Writer == nil { 22 | opts.Out = rx.NewWriter(os.Stdout) 23 | } 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/actions/actions_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/packr/v2" 7 | "github.com/gobuffalo/suite" 8 | ) 9 | 10 | type ActionSuite struct { 11 | *suite.Action 12 | } 13 | 14 | func Test_ActionSuite(t *testing.T) { 15 | action, err := suite.NewActionWithFixtures(App(), packr.New("Test_ActionSuite", "../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ActionSuite{ 21 | Action: action, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/actions/actions_test.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/packr/v2" 7 | "github.com/gobuffalo/suite" 8 | ) 9 | 10 | type ActionSuite struct { 11 | *suite.Action 12 | } 13 | 14 | func Test_ActionSuite(t *testing.T) { 15 | action, err := suite.NewActionWithFixtures(App(), packr.New("Test_ActionSuite", "../fixtures")) 16 | if err != nil { 17 | t.Fatal(err) 18 | } 19 | 20 | as := &ActionSuite{ 21 | Action: action, 22 | } 23 | suite.Run(t, as) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/standard/actions/resource-name.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | type {{.opts.Name.Resource}}Resource struct{ 10 | buffalo.Resource 11 | } 12 | 13 | {{ range $a := .actions }} 14 | // {{$a.Pascalize}} default implementation. 15 | func (v {{$.opts.Name.Resource}}Resource) {{$a.Pascalize}}(c buffalo.Context) error { 16 | return c.Render(http.StatusOK, r.String("{{$.opts.Model.Proper}}#{{$a.Pascalize}}")) 17 | } 18 | {{ end }} 19 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_nested_api.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/admin_planes.go", 4 | "contains": [ 5 | "type AdminPlanesResource struct", 6 | "func (v AdminPlanesResource)", 7 | "tx.Find(plane, c.Param(\"admin_plane_id\"))" 8 | ] 9 | }, 10 | { 11 | "path": "actions/admin_planes_test.go", 12 | "contains": [ 13 | "package actions", 14 | "Test_AdminPlanesResource_List" 15 | ] 16 | }, 17 | { 18 | "path": "locales/admin/planes.en-us.yaml", 19 | "absent": true 20 | } 21 | ] -------------------------------------------------------------------------------- /internal/cmd/setup/cmd.go: -------------------------------------------------------------------------------- 1 | package setup 2 | 3 | import ( 4 | "github.com/spf13/cobra" 5 | ) 6 | 7 | func Cmd() *cobra.Command { 8 | cmd := &cobra.Command{ 9 | Use: "setup", 10 | Short: "Setup a newly created, or recently checked out application.", 11 | Long: setupLongDescription, 12 | RunE: runE, 13 | } 14 | 15 | cmd.Flags().BoolVarP(&setupOptions.verbose, "verbose", "v", false, "run with verbose output") 16 | cmd.Flags().BoolVarP(&setupOptions.dropDatabases, "drop", "d", false, "drop existing databases") 17 | 18 | return cmd 19 | } 20 | -------------------------------------------------------------------------------- /internal/cmd/version/version.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | 7 | "github.com/gobuffalo/cli/internal/runtime" 8 | "github.com/sirupsen/logrus" 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | func run(c *cobra.Command, args []string) { 13 | if !jsonOutput { 14 | logrus.Infof("Buffalo version is: %s", runtime.Version) 15 | return 16 | } 17 | 18 | build := runtime.BuildInfo{} 19 | build.Version = runtime.Version 20 | 21 | enc := json.NewEncoder(os.Stderr) 22 | enc.SetIndent("", " ") 23 | enc.Encode(build) 24 | } 25 | -------------------------------------------------------------------------------- /internal/genny/actions/_fixtures/outputs/multi/actions/app.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/gobuffalo/buffalo" 7 | ) 8 | 9 | var ( 10 | app *buffalo.App 11 | appOnce sync.Once 12 | ) 13 | 14 | func App() *buffalo.App { 15 | appOnce.Do(func() { 16 | app = buffalo.New(buffalo.Options{}) 17 | app.GET("/", HomeHandler) 18 | 19 | app.GET("/user/show", UserShow) 20 | app.GET("/user/edit", UserEdit) 21 | app.ServeFiles("/", assetsBox) // serve files from the public directory 22 | }) 23 | 24 | return app 25 | } 26 | -------------------------------------------------------------------------------- /internal/genny/fix/tools.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | // InstallTools installs required tools like the pop plugin 11 | func InstallTools(opts *Options) genny.RunFn { 12 | return func(r *genny.Runner) error { 13 | fmt.Println("~~~ Installing required tools ~~~") 14 | 15 | if opts.App.WithPop { 16 | if err := r.Exec(exec.Command("go", "install", "github.com/gobuffalo/buffalo-pop/v3@latest")); err != nil { 17 | return err 18 | } 19 | } 20 | 21 | return nil 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /internal/cmd/generate/resource_use_model.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/admins.go", 4 | "contains": [ 5 | "users := &models.Users{}" 6 | ] 7 | }, 8 | { 9 | "path": "models/admin.go", 10 | "absent": true 11 | }, 12 | { 13 | "path": "models/admin_test.go", 14 | "absent": true 15 | }, 16 | { 17 | "path": "migrations/*_create_admins.up.fizz", 18 | "absent": true 19 | }, 20 | { 21 | "path": "migrations/*_create_admins.down.fizz", 22 | "absent": true 23 | } 24 | ] -------------------------------------------------------------------------------- /internal/cmd/destroy/destroy_resource_all.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/ouches.go", 4 | "absent": true 5 | }, 6 | { 7 | "path": "actions/ouches_test.go", 8 | "absent": true 9 | }, 10 | { 11 | "path": "actions/app.go", 12 | "!contains": [ 13 | "app.Resource(\"/ouches\", OuchesResource{})" 14 | ] 15 | }, 16 | { 17 | "path": "locales/ouches.en-us.yaml", 18 | "absent": true 19 | }, 20 | { 21 | "path": "models/ouch.go", 22 | "absent": true 23 | }, 24 | { 25 | "path": "models/ouch_test.go", 26 | "absent": true 27 | } 28 | ] -------------------------------------------------------------------------------- /internal/genny/resource/templates/core/templates/folder-name/edit.plush.html.tmpl: -------------------------------------------------------------------------------- 1 |
2 |

Edit {{.opts.Model.Proper}}

3 |
4 | 5 | <%= formFor({{.opts.Model.VarCaseSingle}}, {action: {{.opts.Name.VarCaseSingle}}Path({ {{.opts.Name.ParamID}}: {{.opts.Model.VarCaseSingle}}.ID }), method: "PUT"}) { %> 6 | <%= partial("{{.folder}}/form.html") %> 7 | <%= linkTo({{.opts.Name.VarCaseSingle}}Path({ {{.opts.Name.ParamID}}: {{.opts.Model.VarCaseSingle}}.ID }), {class: "btn btn-warning", "data-confirm": "Are you sure?", body: "Cancel"}) %> 8 | <% } %> 9 | -------------------------------------------------------------------------------- /internal/cmd/plugins/cache.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "github.com/gobuffalo/cli/internal/cmd/plugins/internal/cache" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | // cacheCmd represents the cache command 9 | var cacheCmd = &cobra.Command{ 10 | Use: "cache", 11 | Short: "commands for managing the plugins cache", 12 | RunE: func(cmd *cobra.Command, args []string) error { 13 | return cache.ListCmd.RunE(cmd, args) 14 | }, 15 | } 16 | 17 | func init() { 18 | cacheCmd.AddCommand(cache.CleanCmd) 19 | cacheCmd.AddCommand(cache.ListCmd) 20 | cacheCmd.AddCommand(cache.BuildCmd) 21 | } 22 | -------------------------------------------------------------------------------- /internal/defaults/defaults.go: -------------------------------------------------------------------------------- 1 | package defaults 2 | 3 | func String(s1, s2 string) string { 4 | if s1 == "" { 5 | return s2 6 | } 7 | return s1 8 | } 9 | 10 | func Int(i1, i2 int) int { 11 | if i1 == 0 { 12 | return i2 13 | } 14 | return i1 15 | } 16 | 17 | func Int64(i1, i2 int64) int64 { 18 | if i1 == 0 { 19 | return i2 20 | } 21 | return i1 22 | } 23 | 24 | func Float32(i1, i2 float32) float32 { 25 | if i1 == 0.0 { 26 | return i2 27 | } 28 | return i1 29 | } 30 | 31 | func Float64(i1, i2 float64) float64 { 32 | if i1 == 0.0 { 33 | return i2 34 | } 35 | return i1 36 | } 37 | -------------------------------------------------------------------------------- /internal/cmd/version/cmd.go: -------------------------------------------------------------------------------- 1 | package version 2 | 3 | import "github.com/spf13/cobra" 4 | 5 | // jsonOutput for the version command 6 | var jsonOutput bool = false 7 | 8 | func Cmd() *cobra.Command { 9 | cmd := &cobra.Command{ 10 | Use: "version", 11 | Short: "Print the version information", 12 | Run: run, 13 | // needed to override the root level pre-run func 14 | PersistentPreRunE: func(c *cobra.Command, args []string) error { 15 | return nil 16 | }, 17 | } 18 | 19 | cmd.Flags().BoolVar(&jsonOutput, "json", false, "Print information in json format") 20 | 21 | return cmd 22 | } 23 | -------------------------------------------------------------------------------- /internal/genny/ci/templates/dot-travis.yml.tmpl: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - "1.11.x" 5 | 6 | env: 7 | - GO_ENV=test 8 | 9 | {{ if eq .opts.DBType "postgres" -}} 10 | services: 11 | - postgresql 12 | {{- end }} 13 | 14 | before_script: 15 | {{- if eq .opts.DBType "postgres" }} 16 | - psql -c 'create database {{.opts.App.Name.File}}_test;' -U postgres 17 | {{- end }} 18 | - mkdir -p $TRAVIS_BUILD_DIR/public/assets 19 | 20 | go_import_path: {{.opts.App.PackagePkg}} 21 | 22 | install: 23 | - go get github.com/gobuffalo/buffalo/buffalo 24 | - go mod download 25 | 26 | script: buffalo test 27 | -------------------------------------------------------------------------------- /internal/genny/info/pkg.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "io" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | func pkgChecks(opts *Options, fsys fs.FS) genny.RunFn { 11 | return func(r *genny.Runner) error { 12 | for _, x := range []string{"go.mod"} { 13 | f, err := fsys.Open(x) 14 | if err != nil { 15 | return nil 16 | } 17 | s, err := io.ReadAll(f) 18 | if err != nil { 19 | return err 20 | } 21 | opts.Out.Header("\nBuffalo: " + x) 22 | _, err = opts.Out.Write(s) 23 | if err != nil { 24 | return err 25 | } 26 | } 27 | return nil 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /internal/genny/build/transform_main.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "strings" 5 | "sync" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | func transformMain(opts *Options) genny.RunFn { 11 | if opts.rollback == nil { 12 | opts.rollback = &sync.Map{} 13 | } 14 | return func(r *genny.Runner) error { 15 | f, err := r.FindFile("cmd/app/main.go") 16 | if err != nil { 17 | return err 18 | } 19 | 20 | opts.rollback.Store(f.Name(), f.String()) 21 | s := strings.Replace(f.String(), "func main()", "func originalMain()", -1) 22 | f = genny.NewFileS(f.Name(), s) 23 | return r.File(f) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_nested_model_name_api.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/admin_users.go", 4 | "contains": [ 5 | "type AdminUsersResource struct", 6 | "func (v AdminUsersResource)" 7 | ] 8 | }, 9 | { 10 | "path": "actions/admin_users_test.go", 11 | "contains": [ 12 | "package actions", 13 | "Test_AdminUsersResource_List" 14 | ] 15 | }, 16 | { 17 | "path": "locales/admin/users.en-us.yaml", 18 | "absent": true 19 | }, 20 | { 21 | "path": "models/admin_user.go", 22 | "contains": [ 23 | "type AdminUser struct" 24 | ] 25 | } 26 | ] -------------------------------------------------------------------------------- /internal/cmd/fix/fix.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "os/signal" 7 | 8 | "github.com/gobuffalo/cli/internal/genny/fix" 9 | "github.com/gobuffalo/genny/v2" 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | // run all compatible checks 14 | func RunE(cmd *cobra.Command, args []string) error { 15 | ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) 16 | defer cancel() 17 | 18 | opts := &fix.Options{ 19 | YesToAll: yesToAll, 20 | } 21 | 22 | run := genny.WetRunner(ctx) 23 | if err := run.WithNew(fix.New(opts)); err != nil { 24 | return err 25 | } 26 | return run.Run() 27 | } 28 | -------------------------------------------------------------------------------- /internal/genny/add/add.go: -------------------------------------------------------------------------------- 1 | package add 2 | 3 | import ( 4 | "bytes" 5 | 6 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | // New add plugin to the config file 11 | func New(opts *Options) (*genny.Generator, error) { 12 | g := genny.New() 13 | 14 | if err := opts.Validate(); err != nil { 15 | return g, err 16 | } 17 | 18 | bb := &bytes.Buffer{} 19 | plugs := plugdeps.New() 20 | plugs.Add(opts.Plugins...) 21 | if err := plugs.Encode(bb); err != nil { 22 | return g, err 23 | } 24 | 25 | g.File(genny.NewFile(plugdeps.ConfigPath(opts.App), bb)) 26 | return g, nil 27 | } 28 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_action_all.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/comments.go", 4 | "contains": [ 5 | "func CommentsShow(c buffalo.Context) error {", 6 | "func CommentsEdit(c buffalo.Context) error {", 7 | "comments/edit.html", 8 | "comments/show.html" 9 | ] 10 | }, 11 | { 12 | "path": "actions/app.go", 13 | "contains": [ 14 | "app.GET(\"/comments/show\", CommentsShow)", 15 | "app.GET(\"/comments/edit\", CommentsEdit)" 16 | ] 17 | }, 18 | { 19 | "path": "templates/comments/show.plush.html", 20 | "contains": [ 21 | "

Comments#Show

" 22 | ] 23 | } 24 | ] -------------------------------------------------------------------------------- /internal/cmd/plugins/encode.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "bytes" 5 | 6 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 7 | "github.com/gobuffalo/genny/v2" 8 | "github.com/gobuffalo/meta" 9 | ) 10 | 11 | // NewEncodePluginsRunner will return a runner that will encode the plugins file 12 | func NewEncodePluginsRunner(app meta.App, plugs *plugdeps.Plugins) func(r *genny.Runner) error { 13 | return func(r *genny.Runner) error { 14 | p := plugdeps.ConfigPath(app) 15 | bb := &bytes.Buffer{} 16 | if err := plugs.Encode(bb); err != nil { 17 | return err 18 | } 19 | 20 | return r.File(genny.NewFile(p, bb)) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /internal/genny/mail/options.go: -------------------------------------------------------------------------------- 1 | package mail 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gobuffalo/flect/name" 7 | "github.com/gobuffalo/meta" 8 | ) 9 | 10 | // Options needed to create a new mailer 11 | type Options struct { 12 | App meta.App `json:"app"` 13 | Name name.Ident `json:"name"` 14 | SkipInit bool `json:"skip_init"` 15 | } 16 | 17 | // Validate options are useful 18 | func (opts *Options) Validate() error { 19 | if opts.App.IsZero() { 20 | opts.App = meta.New(".") 21 | } 22 | 23 | if len(opts.Name.String()) == 0 { 24 | return fmt.Errorf("you must supply a name for your mailer") 25 | } 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /internal/genny/ci/templates/dot-gitlab-ci-no-pop.yml.tmpl: -------------------------------------------------------------------------------- 1 | before_script: 2 | - mkdir -p public/assets 3 | - go get -u github.com/gobuffalo/buffalo/buffalo 4 | - go mod download 5 | 6 | stages: 7 | - test 8 | 9 | .test-vars: &test-vars 10 | variables: 11 | GO_ENV: "test" 12 | 13 | # Golang version choice helper 14 | .use-golang-image: &use-golang-latest 15 | image: golang:latest 16 | 17 | .use-golang-image: &use-golang-1-15 18 | image: golang:1.15 19 | 20 | test: 21 | # Change to "<<: *use-golang-latest" to use the latest Go version 22 | <<: *use-golang-1-15 23 | <<: *test-vars 24 | stage: test 25 | script: 26 | - buffalo test 27 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_action_existing.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/comments.go", 4 | "contains": [ 5 | "func CommentsShow(c buffalo.Context) error {", 6 | "func CommentsEdit(c buffalo.Context) error {", 7 | "func CommentsDestroy(c buffalo.Context) error {", 8 | "comments/edit.html", 9 | "comments/destroy.html", 10 | "comments/show.html" 11 | ] 12 | }, 13 | { 14 | "path": "actions/app.go", 15 | "contains": [ 16 | "app.GET(\"/comments/destroy\", CommentsDestroy)", 17 | "app.GET(\"/comments/edit\", CommentsEdit)", 18 | "app.GET(\"/comments/show\", CommentsShow)" 19 | ] 20 | } 21 | ] -------------------------------------------------------------------------------- /internal/genny/docker/docker_test.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2/gentest" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func Test_New(t *testing.T) { 11 | r := require.New(t) 12 | 13 | g, err := New(&Options{}) 14 | r.NoError(err) 15 | 16 | run := gentest.NewRunner() 17 | r.NoError(run.With(g)) 18 | r.NoError(run.Run()) 19 | 20 | res := run.Results() 21 | r.Len(res.Commands, 0) 22 | r.Len(res.Files, 2) 23 | 24 | f := res.Files[0] 25 | r.Equal(".dockerignore", f.Name()) 26 | 27 | f = res.Files[1] 28 | r.Equal("Dockerfile", f.Name()) 29 | r.Contains(f.String(), "multi-stage") 30 | } 31 | -------------------------------------------------------------------------------- /internal/genny/fix/options.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "github.com/gobuffalo/meta" 5 | ) 6 | 7 | // Options for building a Buffalo application 8 | type Options struct { 9 | App meta.App `json:"app"` 10 | // YesToAll will be used by the command to skip the confirmation 11 | // and perform all implied destroy operations 12 | YesToAll bool `json:"yes_to_all"` 13 | 14 | warnings []string 15 | } 16 | 17 | // Validate that options are usuable 18 | func (opts *Options) Validate() error { 19 | if opts.App.IsZero() { 20 | opts.App = meta.New(".") 21 | } 22 | 23 | if opts.warnings == nil { 24 | opts.warnings = make([]string, 0) 25 | } 26 | 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /internal/genny/info/config.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "io/fs" 5 | "path" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | func configs(opts *Options, fsys fs.FS) genny.RunFn { 11 | return func(r *genny.Runner) error { 12 | return fs.WalkDir(fsys, ".", func(p string, d fs.DirEntry, err error) error { 13 | if err != nil { 14 | return err 15 | } 16 | 17 | if d.IsDir() { 18 | return nil 19 | } 20 | 21 | b, err := fs.ReadFile(fsys, p) 22 | if err != nil { 23 | return err 24 | } 25 | opts.Out.Header("Buffalo: " + path.Join("config", p)) 26 | _, err = opts.Out.Write(append(b, '\n')) 27 | return err 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /internal/cmd/info/cmd.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "github.com/gobuffalo/clara/v2/genny/rx" 5 | "github.com/gobuffalo/cli/internal/genny/info" 6 | "github.com/gobuffalo/meta" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | var ( 11 | app = meta.New(".") 12 | infoOptions = struct { 13 | Clara *rx.Options 14 | Info *info.Options 15 | }{ 16 | Clara: &rx.Options{ 17 | App: app, 18 | }, 19 | Info: &info.Options{ 20 | App: app, 21 | }, 22 | } 23 | ) 24 | 25 | func Cmd() *cobra.Command { 26 | cmd := &cobra.Command{ 27 | Use: "info", 28 | Short: "Print diagnostic information (useful for debugging)", 29 | RunE: runE, 30 | } 31 | 32 | return cmd 33 | } 34 | -------------------------------------------------------------------------------- /internal/genny/info/pkg_test.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "bytes" 5 | "os" 6 | "testing" 7 | 8 | "github.com/gobuffalo/clara/v2/genny/rx" 9 | "github.com/gobuffalo/genny/v2/gentest" 10 | "github.com/gobuffalo/meta" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func Test_pkgChecks(t *testing.T) { 15 | r := require.New(t) 16 | 17 | bb := &bytes.Buffer{} 18 | 19 | run := gentest.NewRunner() 20 | 21 | opts := &Options{ 22 | App: meta.New("."), 23 | Out: rx.NewWriter(bb), 24 | } 25 | 26 | run.WithRun(pkgChecks(opts, os.DirFS("../info/templates/module"))) 27 | r.NoError(run.Run()) 28 | 29 | res := bb.String() 30 | r.Contains(res, "Buffalo: go.mod") 31 | } 32 | -------------------------------------------------------------------------------- /internal/cmd/fix/cmd.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gobuffalo/cli/internal/runtime" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | // yesToAll will be used by the command to skip the confirmation 11 | // and perform all implied destroy operations 12 | var yesToAll bool = false 13 | 14 | func Cmd() *cobra.Command { 15 | cmd := &cobra.Command{ 16 | Use: "fix", 17 | Aliases: []string{"update"}, 18 | Short: fmt.Sprintf("Attempt to fix a Buffalo application's API to match version %s", runtime.Version), 19 | RunE: RunE, 20 | } 21 | 22 | cmd.Flags().BoolVarP(&yesToAll, "y", "y", false, "update all without asking for confirmation") 23 | 24 | return cmd 25 | } 26 | -------------------------------------------------------------------------------- /internal/genny/fix/apptoml.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "bytes" 5 | "path/filepath" 6 | 7 | "github.com/BurntSushi/toml" 8 | "github.com/gobuffalo/genny/v2" 9 | ) 10 | 11 | func EncodeAppToml(opts *Options) genny.RunFn { 12 | return func(r *genny.Runner) error { 13 | p := "config/buffalo-app.toml" 14 | if _, err := r.FindFile(p); err == nil { 15 | return nil 16 | } 17 | dir := genny.NewDir(filepath.Dir(p), 0o755) 18 | if err := r.File(dir); err != nil { 19 | return err 20 | } 21 | 22 | bb := &bytes.Buffer{} 23 | if err := toml.NewEncoder(bb).Encode(opts.App); err != nil { 24 | return err 25 | } 26 | 27 | f := genny.NewFile(p, bb) 28 | return r.File(f) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /internal/genny/info/app_test.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | "github.com/gobuffalo/clara/v2/genny/rx" 8 | "github.com/gobuffalo/genny/v2/gentest" 9 | "github.com/gobuffalo/meta" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test_appDetails(t *testing.T) { 14 | r := require.New(t) 15 | 16 | run := gentest.NewRunner() 17 | 18 | app := meta.New(".") 19 | app.Bin = "paris elephant chevrolet" 20 | 21 | bb := &bytes.Buffer{} 22 | 23 | opts := &Options{ 24 | App: app, 25 | Out: rx.NewWriter(bb), 26 | } 27 | 28 | run.WithRun(appDetails(opts)) 29 | 30 | r.NoError(run.Run()) 31 | 32 | r.Contains(bb.String(), "paris elephant chevrolet") 33 | } 34 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_plural.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/cars.go", 4 | "contains": [ 5 | "func (v CarsResource) List(c buffalo.Context) error {", 6 | "func (v CarsResource) Destroy(c buffalo.Context) error {", 7 | "type CarsResource struct {" 8 | ] 9 | }, 10 | { 11 | "path": "actions/app.go", 12 | "contains": [ 13 | "app.Resource(\"/cars\", CarsResource{})" 14 | ] 15 | }, 16 | { 17 | "path": "actions/cars_test.go", 18 | "contains": [ 19 | "func (as *ActionSuite) Test_CarsResource_List", 20 | "func (as *ActionSuite) Test_CarsResource_Show", 21 | "func (as *ActionSuite) Test_CarsResource_Create" 22 | ] 23 | } 24 | ] -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_singular.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/users.go", 4 | "contains": [ 5 | "func (v UsersResource) List(c buffalo.Context) error {", 6 | "func (v UsersResource) Destroy(c buffalo.Context) error {", 7 | "type UsersResource struct {" 8 | ] 9 | }, 10 | { 11 | "path": "actions/app.go", 12 | "contains": [ 13 | "app.Resource(\"/users\", UsersResource{})" 14 | ] 15 | }, 16 | { 17 | "path": "actions/users_test.go", 18 | "contains": [ 19 | "func (as *ActionSuite) Test_UsersResource_List", 20 | "func (as *ActionSuite) Test_UsersResource_Show", 21 | "func (as *ActionSuite) Test_UsersResource_Create" 22 | ] 23 | } 24 | ] -------------------------------------------------------------------------------- /internal/genny/build/templates/migrations/dot-pop-tmp.md: -------------------------------------------------------------------------------- 1 | hi! i'm just here to ensure that `buffalo build` has a `./migrations` if the application has pop. 2 | 3 | unfortunately, i'm just temporary, so as much as i would love to meet you, and trust me, i really would (i've heard good things), i have to be going. :( 4 | 5 | if you're seeing me in your application, then something horribly, horribly wrong happened during `buffalo build`, or you ran it with the `-d` flag. :) 6 | 7 | regardless, should you come across me laying about, feel free and delete me. it's ok. it won't hurt. well, it might if you use the `-f` flag, i don't know. 8 | 9 | i'll leave you with these famous parting words: 10 | 11 | >> So long, and thanks for all the fish 12 | -------------------------------------------------------------------------------- /internal/genny/refresh/refresh_test.go: -------------------------------------------------------------------------------- 1 | package refresh 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/gobuffalo/flect/name" 8 | "github.com/gobuffalo/genny/v2" 9 | "github.com/gobuffalo/meta" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test_New(t *testing.T) { 14 | r := require.New(t) 15 | 16 | app := meta.New(".") 17 | app.Name = name.New("foo") 18 | g, err := New(&Options{app}) 19 | r.NoError(err) 20 | 21 | run := genny.DryRunner(context.Background()) 22 | r.NoError(run.With(g)) 23 | r.NoError(run.Run()) 24 | 25 | res := run.Results() 26 | r.Len(res.Commands, 0) 27 | r.Len(res.Files, 1) 28 | 29 | f := res.Files[0] 30 | r.Contains(f.String(), "binary_name: foo-build") 31 | } 32 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/templates/application.plush.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Buffalo - Coke 7 | <%= stylesheetTag("application.css") %> 8 | 9 | 10 | "> 11 | 12 | 13 | 14 |
15 | <%= partial("flash.html") %> 16 | <%= yield %> 17 |
18 | 19 | <%= javascriptTag("application.js") %> 20 | 21 | 22 | -------------------------------------------------------------------------------- /internal/cmd/destroy/action.go: -------------------------------------------------------------------------------- 1 | package destroy 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gobuffalo/flect" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | // actionCmd destroys passed action file 11 | var actionCmd = &cobra.Command{ 12 | Use: "action [name]", 13 | // Example: "resource cars", 14 | Aliases: []string{"a"}, 15 | Short: "Destroy action files", 16 | RunE: func(cmd *cobra.Command, args []string) error { 17 | if len(args) == 0 { 18 | return fmt.Errorf("you need to provide a valid action file name in order to destroy it") 19 | } 20 | 21 | name := args[0] 22 | 23 | // Generated actions keep the same name (not plural). 24 | fileName := flect.Underscore(name) 25 | return removeActions(fileName) 26 | }, 27 | } 28 | -------------------------------------------------------------------------------- /internal/plugins/command.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | // Command that the plugin supplies 4 | type Command struct { 5 | // Name "foo" 6 | Name string `json:"name"` 7 | // UseCommand "bar" 8 | UseCommand string `json:"use_command"` 9 | // BuffaloCommand "generate" 10 | BuffaloCommand string `json:"buffalo_command"` 11 | // Description "generates a foo" 12 | Description string `json:"description,omitempty"` 13 | Aliases []string `json:"aliases,omitempty"` 14 | Binary string `json:"-"` 15 | Flags []string `json:"flags,omitempty"` 16 | // Filters events to listen to ("" or "*") is all events 17 | ListenFor string `json:"listen_for,omitempty"` 18 | } 19 | 20 | // Commands is a slice of Command 21 | type Commands []Command 22 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/options_test.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/flect/name" 7 | "github.com/gobuffalo/meta" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_Options_Validate(t *testing.T) { 12 | r := require.New(t) 13 | 14 | app := meta.New(".") 15 | app.Name = name.New("buffalo") 16 | 17 | opts := &Options{ 18 | App: app, 19 | } 20 | 21 | err := opts.Validate() 22 | r.Error(err) 23 | 24 | opts.App.Name = name.New("coke") 25 | err = opts.Validate() 26 | r.NoError(err) 27 | 28 | opts.App.Name = name.New("#$(@#)") 29 | err = opts.Validate() 30 | r.Error(err) 31 | 32 | opts.App.Name = name.New("coke") 33 | err = opts.Validate() 34 | r.NoError(err) 35 | } 36 | -------------------------------------------------------------------------------- /internal/cmd/plugins/available.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "github.com/gobuffalo/cli/internal/plugins/plugcmds" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | // Available used to manage all of the available commands 9 | // for the plugins 10 | var Available = plugcmds.NewAvailable() 11 | 12 | // PluginsCmd is the "root" command for the plugin features. 13 | var PluginsCmd = &cobra.Command{ 14 | Use: "plugins", 15 | Short: "tools for working with buffalo plugins", 16 | } 17 | 18 | func init() { 19 | PluginsCmd.AddCommand(addCmd) 20 | PluginsCmd.AddCommand(listCmd) 21 | PluginsCmd.AddCommand(removeCmd) 22 | PluginsCmd.AddCommand(installCmd) 23 | PluginsCmd.AddCommand(cacheCmd) 24 | 25 | Available.ListenFor("buffalo:setup:.+", Listen) 26 | } 27 | -------------------------------------------------------------------------------- /internal/genny/actions/options.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gobuffalo/meta" 7 | ) 8 | 9 | // Options for the actions generator 10 | type Options struct { 11 | App meta.App 12 | Name string 13 | Actions []string 14 | Method string 15 | SkipTemplates bool 16 | } 17 | 18 | // Validate that options are usuable 19 | func (opts *Options) Validate() error { 20 | if len(opts.Name) == 0 { 21 | return fmt.Errorf("you must provide a name") 22 | } 23 | 24 | if len(opts.Actions) == 0 { 25 | return fmt.Errorf("you must provide at least one action name") 26 | } 27 | 28 | if opts.App.IsZero() { 29 | opts.App = meta.New(".") 30 | } 31 | 32 | if len(opts.Method) == 0 { 33 | opts.Method = "GET" 34 | } 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/genny/info/config_test.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "bytes" 5 | "os" 6 | "testing" 7 | 8 | "github.com/gobuffalo/clara/v2/genny/rx" 9 | "github.com/gobuffalo/genny/v2/gentest" 10 | "github.com/gobuffalo/meta" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func Test_configs(t *testing.T) { 15 | r := require.New(t) 16 | 17 | run := gentest.NewRunner() 18 | 19 | bb := &bytes.Buffer{} 20 | 21 | app := meta.New(".") 22 | opts := &Options{ 23 | App: app, 24 | Out: rx.NewWriter(bb), 25 | } 26 | 27 | run.WithRun(configs(opts, os.DirFS("../info/templates/config"))) 28 | r.NoError(run.Run()) 29 | 30 | x := bb.String() 31 | r.Contains(x, "Buffalo: config/buffalo-app.toml\napp") 32 | r.Contains(x, "Buffalo: config/buffalo-plugins.toml\nplugins") 33 | } 34 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/actions/widgets_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_WidgetsResource_List() { 4 | as.Fail("Not Implemented!") 5 | } 6 | 7 | func (as *ActionSuite) Test_WidgetsResource_Show() { 8 | as.Fail("Not Implemented!") 9 | } 10 | 11 | func (as *ActionSuite) Test_WidgetsResource_Create() { 12 | as.Fail("Not Implemented!") 13 | } 14 | 15 | func (as *ActionSuite) Test_WidgetsResource_Update() { 16 | as.Fail("Not Implemented!") 17 | } 18 | 19 | func (as *ActionSuite) Test_WidgetsResource_Destroy() { 20 | as.Fail("Not Implemented!") 21 | } 22 | 23 | func (as *ActionSuite) Test_WidgetsResource_New() { 24 | as.Fail("Not Implemented!") 25 | } 26 | 27 | func (as *ActionSuite) Test_WidgetsResource_Edit() { 28 | as.Fail("Not Implemented!") 29 | } 30 | -------------------------------------------------------------------------------- /internal/genny/vcs/options.go: -------------------------------------------------------------------------------- 1 | package vcs 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/gobuffalo/meta" 8 | ) 9 | 10 | // Available VCS implementations 11 | var Available = []string{"git", "bzr", "none"} 12 | 13 | // Options for VCS generator 14 | type Options struct { 15 | App meta.App 16 | Provider string 17 | } 18 | 19 | // Validate that options are usuable 20 | func (opts *Options) Validate() error { 21 | if opts.App.IsZero() { 22 | opts.App = meta.New(".") 23 | } 24 | 25 | var found bool 26 | for _, a := range Available { 27 | if opts.Provider == a { 28 | found = true 29 | break 30 | } 31 | } 32 | if !found { 33 | return fmt.Errorf("unknown provider %q expecting one of %s", opts.Provider, strings.Join(Available, ", ")) 34 | } 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/genny/info/app.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | func appDetails(opts *Options) genny.RunFn { 11 | return func(r *genny.Runner) error { 12 | opts.Out.Header("Buffalo: Application Details") 13 | rv := reflect.ValueOf(opts.App) 14 | rt := rv.Type() 15 | 16 | var lines [][]string 17 | for i := 0; i < rt.NumField(); i++ { 18 | f := rt.Field(i) 19 | if !rv.FieldByName(f.Name).CanInterface() { 20 | continue 21 | } 22 | 23 | v := rv.FieldByName(f.Name).Interface() 24 | line := []string{f.Name, fmt.Sprint(v)} 25 | 26 | lines = append(lines, line) 27 | } 28 | err := opts.Out.Tabs(lines) 29 | if err != nil { 30 | return err 31 | } 32 | return opts.Out.WriteString("\n") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /internal/genny/fix/docker_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2" 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/gobuffalo/meta" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_FixDocker(t *testing.T) { 13 | r := require.New(t) 14 | 15 | run := gentest.NewRunner() 16 | r.NoError(run.File(genny.NewFileS("Dockerfile", "my custom Dockerfile"))) 17 | 18 | opts := &Options{ 19 | App: meta.App{ 20 | Root: ".", 21 | WithDocker: true, 22 | }, 23 | YesToAll: true, 24 | } 25 | g := FixDocker(opts) 26 | run.WithRun(g) 27 | 28 | r.NoError(run.Run()) 29 | results := run.Results() 30 | 31 | f, err := results.Find("Dockerfile") 32 | r.NoError(err) 33 | 34 | r.Contains(f.String(), "multi-stage Dockerfile") 35 | } 36 | -------------------------------------------------------------------------------- /internal/genny/build/transform_main_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/cli/internal/genny/newapp/web" 7 | "github.com/gobuffalo/cli/internal/genny/testrunner" 8 | "github.com/gobuffalo/genny/v2/gentest" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_transformMain(t *testing.T) { 13 | r := require.New(t) 14 | 15 | ref, err := testrunner.WebApp(&web.Options{}) 16 | r.NoError(err) 17 | main, err := ref.Disk.Find("cmd/app/main.go") 18 | r.NoError(err) 19 | 20 | run := gentest.NewRunner() 21 | run.Disk.Add(main) 22 | 23 | opts := &Options{} 24 | run.WithRun(transformMain(opts)) 25 | r.NoError(run.Run()) 26 | 27 | res := run.Results() 28 | r.Len(res.Files, 1) 29 | f := res.Files[0] 30 | r.Contains(f.String(), "func originalMain()") 31 | } 32 | -------------------------------------------------------------------------------- /internal/cmd/plugins/internal/cache/list.go: -------------------------------------------------------------------------------- 1 | package cache 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/gobuffalo/cli/internal/plugins" 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | // ListCmd displays the contents of the plugin cache 13 | var ListCmd = &cobra.Command{ 14 | Use: "list", 15 | Short: "displays the contents of the plugin cache", 16 | RunE: func(cmd *cobra.Command, args []string) error { 17 | b, err := os.ReadFile(plugins.CachePath) 18 | if err != nil { 19 | return err 20 | } 21 | m := map[string]interface{}{} 22 | err = json.Unmarshal(b, &m) 23 | if err != nil { 24 | return err 25 | } 26 | is, err := json.MarshalIndent(m, "", " ") 27 | if err != nil { 28 | return err 29 | } 30 | 31 | fmt.Println(string(is)) 32 | return nil 33 | }, 34 | } 35 | -------------------------------------------------------------------------------- /Dockerfile.slim.build: -------------------------------------------------------------------------------- 1 | FROM golang:1.18-alpine 2 | 3 | EXPOSE 3000 4 | 5 | RUN apk add --no-cache --upgrade apk-tools \ 6 | && apk add --no-cache bash curl openssl git build-base nodejs npm sqlite sqlite-dev mysql-client vim postgresql libpq postgresql-contrib libc6-compat 7 | 8 | # Installing linter 9 | RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh \ 10 | | sh -s -- -b $(go env GOPATH)/bin v1.24.0 11 | 12 | # Installing Yarn 13 | RUN npm i -g --no-progress yarn \ 14 | && yarn config set yarn-offline-mirror /npm-packages-offline-cache \ 15 | && yarn config set yarn-offline-mirror-pruning true 16 | 17 | # Installing buffalo binary 18 | COPY buffalo /go/bin/buffalo 19 | 20 | WORKDIR / 21 | RUN go install github.com/gobuffalo/buffalo-pop/v3@latest 22 | 23 | RUN mkdir /src 24 | WORKDIR /src -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/actions/admin_widgets_test.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | func (as *ActionSuite) Test_AdminWidgetsResource_List() { 4 | as.Fail("Not Implemented!") 5 | } 6 | 7 | func (as *ActionSuite) Test_AdminWidgetsResource_Show() { 8 | as.Fail("Not Implemented!") 9 | } 10 | 11 | func (as *ActionSuite) Test_AdminWidgetsResource_Create() { 12 | as.Fail("Not Implemented!") 13 | } 14 | 15 | func (as *ActionSuite) Test_AdminWidgetsResource_Update() { 16 | as.Fail("Not Implemented!") 17 | } 18 | 19 | func (as *ActionSuite) Test_AdminWidgetsResource_Destroy() { 20 | as.Fail("Not Implemented!") 21 | } 22 | 23 | func (as *ActionSuite) Test_AdminWidgetsResource_New() { 24 | as.Fail("Not Implemented!") 25 | } 26 | 27 | func (as *ActionSuite) Test_AdminWidgetsResource_Edit() { 28 | as.Fail("Not Implemented!") 29 | } 30 | -------------------------------------------------------------------------------- /internal/genny/actions/build_templates.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "fmt" 5 | "io/fs" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | func buildTemplates(pres *presenter) genny.RunFn { 11 | return func(r *genny.Runner) error { 12 | sub, err := fs.Sub(templates, "templates") 13 | if err != nil { 14 | return err 15 | } 16 | 17 | f, err := fs.ReadFile(sub, "view.plush.html.tmpl") 18 | if err != nil { 19 | return err 20 | } 21 | for _, a := range pres.Actions { 22 | pres.Data["action"] = a 23 | fn := fmt.Sprintf("templates/%s/%s.plush.html.tmpl", pres.Name.Folder(), a.File()) 24 | xf := genny.NewFileB(fn, f) 25 | xf, err = transform(pres, xf) 26 | if err != nil { 27 | return err 28 | } 29 | if err := r.File(xf); err != nil { 30 | return err 31 | } 32 | } 33 | return nil 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_mailer.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "mailers/mailers.go", 4 | "contains": [ 5 | "github.com/gobuffalo/buffalo/mail", 6 | "smtp, err = mail.NewSMTPSender(host, port, user, password)" 7 | ], 8 | "!contains": [ 9 | "github.com/gobuffalo/x/mail" 10 | ] 11 | }, 12 | { 13 | "path": "templates/mail/layout.plush.html", 14 | "contains": [ 15 | "

templates/mailers/layout.plush.html

" 16 | ] 17 | }, 18 | { 19 | "path": "mailers/welcome_email.go", 20 | "contains": [ 21 | "err := m.AddBody(r.HTML(\"welcome_email.html\"), render.Data{})" 22 | ] 23 | }, 24 | { 25 | "path": "templates/mail/welcome_email.plush.html", 26 | "contains": [ 27 | "

Welcome Email

", 28 | "

../templates/mail/welcome_email.plush.html

" 29 | ] 30 | } 31 | ] -------------------------------------------------------------------------------- /internal/cmd/version/version_test.go: -------------------------------------------------------------------------------- 1 | // +build integration 2 | 3 | package version 4 | 5 | import ( 6 | "testing" 7 | 8 | "github.com/gobuffalo/cli/internal/testhelpers" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestVersion(t *testing.T) { 13 | r := require.New(t) 14 | r.NoError(testhelpers.EnsureBuffaloCMD(t)) 15 | 16 | tt := []struct { 17 | name string 18 | args []string 19 | content string 20 | }{ 21 | {name: "Plain text", args: []string{"version"}, content: "version"}, 22 | {name: "JSON", args: []string{"version", "--json"}, content: "\"version\":"}, 23 | } 24 | 25 | for _, tc := range tt { 26 | t.Run(tc.name, func(t *testing.T) { 27 | rx := require.New(t) 28 | out, err := testhelpers.RunBuffaloCMD(t, tc.args) 29 | 30 | rx.NoError(err) 31 | rx.Contains(out, tc.content) 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/templates/application.plush.html.tmpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Buffalo - {{ .opts.App.Name.Titleize }} 7 | {{- if not .opts.App.WithWebpack }} 8 | <%= stylesheetTag("buffalo.css") %> 9 | {{- end }} 10 | <%= stylesheetTag("application.css") %> 11 | 12 | 13 | "> 14 | 15 | 16 | 17 |
18 | <%= partial("flash.html") %> 19 | <%= yield %> 20 |
21 | 22 | <%= javascriptTag("application.js") %> 23 | 24 | 25 | -------------------------------------------------------------------------------- /internal/cmd/plugins.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "sync" 5 | 6 | "github.com/gobuffalo/cli/internal/plugins" 7 | "github.com/sirupsen/logrus" 8 | "github.com/spf13/cobra" 9 | ) 10 | 11 | var _plugs plugins.List 12 | var initPlugsOnce sync.Once 13 | 14 | func plugs() plugins.List { 15 | initPlugsOnce.Do(func() { 16 | var err error 17 | _plugs, err = plugins.Available() 18 | if err == nil { 19 | return 20 | } 21 | 22 | _plugs = plugins.List{} 23 | logrus.Errorf("error loading plugins %s", err) 24 | }) 25 | return _plugs 26 | } 27 | 28 | func decorate(name string, cmd *cobra.Command) { 29 | pugs := plugs() 30 | for _, c := range pugs[name] { 31 | // FIXME: why register all plugins as anywhere command? 32 | //anywhereCommands = append(anywhereCommands, c.Name) 33 | cc := plugins.Decorate(c) 34 | cmd.AddCommand(cc) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /internal/genny/build/templates/a/aa.go.plush: -------------------------------------------------------------------------------- 1 | package a 2 | 3 | import ( 4 | "log" 5 | 6 | <%= if (opts.Environment != "development") { %> 7 | "github.com/gobuffalo/envy" 8 | <% } %> 9 | "github.com/gobuffalo/flect" 10 | "github.com/gobuffalo/pop/v6" 11 | ) 12 | 13 | func init() { 14 | <%= if (opts.Environment != "development") { %> 15 | if err := envy.MustSet("GO_ENV", "<%= opts.Environment %>"); err != nil { 16 | log.Fatal(err) 17 | } 18 | <% } %> 19 | 20 | databaseYml() 21 | 22 | r, err := FS().Open("inflections.json") 23 | if err != nil { 24 | return 25 | } 26 | 27 | if err := flect.LoadInflections(r); err != nil { 28 | log.Fatal(err) 29 | } 30 | } 31 | 32 | func databaseYml() { 33 | r, err := FS().Open("database.yml") 34 | if err != nil { 35 | return 36 | } 37 | 38 | if err := pop.LoadFrom(r); err != nil { 39 | log.Fatal(err) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/templates/actions/render.go.tmpl: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "{{ .opts.App.PackagePkg }}/public" 5 | "{{ .opts.App.PackagePkg }}/templates" 6 | 7 | "github.com/gobuffalo/buffalo/render" 8 | ) 9 | 10 | var r *render.Engine 11 | 12 | func init() { 13 | r = render.New(render.Options{ 14 | // HTML layout to be used for all HTML requests: 15 | HTMLLayout: "application.plush.html", 16 | 17 | // fs.FS containing templates 18 | TemplatesFS: templates.FS(), 19 | 20 | // fs.FS containing assets 21 | AssetsFS: public.FS(), 22 | 23 | // Add template helpers here: 24 | Helpers: render.Helpers{ 25 | // for non-bootstrap form helpers uncomment the lines 26 | // below and import "github.com/gobuffalo/helpers/forms" 27 | // forms.FormKey: forms.Form, 28 | // forms.FormForKey: forms.FormFor, 29 | }, 30 | }) 31 | } 32 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_nested_model_name_web.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/admin_users.go", 4 | "contains": [ 5 | "type AdminUsersResource struct", 6 | "func (v AdminUsersResource)" 7 | ] 8 | }, 9 | { 10 | "path": "actions/admin_users_test.go", 11 | "contains": [ 12 | "package actions", 13 | "Test_AdminUsersResource_List" 14 | ] 15 | }, 16 | { 17 | "path": "locales/admin/users.en-us.yaml", 18 | "contains": [ 19 | "translation: \"AdminUser was successfully created.\"" 20 | ] 21 | }, 22 | { 23 | "path": "templates/admin/users/_form.plush.html", 24 | "contains": [ 25 | "" 26 | ] 27 | }, 28 | { 29 | "path": "models/admin_user.go", 30 | "contains": [ 31 | "type AdminUser struct" 32 | ] 33 | } 34 | ] -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/actions/render.go: -------------------------------------------------------------------------------- 1 | package actions 2 | 3 | import ( 4 | "github.com/gobuffalo/buffalo/render" 5 | "github.com/gobuffalo/packr/v2" 6 | ) 7 | 8 | var ( 9 | r *render.Engine 10 | assetsBox = packr.New("app:assets", "../public") 11 | ) 12 | 13 | func init() { 14 | r = render.New(render.Options{ 15 | // HTML layout to be used for all HTML requests: 16 | HTMLLayout: "application.plush.html", 17 | 18 | // Box containing all of the templates: 19 | TemplatesBox: packr.New("app:templates", "../templates"), 20 | AssetsBox: assetsBox, 21 | 22 | // Add template helpers here: 23 | Helpers: render.Helpers{ 24 | // for non-bootstrap form helpers uncomment the lines 25 | // below and import "github.com/gobuffalo/helpers/forms" 26 | // forms.FormKey: forms.Form, 27 | // forms.FormForKey: forms.FormFor, 28 | }, 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /internal/genny/mail/init/templates/mailers/mailers.go.tmpl: -------------------------------------------------------------------------------- 1 | package mailers 2 | 3 | import ( 4 | "log" 5 | 6 | "{{ .opts.App.PackagePkg }}/templates" 7 | 8 | "github.com/gobuffalo/buffalo/mail" 9 | "github.com/gobuffalo/buffalo/render" 10 | "github.com/gobuffalo/envy" 11 | ) 12 | 13 | var ( 14 | smtp mail.Sender 15 | r *render.Engine 16 | ) 17 | 18 | func init() { 19 | // Pulling config from the env. 20 | port := envy.Get("SMTP_PORT", "1025") 21 | host := envy.Get("SMTP_HOST", "localhost") 22 | user := envy.Get("SMTP_USER", "") 23 | password := envy.Get("SMTP_PASSWORD", "") 24 | 25 | var err error 26 | smtp, err = mail.NewSMTPSender(host, port, user, password) 27 | 28 | if err != nil { 29 | log.Fatal(err) 30 | } 31 | 32 | r = render.New(render.Options{ 33 | HTMLLayout: "mail/layout.plush.html", 34 | TemplatesFS: templates.FS(), 35 | Helpers: render.Helpers{}, 36 | }) 37 | } 38 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | release: 4 | types: 5 | - published 6 | 7 | jobs: 8 | release: 9 | name: Release 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Set up Go 13 | uses: actions/setup-go@v3 14 | with: 15 | go-version: 1.18 16 | id: go 17 | 18 | - name: Checkout Code 19 | uses: actions/checkout@v3 20 | 21 | - name: Log in to Docker Hub 22 | uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 23 | with: 24 | username: ${{ secrets.DOCKER_USERNAME }} 25 | password: ${{ secrets.DOCKER_PASSWORD }} 26 | 27 | - name: Run GoReleaser 28 | uses: goreleaser/goreleaser-action@v3 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }} 31 | with: 32 | version: latest 33 | args: release --rm-dist 34 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/fixtures/sample.toml.tmpl: -------------------------------------------------------------------------------- 1 | [[scenario]] 2 | name = "lots of widgets" 3 | 4 | [[scenario.table]] 5 | name = "widgets" 6 | 7 | [[scenario.table.row]] 8 | id = "<%= uuidNamed("widget") %>" 9 | name = "This is widget #1" 10 | body = "some widget body" 11 | created_at = "<%= now() %>" 12 | updated_at = "<%= now() %>" 13 | 14 | [[scenario.table.row]] 15 | id = "<%= uuid() %>" 16 | name = "This is widget #2" 17 | body = "some widget body" 18 | created_at = "<%= now() %>" 19 | updated_at = "<%= now() %>" 20 | 21 | [[scenario.table]] 22 | name = "users" 23 | 24 | [[scenario.table.row]] 25 | id = "<%= uuid() %>" 26 | name = "Mark Bates" 27 | admin = true 28 | age = 41 29 | widget_id = "<%= uuidNamed("widget") %>" 30 | created_at = "<%= now() %>" 31 | updated_at = "<%= now() %>" 32 | 33 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/fixtures/sample.toml: -------------------------------------------------------------------------------- 1 | [[scenario]] 2 | name = "lots of widgets" 3 | 4 | [[scenario.table]] 5 | name = "widgets" 6 | 7 | [[scenario.table.row]] 8 | id = "<%= uuidNamed("widget") %>" 9 | name = "This is widget #1" 10 | body = "some widget body" 11 | created_at = "<%= now() %>" 12 | updated_at = "<%= now() %>" 13 | 14 | [[scenario.table.row]] 15 | id = "<%= uuid() %>" 16 | name = "This is widget #2" 17 | body = "some widget body" 18 | created_at = "<%= now() %>" 19 | updated_at = "<%= now() %>" 20 | 21 | [[scenario.table]] 22 | name = "users" 23 | 24 | [[scenario.table.row]] 25 | id = "<%= uuid() %>" 26 | name = "Mark Bates" 27 | admin = true 28 | age = 41 29 | widget_id = "<%= uuidNamed("widget") %>" 30 | created_at = "<%= now() %>" 31 | updated_at = "<%= now() %>" 32 | 33 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/fixtures/sample.toml: -------------------------------------------------------------------------------- 1 | [[scenario]] 2 | name = "lots of widgets" 3 | 4 | [[scenario.table]] 5 | name = "widgets" 6 | 7 | [[scenario.table.row]] 8 | id = "<%= uuidNamed("widget") %>" 9 | name = "This is widget #1" 10 | body = "some widget body" 11 | created_at = "<%= now() %>" 12 | updated_at = "<%= now() %>" 13 | 14 | [[scenario.table.row]] 15 | id = "<%= uuid() %>" 16 | name = "This is widget #2" 17 | body = "some widget body" 18 | created_at = "<%= now() %>" 19 | updated_at = "<%= now() %>" 20 | 21 | [[scenario.table]] 22 | name = "users" 23 | 24 | [[scenario.table.row]] 25 | id = "<%= uuid() %>" 26 | name = "Mark Bates" 27 | admin = true 28 | age = 41 29 | widget_id = "<%= uuidNamed("widget") %>" 30 | created_at = "<%= now() %>" 31 | updated_at = "<%= now() %>" 32 | 33 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/templates/widgets/show.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

Widget Details

3 | 4 |
5 | <%= linkTo(widgetsPath(), {class: "btn btn-info"}) { %> 6 | Back to all Widgets 7 | <% } %> 8 | <%= linkTo(editWidgetPath({ widget_id: widget.ID }), {class: "btn btn-warning", body: "Edit"}) %> 9 | <%= linkTo(widgetPath({ widget_id: widget.ID }), {class: "btn btn-danger", "data-method": "DELETE", "data-confirm": "Are you sure?", body: "Destroy"}) %> 10 |
11 |
12 | 13 | 23 | -------------------------------------------------------------------------------- /internal/genny/grift/grift.go: -------------------------------------------------------------------------------- 1 | package grift 2 | 3 | import ( 4 | "text/template" 5 | 6 | "github.com/gobuffalo/genny/v2" 7 | "github.com/gobuffalo/genny/v2/gogen" 8 | ) 9 | 10 | // New generator to create a grift task 11 | func New(opts *Options) (*genny.Generator, error) { 12 | g := genny.New() 13 | 14 | if err := opts.Validate(); err != nil { 15 | return g, err 16 | } 17 | 18 | data := map[string]interface{}{ 19 | "opts": opts, 20 | } 21 | t := gogen.TemplateTransformer(data, template.FuncMap{}) 22 | g.Transformer(t) 23 | 24 | g.RunFn(func(r *genny.Runner) error { 25 | return genFile(r, opts) 26 | }) 27 | return g, nil 28 | } 29 | 30 | func genFile(r *genny.Runner, opts *Options) error { 31 | header := tmplHeader 32 | path := "grifts/" + opts.Name.File(".go.tmpl").String() 33 | if f, err := r.FindFile(path); err == nil { 34 | header = f.String() 35 | } 36 | f := genny.NewFileS(path, header+tmplBody) 37 | return r.File(f) 38 | } 39 | -------------------------------------------------------------------------------- /internal/cmd/test/test_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_CutArg(t *testing.T) { 9 | tests := []struct { 10 | arg string 11 | args []string 12 | expected []string 13 | }{ 14 | {"b", []string{"a", "b", "c"}, []string{"a", "c"}}, 15 | {"--is-not-in-args", []string{"a", "b", "c"}, []string{"a", "b", "c"}}, 16 | {"--foo", []string{"--foo", "--bar", "--baz"}, []string{"--bar", "--baz"}}, 17 | {"--force-migrations", []string{"./actions/", "--force-migrations"}, []string{"./actions/"}}, 18 | {"--force-migrations", []string{"./actions/", "--force-migrations", "-m", "Test_HomeHandler"}, []string{"./actions/", "-m", "Test_HomeHandler"}}, 19 | } 20 | 21 | for _, tt := range tests { 22 | result := cutArg(tt.arg, tt.args) 23 | if !reflect.DeepEqual(result, tt.expected) { 24 | t.Errorf("got %s, want %s when cutting %s from %s", result, tt.expected, tt.arg, tt.args) 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /internal/genny/grift/templates.go: -------------------------------------------------------------------------------- 1 | package grift 2 | 3 | const tmplHeader = `package grifts 4 | 5 | import ( 6 | . "github.com/gobuffalo/grift/grift" 7 | ) 8 | ` 9 | 10 | const tmplBody = ` 11 | {{ if .opts.Namespaced }} 12 | {{ range $index, $element := .opts.Parts }} 13 | {{ if $.opts.Last $element}} 14 | Desc("{{$element.File}}", "Task Description") 15 | Add("{{$element.File}}", func(c *Context) error{ 16 | return nil 17 | }) 18 | {{ else }} 19 | {{if eq $index 0}} 20 | var _ = Namespace("{{$element.File}}", func(){ 21 | {{ else }} 22 | Namespace("{{$element.File}}", func(){ 23 | {{end}} 24 | {{ end }} 25 | {{ end }} 26 | {{ range $index, $element := .opts.Parts }} 27 | {{ if $index }} }) {{ end }} 28 | {{ end }} 29 | {{ else }} 30 | var _ = Desc("{{.opts.Name.File}}", "Task Description") 31 | var _ = Add("{{.opts.Name.File}}", func(c *Context) error { 32 | return nil 33 | }) 34 | {{ end }}` 35 | -------------------------------------------------------------------------------- /internal/testhelpers/tmpfolder.go: -------------------------------------------------------------------------------- 1 | package testhelpers 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | ) 7 | 8 | // RunWithinTempFolder runs the given function on a temporary folder 9 | // and returns to the original working directory afterwards. 10 | func RunWithinTempFolder(t *testing.T, fn func(t *testing.T)) { 11 | t.Helper() 12 | 13 | original, err := os.Getwd() 14 | if err != nil { 15 | t.Fatal(err) 16 | } 17 | 18 | t.Cleanup(func() { 19 | err := os.Chdir(original) 20 | if err != nil { 21 | t.Logf("error moving back to the original folder: %s", err) 22 | } 23 | }) 24 | 25 | dir, err := os.MkdirTemp("", "buffalo-integration-test-*") 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | t.Cleanup(func() { 31 | if err := os.RemoveAll(dir); err != nil { 32 | t.Logf("failed to delete temporary directory: %s", dir) 33 | } 34 | }) 35 | 36 | err = os.Chdir(dir) 37 | if err != nil { 38 | t.Fatal(err) 39 | } 40 | 41 | fn(t) 42 | } 43 | -------------------------------------------------------------------------------- /internal/cmd/plugins/listen.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/gobuffalo/cli/internal/genny/plugins/install" 7 | "github.com/gobuffalo/cli/internal/plugins" 8 | "github.com/gobuffalo/events" 9 | "github.com/gobuffalo/genny/v2" 10 | ) 11 | 12 | // Listen is listener for plugin events pipeline 13 | func Listen(e events.Event) error { 14 | if e.Kind != "buffalo:setup:started" { 15 | return nil 16 | } 17 | 18 | run := genny.WetRunner(context.Background()) 19 | 20 | opts := &install.Options{} 21 | gg, err := install.New(opts) 22 | if err != nil { 23 | return err 24 | } 25 | run.WithGroup(gg) 26 | payload := e.Payload 27 | payload["plugins"] = opts.Plugins 28 | events.EmitPayload(plugins.EvtSetupStarted, payload) 29 | if err := run.Run(); err != nil { 30 | events.EmitError(plugins.EvtSetupErr, err, payload) 31 | return err 32 | } 33 | events.EmitPayload(plugins.EvtSetupFinished, payload) 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /internal/genny/fix/tools_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/gobuffalo/meta" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_InstallTools_WithOutPop(t *testing.T) { 13 | r := require.New(t) 14 | 15 | run := gentest.NewRunner() 16 | 17 | run.WithRun(InstallTools(&Options{})) 18 | 19 | r.NoError(run.Run()) 20 | 21 | results := run.Results() 22 | r.Len(results.Commands, 0) 23 | } 24 | 25 | func Test_InstallTools_WithPop(t *testing.T) { 26 | r := require.New(t) 27 | 28 | run := gentest.NewRunner() 29 | 30 | run.WithRun(InstallTools(&Options{ 31 | App: meta.App{ 32 | WithPop: true, 33 | }, 34 | })) 35 | 36 | r.NoError(run.Run()) 37 | 38 | results := run.Results() 39 | r.Len(results.Commands, 1) 40 | c := results.Commands[0] 41 | r.Equal("go install github.com/gobuffalo/buffalo-pop/v3@latest", strings.Join(c.Args, " ")) 42 | } 43 | -------------------------------------------------------------------------------- /internal/genny/add/options.go: -------------------------------------------------------------------------------- 1 | package add 2 | 3 | import ( 4 | "errors" 5 | "os" 6 | 7 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 8 | "github.com/gobuffalo/meta" 9 | ) 10 | 11 | // Options container for passing needed info for 12 | // adding plugins to the config file. 13 | type Options struct { 14 | App meta.App 15 | Plugins []plugdeps.Plugin 16 | } 17 | 18 | // Validate that options are usuable 19 | func (opts *Options) Validate() error { 20 | if opts.App.IsZero() { 21 | pwd, err := os.Getwd() 22 | if err != nil { 23 | return err 24 | } 25 | opts.App = meta.New(pwd) 26 | } 27 | if len(opts.Plugins) == 0 { 28 | plugs, err := plugdeps.List(opts.App) 29 | if err != nil && !errors.Is(err, plugdeps.ErrMissingConfig) { 30 | return err 31 | } 32 | opts.Plugins = plugs.List() 33 | } 34 | 35 | for i, p := range opts.Plugins { 36 | p.Tags = opts.App.BuildTags("", p.Tags...) 37 | opts.Plugins[i] = p 38 | } 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /internal/genny/testrunner/generators.go: -------------------------------------------------------------------------------- 1 | package testrunner 2 | 3 | import ( 4 | "github.com/gobuffalo/cli/internal/genny/newapp/api" 5 | "github.com/gobuffalo/cli/internal/genny/newapp/web" 6 | "github.com/gobuffalo/genny/v2" 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | ) 9 | 10 | func WebApp(opts *web.Options) (*genny.Runner, error) { 11 | gg, err := web.New(opts) 12 | if err != nil { 13 | return nil, err 14 | } 15 | return newApp(gg) 16 | } 17 | 18 | func ApiApp(opts *api.Options) (*genny.Runner, error) { 19 | gg, err := api.New(opts) 20 | if err != nil { 21 | return nil, err 22 | } 23 | return newApp(gg) 24 | } 25 | 26 | func newApp(gg *genny.Group) (*genny.Runner, error) { 27 | run := gentest.NewRunner() 28 | run.WithGroup(gg) 29 | if err := run.Run(); err != nil { 30 | return nil, err 31 | } 32 | 33 | runner := gentest.NewRunner() 34 | for _, f := range run.Results().Files { 35 | runner.Disk.Add(f) 36 | } 37 | return runner, nil 38 | } 39 | -------------------------------------------------------------------------------- /internal/genny/resource/models.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "os/exec" 5 | 6 | "github.com/gobuffalo/flect/name" 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | func modelCommand(model name.Ident, opts *Options) *exec.Cmd { 11 | args := opts.Attrs.Slice() 12 | mn := model.Singularize().Underscore().String() 13 | args = append([]string{"pop", "g", "model", mn}, args...) 14 | 15 | if opts.SkipMigration { 16 | args = append(args, "--skip-migration") 17 | } 18 | 19 | return exec.Command("buffalo-pop", args...) 20 | } 21 | 22 | func installPop(opts *Options) genny.RunFn { 23 | return func(r *genny.Runner) error { 24 | if opts.SkipModel { 25 | return nil 26 | } 27 | if _, err := r.LookPath("buffalo-pop"); err != nil { 28 | c := exec.Command("go", "get", "github.com/gobuffalo/buffalo-pop/v3") 29 | if err := r.Exec(c); err != nil { 30 | return err 31 | } 32 | } 33 | return r.Exec(modelCommand(name.New(opts.Model), opts)) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /internal/runtime/build.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | // BuildInfo holds information about the build 10 | type BuildInfo struct { 11 | Version string `json:"version"` 12 | Time time.Time `json:"-"` 13 | } 14 | 15 | // String implements fmt.String 16 | func (b BuildInfo) String() string { 17 | return fmt.Sprintf("%s (%s)", b.Version, b.Time) 18 | } 19 | 20 | var build = BuildInfo{ 21 | Version: "", 22 | Time: time.Time{}, 23 | } 24 | 25 | // Build returns the information about the current build 26 | // of the application. In development mode this will almost 27 | // always run zero values for BuildInfo. 28 | func Build() BuildInfo { 29 | return build 30 | } 31 | 32 | var so sync.Once 33 | 34 | // SetBuild allows the setting of build information only once. 35 | // This is typically managed by the binary built by `buffalo build`. 36 | func SetBuild(b BuildInfo) { 37 | so.Do(func() { 38 | build = b 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/templates/admin/widgets/show.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

Widget Details

3 | 4 |
5 | <%= linkTo(adminWidgetsPath(), {class: "btn btn-info"}) { %> 6 | Back to all Widgets 7 | <% } %> 8 | <%= linkTo(editAdminWidgetPath({ admin_widget_id: widget.ID }), {class: "btn btn-warning", body: "Edit"}) %> 9 | <%= linkTo(adminWidgetPath({ admin_widget_id: widget.ID }), {class: "btn btn-danger", "data-method": "DELETE", "data-confirm": "Are you sure?", body: "Destroy"}) %> 10 |
11 |
12 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /internal/cmd/dev/cmd.go: -------------------------------------------------------------------------------- 1 | package dev 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/gobuffalo/events" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | // debug flag to enable delve debugging 11 | var debug bool = false 12 | 13 | func Cmd() *cobra.Command { 14 | // Listen to events for event rewrite 15 | events.NamedListen("buffalo:dev", func(e events.Event) { 16 | if strings.HasPrefix(e.Kind, "refresh:") { 17 | e.Kind = strings.Replace(e.Kind, "refresh:", "buffalo:dev:", 1) 18 | events.Emit(e) 19 | } 20 | }) 21 | 22 | // devCmd represents the dev command 23 | cmd := &cobra.Command{ 24 | Use: "dev", 25 | Short: "Run the Buffalo app in 'development' mode", 26 | Long: `Run the Buffalo app in 'development' mode. 27 | This includes rebuilding the application when files change. 28 | This behavior can be changed in .buffalo.dev.yml file.`, 29 | RunE: runE, 30 | } 31 | 32 | cmd.Flags().BoolVarP(&debug, "debug", "d", false, "use delve to debug the app") 33 | 34 | return cmd 35 | } 36 | -------------------------------------------------------------------------------- /internal/genny/vcs/vcs.go: -------------------------------------------------------------------------------- 1 | package vcs 2 | 3 | import ( 4 | "embed" 5 | "fmt" 6 | "os/exec" 7 | 8 | "github.com/gobuffalo/genny/v2" 9 | ) 10 | 11 | //go:embed templates/* 12 | var templates embed.FS 13 | 14 | // New generator for adding VCS to an application 15 | func New(opts *Options) (*genny.Generator, error) { 16 | g := genny.New() 17 | 18 | if err := opts.Validate(); err != nil { 19 | return g, err 20 | } 21 | 22 | if opts.Provider == "none" { 23 | return g, nil 24 | } 25 | 26 | f, err := templates.Open("templates/ignore.tmpl") 27 | if err != nil { 28 | return g, err 29 | } 30 | 31 | p := opts.Provider 32 | n := fmt.Sprintf(".%signore", p) 33 | g.File(genny.NewFile(n, f)) 34 | g.Command(exec.Command(p, "init")) 35 | 36 | args := []string{"add", "."} 37 | if p == "bzr" { 38 | // Ensure Bazaar is as quiet as Git 39 | args = append(args, "-q") 40 | } 41 | g.Command(exec.Command(p, args...)) 42 | g.Command(exec.Command(p, "commit", "-q", "-m", "Initial Commit")) 43 | return g, nil 44 | } 45 | -------------------------------------------------------------------------------- /internal/genny/grift/options.go: -------------------------------------------------------------------------------- 1 | package grift 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/gobuffalo/flect/name" 8 | ) 9 | 10 | // Options for creating a new grift task 11 | type Options struct { 12 | Name name.Ident `json:"name"` 13 | Parts []name.Ident `json:"parts"` 14 | Args []string `json:"args"` 15 | Namespaced bool `json:"namespaced"` 16 | } 17 | 18 | // Last checks if the name is the last of the parts 19 | func (opts Options) Last(n name.Ident) bool { 20 | return opts.Parts[len(opts.Parts)-1].String() == n.String() 21 | } 22 | 23 | // Validate options 24 | func (opts *Options) Validate() error { 25 | if len(opts.Args) == 0 { 26 | return fmt.Errorf("you need to provide a name for the grift task") 27 | } 28 | 29 | opts.Namespaced = strings.Contains(opts.Args[0], ":") 30 | 31 | for _, n := range strings.Split(opts.Args[0], ":") { 32 | opts.Parts = append(opts.Parts, name.New(n)) 33 | } 34 | opts.Name = opts.Parts[len(opts.Parts)-1] 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /internal/cmd/generate/goth.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/auth.go", 4 | "contains": [ 5 | "github.com/markbates/goth/providers/facebook", 6 | "github.com/markbates/goth/providers/twitter", 7 | "github.com/markbates/goth/providers/linkedin", 8 | "github.com/markbates/goth/providers/github", 9 | "FACEBOOK_KEY", 10 | "FACEBOOK_SECRET", 11 | "TWITTER_KEY", 12 | "TWITTER_SECRET", 13 | "GITHUB_KEY", 14 | "GITHUB_SECRET", 15 | "LINKEDIN_KEY", 16 | "LINKEDIN_SECRET" 17 | ], 18 | "!contains": [ 19 | "app := App().Group(\"/auth\")", 20 | "github.com/markbates/goth/providers/yammer", 21 | "buffalo.WrapHandlerFunc(gothic.BeginAuthHandler)" 22 | ] 23 | }, 24 | { 25 | "path": "actions/app.go", 26 | "contains": [ 27 | "auth := app.Group(\"/auth\")", 28 | "auth.GET(\"/{provider}\", buffalo.WrapHandlerFunc(gothic.BeginAuthHandler))", 29 | "auth.GET(\"/{provider}/callback\", AuthCallback)" 30 | ] 31 | } 32 | ] -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18api/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "coke/actions" 5 | "log" 6 | ) 7 | 8 | // main is the starting point for your Buffalo application. 9 | // You can feel free and add to this `main` method, change 10 | // what it does, etc... 11 | // All we ask is that, at some point, you make sure to 12 | // call `app.Serve()`, unless you don't want to start your 13 | // application that is. :) 14 | func main() { 15 | app := actions.App() 16 | if err := app.Serve(); err != nil { 17 | log.Fatal(err) 18 | } 19 | } 20 | 21 | /* 22 | # Notes about `main.go` 23 | 24 | ## SSL Support 25 | 26 | We recommend placing your application behind a proxy, such as 27 | Apache or Nginx and letting them do the SSL heavy lifting 28 | for you. https://gobuffalo.io/en/docs/proxy 29 | 30 | ## Buffalo Build 31 | 32 | When `buffalo build` is run to compile your binary, this `main` 33 | function will be at the heart of that binary. It is expected 34 | that your `main` function will start your application using 35 | the `app.Serve()` method. 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /internal/genny/fix/_fixtures/buffaloPre0_18web/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "coke/actions" 5 | "log" 6 | ) 7 | 8 | // main is the starting point for your Buffalo application. 9 | // You can feel free and add to this `main` method, change 10 | // what it does, etc... 11 | // All we ask is that, at some point, you make sure to 12 | // call `app.Serve()`, unless you don't want to start your 13 | // application that is. :) 14 | func main() { 15 | app := actions.App() 16 | if err := app.Serve(); err != nil { 17 | log.Fatal(err) 18 | } 19 | } 20 | 21 | /* 22 | # Notes about `main.go` 23 | 24 | ## SSL Support 25 | 26 | We recommend placing your application behind a proxy, such as 27 | Apache or Nginx and letting them do the SSL heavy lifting 28 | for you. https://gobuffalo.io/en/docs/proxy 29 | 30 | ## Buffalo Build 31 | 32 | When `buffalo build` is run to compile your binary, this `main` 33 | function will be at the heart of that binary. It is expected 34 | that your `main` function will start your application using 35 | the `app.Serve()` method. 36 | 37 | */ 38 | -------------------------------------------------------------------------------- /internal/genny/build/cleanup.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | "path/filepath" 7 | 8 | "github.com/gobuffalo/genny/v2" 9 | ) 10 | 11 | // Cleanup all of the generated files 12 | func Cleanup(opts *Options) genny.RunFn { 13 | return func(r *genny.Runner) error { 14 | defer os.RemoveAll(filepath.Join(opts.Root, "a")) 15 | 16 | var err error 17 | opts.rollback.Range(func(k, v interface{}) bool { 18 | f := genny.NewFileS(k.(string), v.(string)) 19 | r.Logger.Debugf("Rollback: %s", f.Name()) 20 | if err = r.File(f); err != nil { 21 | return false 22 | } 23 | r.Disk.Remove(f.Name()) 24 | return true 25 | }) 26 | if err != nil { 27 | return err 28 | } 29 | for _, f := range r.Disk.Files() { 30 | if _, keep := opts.keep.Load(f.Name()); keep { 31 | // Keep this file 32 | continue 33 | } 34 | if err := r.Disk.Delete(f.Name()); err != nil { 35 | return err 36 | } 37 | } 38 | if opts.WithBuildDeps { 39 | return r.Exec(exec.Command("go", "mod", "tidy")) 40 | } 41 | return nil 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /internal/genny/plugins/install/options.go: -------------------------------------------------------------------------------- 1 | package install 2 | 3 | import ( 4 | "errors" 5 | "os" 6 | 7 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 8 | "github.com/gobuffalo/meta" 9 | ) 10 | 11 | // Options container for passing needed info for 12 | // installing plugins and adding them to the config file. 13 | type Options struct { 14 | App meta.App 15 | Plugins []plugdeps.Plugin 16 | Tags meta.BuildTags 17 | Vendor bool 18 | } 19 | 20 | // Validate that options are usuable 21 | func (opts *Options) Validate() error { 22 | if opts.App.IsZero() { 23 | pwd, err := os.Getwd() 24 | if err != nil { 25 | return err 26 | } 27 | opts.App = meta.New(pwd) 28 | } 29 | if len(opts.Plugins) == 0 { 30 | plugs, err := plugdeps.List(opts.App) 31 | if err != nil && !errors.Is(err, plugdeps.ErrMissingConfig) { 32 | return err 33 | } 34 | opts.Plugins = plugs.List() 35 | } 36 | 37 | for i, p := range opts.Plugins { 38 | p.Tags = opts.App.BuildTags("", append(opts.Tags, p.Tags...)...) 39 | opts.Plugins[i] = p 40 | } 41 | 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /internal/genny/resource/templates/core/templates/folder-name/show.plush.html.tmpl: -------------------------------------------------------------------------------- 1 |
2 |

{{.opts.Model.Proper}} Details

3 | 4 |
5 | <%= linkTo({{.opts.Name.VarCasePlural}}Path(), {class: "btn btn-info"}) { %> 6 | Back to all {{.opts.Model.Group}} 7 | <% } %> 8 | <%= linkTo(edit{{.opts.Name.Proper}}Path({ {{.opts.Name.ParamID}}: {{.opts.Model.VarCaseSingle}}.ID }), {class: "btn btn-warning", body: "Edit"}) %> 9 | <%= linkTo({{.opts.Name.VarCaseSingle}}Path({ {{.opts.Name.ParamID}}: {{.opts.Model.VarCaseSingle}}.ID }), {class: "btn btn-danger", "data-method": "DELETE", "data-confirm": "Are you sure?", body: "Destroy"}) %> 10 |
11 |
12 | 13 | 14 | 15 | 25 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/cmd/app/main.go.tmpl: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | 6 | "{{ .opts.App.ActionsPkg }}" 7 | ) 8 | 9 | // main is the starting point for your Buffalo application. 10 | // You can feel free and add to this `main` method, change 11 | // what it does, etc... 12 | // All we ask is that, at some point, you make sure to 13 | // call `app.Serve()`, unless you don't want to start your 14 | // application that is. :) 15 | func main() { 16 | app := actions.App() 17 | if err := app.Serve(); err != nil { 18 | log.Fatal(err) 19 | } 20 | } 21 | 22 | /* 23 | # Notes about `main.go` 24 | 25 | ## SSL Support 26 | 27 | We recommend placing your application behind a proxy, such as 28 | Apache or Nginx and letting them do the SSL heavy lifting 29 | for you. https://gobuffalo.io/en/docs/proxy 30 | 31 | ## Buffalo Build 32 | 33 | When `buffalo build` is run to compile your binary, this `main` 34 | function will be at the heart of that binary. It is expected 35 | that your `main` function will start your application using 36 | the `app.Serve()` method. 37 | 38 | */ 39 | -------------------------------------------------------------------------------- /internal/genny/fix/action.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | "github.com/gobuffalo/genny/v2/gogen" 9 | ) 10 | 11 | // ReplaceAppOnce fixes `actions/app.go` to fix the double execution issue. 12 | // it covers https://github.com/gobuffalo/buffalo/issues/1653 and 13 | // https://github.com/gobuffalo/cli/issues/228 14 | func ReplaceAppOnce(opts *Options) genny.RunFn { 15 | return func(r *genny.Runner) error { 16 | fmt.Println("~~~ Apply AppOnce ~~~") 17 | 18 | file, err := r.FindFile("actions/app.go") 19 | if err != nil { 20 | return err 21 | } 22 | 23 | if !strings.Contains(file.String(), "appOnce.Do") { 24 | file, err = gogen.ReplaceBlock(file, "if app == nil {", "}", "appOnce.Do(func() {", "})") 25 | if err != nil { 26 | return err 27 | } 28 | 29 | file, err = gogen.AddGlobal(file, "appOnce sync.Once") 30 | if err != nil { 31 | return err 32 | } 33 | 34 | file, err = gogen.AddImport(file, "sync") 35 | if err != nil { 36 | return err 37 | } 38 | } 39 | 40 | return r.File(file) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /internal/genny/info/info.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | 7 | "github.com/gobuffalo/genny/v2" 8 | ) 9 | 10 | const noBuffalo = "Warning: It seems like it is not a buffalo app. (.buffalo.dev.yml not found)\n\n" 11 | 12 | // New returns a generator that performs buffalo 13 | // related rx checks 14 | func New(opts *Options) (*genny.Generator, error) { 15 | g := genny.New() 16 | 17 | if err := opts.Validate(); err != nil { 18 | return g, err 19 | } 20 | 21 | devFile := filepath.Join(opts.App.Root, ".buffalo.dev.yml") 22 | if _, err := os.Stat(devFile); err != nil { 23 | g.RunFn(func(r *genny.Runner) error { 24 | opts.Out.Header("Buffalo: Application Details") 25 | return opts.Out.WriteString(noBuffalo) 26 | }) 27 | return g, nil 28 | } 29 | 30 | g.RunFn(appDetails(opts)) 31 | 32 | path := filepath.Join(opts.App.Root, "config") 33 | if _, err := os.Stat(path); err == nil { 34 | configFS := os.DirFS(path) 35 | g.RunFn(configs(opts, configFS)) 36 | } 37 | 38 | aFS := os.DirFS(opts.App.Root) 39 | g.RunFn(pkgChecks(opts, aFS)) 40 | 41 | return g, nil 42 | } 43 | -------------------------------------------------------------------------------- /internal/cmd/generate/generate_resource_nested_web.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "actions/admin_planes.go", 4 | "contains": [ 5 | "type AdminPlanesResource struct", 6 | "func (v AdminPlanesResource)", 7 | "tx.Find(plane, c.Param(\"admin_plane_id\"))" 8 | ] 9 | }, 10 | { 11 | "path": "actions/admin_planes_test.go", 12 | "contains": [ 13 | "package actions", 14 | "Test_AdminPlanesResource_List" 15 | ] 16 | }, 17 | { 18 | "path": "locales/admin/planes.en-us.yaml", 19 | "contains": [ 20 | "translation: \"Plane was successfully created.\"" 21 | ] 22 | }, 23 | { 24 | "path": "templates/admin/planes/_form.plush.html", 25 | "contains": [ 26 | "" 27 | ] 28 | }, 29 | { 30 | "path": "templates/admin/planes/index.plush.html", 31 | "contains": [ 32 | "newAdminPlanesPath()" 33 | ] 34 | }, 35 | { 36 | "path": "templates/admin/planes/show.plush.html", 37 | "contains": [ 38 | "editAdminPlanePath({ admin_plane_id: plane.ID })" 39 | ] 40 | } 41 | ] -------------------------------------------------------------------------------- /internal/genny/fix/fix_helpers.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "fmt" 5 | "io/fs" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/gobuffalo/genny/v2" 10 | ) 11 | 12 | func walkDisk(disk *genny.Disk, root string, walkFun filepath.WalkFunc) error { 13 | for _, f := range disk.Files() { 14 | rel, err := filepath.Rel(root, f.Name()) 15 | if err != nil { 16 | err = walkFun(f.Name(), nil, fmt.Errorf("cannot process file %s: %w", f.Name(), err)) 17 | if err != nil { 18 | return err 19 | } 20 | } 21 | 22 | if strings.HasPrefix(rel, "..") { 23 | continue 24 | } 25 | 26 | // skip directories that are not part of the buffalo source tree 27 | for _, prefix := range []string{"vendor", "node_modules", ".git"} { 28 | if strings.HasPrefix(f.Name(), prefix) { 29 | return nil 30 | } 31 | } 32 | 33 | file, ok := f.(fs.File) 34 | if !ok { 35 | return fmt.Errorf("cannot process file %s: cast failed", f.Name()) 36 | } 37 | 38 | info, err := file.Stat() 39 | 40 | err = walkFun(f.Name(), info, err) 41 | if err != nil { 42 | return err 43 | } 44 | } 45 | 46 | return nil 47 | } 48 | -------------------------------------------------------------------------------- /internal/plugins/plugcmds/plug_map_test.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/gobuffalo/mapgen. DO NOT EDIT. 2 | 3 | package plugcmds 4 | 5 | import ( 6 | "sort" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_plugMap(t *testing.T) { 13 | r := require.New(t) 14 | 15 | sm := &plugMap{} 16 | 17 | sm.Store("a", plug{}) 18 | 19 | s, ok := sm.Load("a") 20 | r.True(ok) 21 | r.Equal(plug{}, s) 22 | 23 | s, ok = sm.LoadOrStore("b", plug{}) 24 | r.True(ok) 25 | r.Equal(plug{}, s) 26 | 27 | s, ok = sm.LoadOrStore("b", plug{}) 28 | r.True(ok) 29 | r.Equal(plug{}, s) 30 | 31 | var keys []string 32 | 33 | sm.Range(func(key string, value plug) bool { 34 | keys = append(keys, key) 35 | return true 36 | }) 37 | 38 | sort.Strings(keys) 39 | 40 | r.Equal(sm.Keys(), keys) 41 | 42 | sm.Delete("b") 43 | r.Equal([]string{"a", "b"}, keys) 44 | 45 | sm.Delete("b") 46 | _, ok = sm.Load("b") 47 | r.False(ok) 48 | p := plug{ 49 | BuffaloCommand: "foo", 50 | } 51 | func(m *plugMap) { 52 | m.Store("c", p) 53 | }(sm) 54 | s, ok = sm.Load("c") 55 | r.True(ok) 56 | r.Equal(p, s) 57 | } 58 | -------------------------------------------------------------------------------- /internal/plugins/plugdeps/plugins_test.go: -------------------------------------------------------------------------------- 1 | package plugdeps 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "strings" 7 | "testing" 8 | 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_Plugins_Encode(t *testing.T) { 13 | r := require.New(t) 14 | 15 | bb := &bytes.Buffer{} 16 | 17 | plugs := New() 18 | plugs.Add(pop, heroku, local) 19 | 20 | r.NoError(plugs.Encode(bb)) 21 | 22 | fmt.Println(bb.String()) 23 | act := strings.TrimSpace(bb.String()) 24 | exp := strings.TrimSpace(eToml) 25 | r.Equal(exp, act) 26 | } 27 | 28 | func Test_Plugins_Decode(t *testing.T) { 29 | r := require.New(t) 30 | 31 | plugs := New() 32 | r.NoError(plugs.Decode(strings.NewReader(eToml))) 33 | 34 | names := []string{"buffalo-hello.rb", "buffalo-heroku", "buffalo-pop"} 35 | list := plugs.List() 36 | 37 | r.Len(list, len(names)) 38 | for i, p := range list { 39 | r.Equal(names[i], p.Binary) 40 | } 41 | } 42 | 43 | func Test_Plugins_Remove(t *testing.T) { 44 | r := require.New(t) 45 | 46 | plugs := New() 47 | plugs.Add(pop, heroku) 48 | r.Len(plugs.List(), 2) 49 | plugs.Remove(pop) 50 | r.Len(plugs.List(), 1) 51 | } 52 | -------------------------------------------------------------------------------- /internal/genny/resource/options.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/gobuffalo/attrs" 8 | "github.com/gobuffalo/meta" 9 | ) 10 | 11 | // Options for generating a new resource 12 | type Options struct { 13 | App meta.App `json:"app"` 14 | Name string `json:"name"` 15 | Model string `json:"model"` 16 | SkipMigration bool `json:"skip_migration"` 17 | SkipModel bool `json:"skip_model"` 18 | SkipTemplates bool `json:"skip_templates"` 19 | Attrs attrs.Attrs `json:"props"` 20 | } 21 | 22 | // Validate that options are usuable 23 | func (opts *Options) Validate() error { 24 | if opts.App.IsZero() { 25 | opts.App = meta.New(".") 26 | } 27 | 28 | if len(opts.Name) == 0 { 29 | return fmt.Errorf("you must provide a name") 30 | } 31 | 32 | if len(opts.Model) == 0 { 33 | opts.Model = opts.Name 34 | } 35 | 36 | if strings.Contains(opts.Model, "/") { 37 | parts := strings.Split(opts.Model, "/") 38 | opts.Model = parts[len(parts)-1] 39 | } 40 | 41 | if opts.App.AsAPI { 42 | opts.SkipTemplates = true 43 | } 44 | 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /internal/defaults/defaults_test.go: -------------------------------------------------------------------------------- 1 | package defaults 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/stretchr/testify/assert" 7 | ) 8 | 9 | func Test_String(t *testing.T) { 10 | a := assert.New(t) 11 | 12 | a.Equal(String("", "foo"), "foo") 13 | a.Equal(String("bar", "foo"), "bar") 14 | var s string 15 | a.Equal(String(s, "foo"), "foo") 16 | } 17 | 18 | func Test_Int(t *testing.T) { 19 | a := assert.New(t) 20 | 21 | a.Equal(Int(0, 1), 1) 22 | a.Equal(Int(2, 1), 2) 23 | var s int 24 | a.Equal(Int(s, 1), 1) 25 | } 26 | 27 | func Test_Int64(t *testing.T) { 28 | a := assert.New(t) 29 | 30 | a.Equal(Int64(0, 1), int64(1)) 31 | a.Equal(Int64(2, 1), int64(2)) 32 | var s int64 33 | a.Equal(Int64(s, 1), int64(1)) 34 | } 35 | 36 | func Test_Float32(t *testing.T) { 37 | a := assert.New(t) 38 | 39 | a.Equal(Float32(0, 1), float32(1)) 40 | a.Equal(Float32(2, 1), float32(2)) 41 | var s float32 42 | a.Equal(Float32(s, 1), float32(1)) 43 | } 44 | 45 | func Test_Float64(t *testing.T) { 46 | a := assert.New(t) 47 | 48 | a.Equal(Float64(0, 1), float64(1)) 49 | a.Equal(Float64(2, 1), float64(2)) 50 | var s float64 51 | a.Equal(Float64(s, 1), float64(1)) 52 | } 53 | -------------------------------------------------------------------------------- /internal/genny/fix/apptoml_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2" 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/gobuffalo/meta" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_EncodeAppToml(t *testing.T) { 13 | r := require.New(t) 14 | 15 | run := gentest.NewRunner() 16 | 17 | g := EncodeAppToml(&Options{ 18 | App: meta.Named("coke", "."), 19 | }) 20 | run.WithRun(g) 21 | 22 | r.NoError(run.Run()) 23 | 24 | results := run.Results() 25 | f, err := results.Find("config/buffalo-app.toml") 26 | r.NoError(err) 27 | 28 | r.Contains(f.String(), `name = "coke"`) 29 | } 30 | 31 | func Test_EncodeAppToml_NotReplaceExisting(t *testing.T) { 32 | r := require.New(t) 33 | 34 | run := gentest.NewRunner() 35 | r.NoError(run.File(genny.NewFileS("config/buffalo-app.toml", `name = "pepsi"`))) 36 | 37 | g := EncodeAppToml(&Options{ 38 | App: meta.Named("coke", "."), 39 | }) 40 | run.WithRun(g) 41 | 42 | r.NoError(run.Run()) 43 | 44 | results := run.Results() 45 | f, err := results.Find("config/buffalo-app.toml") 46 | r.NoError(err) 47 | 48 | r.Contains(f.String(), `name = "pepsi"`) 49 | } 50 | -------------------------------------------------------------------------------- /internal/genny/fix/action_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "github.com/gobuffalo/genny/v2/gentest" 9 | "github.com/gobuffalo/meta" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test_ReplaceAppOnce(t *testing.T) { 14 | r := require.New(t) 15 | 16 | tt := []struct { 17 | Name string 18 | OK bool 19 | }{ 20 | {"buffalo0_11", false}, 21 | {"buffaloPre0_18api", true}, 22 | {"buffaloPre0_18web", true}, 23 | } 24 | 25 | for _, tc := range tt { 26 | t.Run(tc.Name, func(t *testing.T) { 27 | run := gentest.NewRunner() 28 | 29 | err := run.Disk.AddFS(os.DirFS(filepath.Join("_fixtures", tc.Name))) 30 | r.NoError(err) 31 | 32 | opts := &Options{ 33 | App: meta.Named("coke", "."), 34 | } 35 | g := ReplaceAppOnce(opts) 36 | run.WithRun(g) 37 | 38 | if tc.OK { 39 | r.NoError(run.Run()) 40 | f, err := run.FindFile("actions/app.go") 41 | r.NoError(err) 42 | 43 | //fmt.Println("XXX =====", f.String()) 44 | r.Contains(f.String(), "appOnce", "files in vendor directory should not be changed") 45 | } else { 46 | r.Error(run.Run()) 47 | } 48 | }) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /internal/genny/newapp/api/api.go: -------------------------------------------------------------------------------- 1 | package api 2 | 3 | import ( 4 | "embed" 5 | "html/template" 6 | "io/fs" 7 | 8 | "github.com/gobuffalo/cli/internal/genny/newapp/core" 9 | "github.com/gobuffalo/genny/v2" 10 | "github.com/gobuffalo/genny/v2/gogen" 11 | ) 12 | 13 | //go:embed templates/* 14 | var templates embed.FS 15 | 16 | // Templates used for api project files 17 | // (exported mostly for the "fix" command) 18 | func Templates() (fs.FS, error) { 19 | return fs.Sub(templates, "templates") 20 | } 21 | 22 | // New generator for creating a Buffalo API application 23 | func New(opts *Options) (*genny.Group, error) { 24 | if err := opts.Validate(); err != nil { 25 | return nil, err 26 | } 27 | 28 | gg, err := core.New(opts.Options) 29 | if err != nil { 30 | return gg, err 31 | } 32 | 33 | g := genny.New() 34 | data := map[string]interface{}{ 35 | "opts": opts, 36 | } 37 | 38 | helpers := template.FuncMap{} 39 | 40 | t := gogen.TemplateTransformer(data, helpers) 41 | g.Transformer(t) 42 | sub, err := Templates() 43 | if err != nil { 44 | return gg, err 45 | } 46 | 47 | if err := g.FS(sub); err != nil { 48 | return gg, err 49 | } 50 | 51 | gg.Add(g) 52 | return gg, nil 53 | } 54 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/default/templates/widgets/index.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

Widgets

3 |
4 | <%= linkTo(newWidgetsPath(), {class: "btn btn-primary"}) { %> 5 | Create New Widget 6 | <% } %> 7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <%= for (widget) in widgets { %> 17 | 18 | 19 | 26 | 27 | <% } %> 28 | 29 |
Name 
<%= widget.Name %> 20 |
21 | <%= linkTo(widgetPath({ widget_id: widget.ID }), {class: "btn btn-info", body: "View"}) %> 22 | <%= linkTo(editWidgetPath({ widget_id: widget.ID }), {class: "btn btn-warning", body: "Edit"}) %> 23 | <%= linkTo(widgetPath({ widget_id: widget.ID }), {class: "btn btn-danger", "data-method": "DELETE", "data-confirm": "Are you sure?", body: "Destroy"}) %> 24 |
25 |
30 | 31 |
32 | <%= paginator(pagination) %> 33 |
34 | -------------------------------------------------------------------------------- /internal/genny/build/apkg.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "os/exec" 5 | 6 | "github.com/gobuffalo/genny/v2" 7 | ) 8 | 9 | func apkg(opts *Options) (*genny.Generator, error) { 10 | g := genny.New() 11 | 12 | if err := opts.Validate(); err != nil { 13 | return g, err 14 | } 15 | 16 | g.RunFn(copyInflections) 17 | g.RunFn(copyDatabase) 18 | g.RunFn(addDependencies) 19 | 20 | return g, nil 21 | } 22 | 23 | func addDependencies(r *genny.Runner) error { 24 | return r.Exec(exec.Command("go", "mod", "tidy")) 25 | } 26 | 27 | func copyDatabase(r *genny.Runner) error { 28 | defer func() { 29 | r.Disk.Remove("database.yml") 30 | }() 31 | f, err := r.FindFile("database.yml") 32 | if err != nil { 33 | f, err = r.FindFile("config/database.yml") 34 | if err != nil { 35 | // it's ok to not have this file 36 | return nil 37 | } 38 | } 39 | return r.File(genny.NewFile("a/database.yml", f)) 40 | } 41 | 42 | func copyInflections(r *genny.Runner) error { 43 | defer func() { 44 | r.Disk.Remove("inflections.json") 45 | }() 46 | f, err := r.FindFile("inflections.json") 47 | if err != nil { 48 | // it's ok to not have this file 49 | return nil 50 | } 51 | return r.File(genny.NewFile("a/inflections.json", f)) 52 | } 53 | -------------------------------------------------------------------------------- /internal/genny/build/cleanup_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "sync" 5 | "testing" 6 | 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/gobuffalo/meta" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_WithDeps(t *testing.T) { 13 | r := require.New(t) 14 | 15 | run := gentest.NewRunner() 16 | 17 | opts := &Options{ 18 | WithAssets: false, 19 | WithBuildDeps: true, 20 | Environment: "bar", 21 | App: meta.New("."), 22 | } 23 | 24 | emptyMap := sync.Map{} 25 | opts.rollback = &emptyMap 26 | 27 | f := Cleanup(opts) 28 | r.NoError(f(run)) 29 | 30 | results := run.Results() 31 | 32 | cmds := []string{"go mod tidy"} 33 | for i, c := range results.Commands { 34 | eq(r, cmds[i], c) 35 | } 36 | } 37 | 38 | func Test_WithoutDeps(t *testing.T) { 39 | r := require.New(t) 40 | 41 | run := gentest.NewRunner() 42 | 43 | opts := &Options{ 44 | WithAssets: false, 45 | WithBuildDeps: false, 46 | Environment: "bar", 47 | App: meta.New("."), 48 | } 49 | 50 | emptyMap := sync.Map{} 51 | opts.rollback = &emptyMap 52 | 53 | f := Cleanup(opts) 54 | r.NoError(f(run)) 55 | 56 | results := run.Results() 57 | 58 | r.Len(results.Commands, 0) 59 | } 60 | -------------------------------------------------------------------------------- /internal/genny/ci/templates/dot-github/workflows/test.yml.tmpl: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | {{ if eq .opts.DBType "postgres" -}} 14 | services: 15 | postgres: 16 | image: postgres:9.6-alpine 17 | env: 18 | POSTGRES_DB: {{.opts.App.Name.File}}_test 19 | POSTGRES_PASSWORD: postgres 20 | options: >- 21 | --health-cmd pg_isready 22 | --health-interval 10s 23 | --health-timeout 5s 24 | --health-retries 5 25 | ports: 26 | - 5432:5432 27 | {{- end }} 28 | steps: 29 | - uses: actions/checkout@v3 30 | - uses: actions/setup-go@v3 31 | with: 32 | go-version: ~1.18 33 | cache: true 34 | - name: setup 35 | run: | 36 | go install github.com/gobuffalo/cli/cmd/buffalo@latest 37 | - name: test 38 | {{ if eq .opts.DBType "postgres" -}} 39 | env: 40 | TEST_DATABASE_URL: postgres://postgres:postgres@localhost:5432/{{.opts.App.Name.File}}_test?sslmode=disable 41 | {{- end }} 42 | run: | 43 | buffalo test 44 | -------------------------------------------------------------------------------- /internal/genny/newapp/web/options.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gobuffalo/cli/internal/genny/assets/standard" 7 | "github.com/gobuffalo/cli/internal/genny/assets/webpack" 8 | "github.com/gobuffalo/cli/internal/genny/newapp/core" 9 | ) 10 | 11 | // Options for a web app 12 | type Options struct { 13 | *core.Options 14 | Webpack *webpack.Options 15 | Standard *standard.Options 16 | } 17 | 18 | // Validate that options are usuable 19 | func (opts *Options) Validate() error { 20 | if opts.Options == nil { 21 | opts.Options = &core.Options{} 22 | } 23 | 24 | if err := opts.Options.Validate(); err != nil { 25 | return err 26 | } 27 | 28 | if opts.Docker != nil { 29 | if opts.Docker.App.IsZero() { 30 | opts.Docker.App = opts.App 31 | } 32 | if err := opts.Docker.Validate(); err != nil { 33 | return err 34 | } 35 | } 36 | 37 | if opts.Webpack != nil { 38 | if opts.Webpack.App.IsZero() { 39 | opts.Webpack.App = opts.App 40 | } 41 | if err := opts.Webpack.Validate(); err != nil { 42 | return err 43 | } 44 | } 45 | 46 | if opts.Standard != nil && opts.Webpack != nil { 47 | return fmt.Errorf("you can not use both webpack and standard generators") 48 | } 49 | 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /internal/genny/resource/_fixtures/nested/templates/admin/widgets/index.plush.html: -------------------------------------------------------------------------------- 1 |
2 |

Widgets

3 |
4 | <%= linkTo(newAdminWidgetsPath(), {class: "btn btn-primary"}) { %> 5 | Create New Widget 6 | <% } %> 7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | <%= for (widget) in widgets { %> 17 | 18 | 19 | 26 | 27 | <% } %> 28 | 29 |
Name 
<%= widget.Name %> 20 |
21 | <%= linkTo(adminWidgetPath({ admin_widget_id: widget.ID }), {class: "btn btn-info", body: "View"}) %> 22 | <%= linkTo(editAdminWidgetPath({ admin_widget_id: widget.ID }), {class: "btn btn-warning", body: "Edit"}) %> 23 | <%= linkTo(adminWidgetPath({ admin_widget_id: widget.ID }), {class: "btn btn-danger", "data-method": "DELETE", "data-confirm": "Are you sure?", body: "Destroy"}) %> 24 |
25 |
30 | 31 |
32 | <%= paginator(pagination) %> 33 |
34 | -------------------------------------------------------------------------------- /internal/cmd/generate/task.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "context" 5 | "os" 6 | 7 | "github.com/gobuffalo/cli/internal/genny/grift" 8 | "github.com/gobuffalo/genny/v2" 9 | "github.com/gobuffalo/genny/v2/gogen" 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | var taskOptions = struct { 14 | dryRun bool 15 | *grift.Options 16 | }{ 17 | Options: &grift.Options{}, 18 | } 19 | 20 | // TaskCmd is the command called with the generate grift cli. 21 | var TaskCmd = &cobra.Command{ 22 | Use: "task [name]", 23 | Aliases: []string{"t", "grift"}, 24 | Short: "Generate a grift task", 25 | RunE: func(cmd *cobra.Command, args []string) error { 26 | run := genny.WetRunner(context.Background()) 27 | if taskOptions.dryRun { 28 | run = genny.DryRunner(context.Background()) 29 | } 30 | 31 | opts := taskOptions.Options 32 | opts.Args = args 33 | g, err := grift.New(opts) 34 | if err != nil { 35 | return err 36 | } 37 | run.With(g) 38 | 39 | pwd, _ := os.Getwd() 40 | g, err = gogen.Fmt(pwd) 41 | if err != nil { 42 | return err 43 | } 44 | run.With(g) 45 | 46 | return run.Run() 47 | }, 48 | } 49 | 50 | func init() { 51 | TaskCmd.Flags().BoolVarP(&taskOptions.dryRun, "dry-run", "d", false, "dry run of the generator") 52 | } 53 | -------------------------------------------------------------------------------- /internal/cmd/destroy/mailer.go: -------------------------------------------------------------------------------- 1 | package destroy 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | 8 | "github.com/gobuffalo/flect" 9 | "github.com/sirupsen/logrus" 10 | "github.com/spf13/cobra" 11 | ) 12 | 13 | // mailerCmd destroys a passed mailer 14 | var mailerCmd = &cobra.Command{ 15 | Use: "mailer [name]", 16 | // Example: "mailer cars", 17 | Aliases: []string{"l"}, 18 | Short: "Destroy mailer files", 19 | RunE: func(cmd *cobra.Command, args []string) error { 20 | if len(args) == 0 { 21 | return fmt.Errorf("you need to provide a valid mailer name in order to destroy it") 22 | } 23 | 24 | name := args[0] 25 | 26 | removeMailer(name) 27 | 28 | return nil 29 | }, 30 | } 31 | 32 | func removeMailer(name string) { 33 | if yesToAll || confirm("Want to remove mailer? (y/N)") { 34 | mailerFileName := flect.Singularize(flect.Underscore(name)) 35 | 36 | files := []string{ 37 | filepath.Join("mailers", fmt.Sprintf("%v.go", mailerFileName)), 38 | filepath.Join("templates/mail", fmt.Sprintf("%v.html", mailerFileName)), 39 | filepath.Join("templates/mail", fmt.Sprintf("%v.plush.html", mailerFileName)), 40 | } 41 | 42 | for _, f := range files { 43 | os.Remove(f) 44 | logrus.Infof("- Deleted %v", f) 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /internal/genny/grift/grift_test.go: -------------------------------------------------------------------------------- 1 | package grift 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2/gentest" 7 | "github.com/stretchr/testify/require" 8 | ) 9 | 10 | func Test_New(t *testing.T) { 11 | r := require.New(t) 12 | 13 | run := gentest.NewRunner() 14 | err := run.WithNew(New(&Options{ 15 | Args: []string{"foo"}, 16 | })) 17 | r.NoError(err) 18 | r.NoError(run.Run()) 19 | 20 | res := run.Results() 21 | r.Len(res.Commands, 0) 22 | r.Len(res.Files, 1) 23 | 24 | f := res.Files[0] 25 | r.Equal("grifts/foo.go", f.Name()) 26 | body := f.String() 27 | r.Contains(body, `var _ = Add("foo", func(c *Context) error`) 28 | } 29 | 30 | func Test_New_Namespaced(t *testing.T) { 31 | r := require.New(t) 32 | 33 | run := gentest.NewRunner() 34 | err := run.WithNew(New(&Options{ 35 | Args: []string{"foo:bar"}, 36 | })) 37 | r.NoError(err) 38 | r.NoError(run.Run()) 39 | 40 | res := run.Results() 41 | r.Len(res.Commands, 0) 42 | r.Len(res.Files, 1) 43 | 44 | f := res.Files[0] 45 | r.Equal("grifts/bar.go", f.Name()) 46 | body := f.String() 47 | r.Contains(body, `Add("bar", func(c *Context) error`) 48 | } 49 | 50 | func Test_New_No_Name(t *testing.T) { 51 | r := require.New(t) 52 | 53 | _, err := New(&Options{}) 54 | r.Error(err) 55 | } 56 | -------------------------------------------------------------------------------- /internal/genny/fix/refresh_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "github.com/gobuffalo/genny/v2/gentest" 9 | "github.com/gobuffalo/meta" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestRefresh(t *testing.T) { 14 | r := require.New(t) 15 | 16 | tt := []struct { 17 | Name string 18 | warnings []string 19 | }{ 20 | { 21 | Name: "buffalo0_11", 22 | warnings: []string{"app.Start has been removed in v0.11.0. Use app.Serve Instead. [main.go]"}, 23 | }, 24 | { 25 | Name: "buffaloPre0_18api", 26 | warnings: []string{}, 27 | }, 28 | { 29 | Name: "buffaloPre0_18web", 30 | warnings: []string{}, 31 | }, 32 | } 33 | 34 | for _, tc := range tt { 35 | t.Run(tc.Name, func(t *testing.T) { 36 | run := gentest.NewRunner() 37 | 38 | err := run.Disk.AddFS(os.DirFS(filepath.Join("_fixtures", tc.Name))) 39 | r.NoError(err) 40 | 41 | opts := &Options{ 42 | App: meta.Named("coke", "."), 43 | } 44 | 45 | g := Refresh(opts) 46 | run.WithRun(g) 47 | 48 | r.NoError(run.Run()) 49 | results := run.Results() 50 | 51 | f, err := results.Find(".buffalo.dev.yml") 52 | 53 | r.NoError(err) 54 | r.Contains(f.String(), "./cmd/app") 55 | }) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /internal/genny/assets/standard/standard.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "strings" 7 | "text/template" 8 | 9 | "github.com/gobuffalo/genny/v2" 10 | "github.com/gobuffalo/genny/v2/gogen" 11 | ) 12 | 13 | //go:embed templates/* 14 | var templates embed.FS 15 | 16 | // New generator for creating basic asset files 17 | func New(opts *Options) (*genny.Generator, error) { 18 | g := genny.New() 19 | 20 | sub, err := fs.Sub(templates, "templates") 21 | if err != nil { 22 | return g, err 23 | } 24 | 25 | if err := g.FS(sub); err != nil { 26 | return g, err 27 | } 28 | 29 | data := map[string]interface{}{} 30 | h := template.FuncMap{} 31 | t := gogen.TemplateTransformer(data, h) 32 | g.Transformer(t) 33 | 34 | g.RunFn(func(r *genny.Runner) error { 35 | f, err := r.FindFile("templates/application.plush.html") 36 | if err != nil { 37 | return err 38 | } 39 | 40 | s := strings.Replace(f.String(), "", "\n"+bs4, 1) 41 | return r.File(genny.NewFileS(f.Name(), s)) 42 | }) 43 | 44 | return g, nil 45 | } 46 | 47 | const bs4 = `` 48 | -------------------------------------------------------------------------------- /internal/genny/refresh/refresh.go: -------------------------------------------------------------------------------- 1 | package refresh 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "strings" 7 | 8 | "github.com/gobuffalo/genny/v2" 9 | "github.com/gobuffalo/genny/v2/plushgen" 10 | "github.com/gobuffalo/plush/v4" 11 | ) 12 | 13 | //go:embed templates/* 14 | var templates embed.FS 15 | 16 | // New generator to generate refresh templates 17 | func New(opts *Options) (*genny.Generator, error) { 18 | g := genny.New() 19 | if err := opts.Validate(); err != nil { 20 | return g, err 21 | } 22 | 23 | sub, err := fs.Sub(templates, "templates") 24 | if err != nil { 25 | return g, err 26 | } 27 | 28 | if err := g.FS(sub); err != nil { 29 | return g, err 30 | } 31 | 32 | ctx := plush.NewContext() 33 | ctx.Set("app", opts.App) 34 | g.Transformer(plushgen.Transformer(ctx)) 35 | g.Transformer(genny.Dot()) 36 | 37 | // TODO: workaround for 1.16, remove when we upgrade to 1.17 and rename "dot-*" files back to "-dot-*" 38 | g.Transformer(genny.NewTransformer("*", func(f genny.File) (genny.File, error) { 39 | name := f.Name() 40 | if strings.HasPrefix(name, "dot-") { 41 | name = strings.TrimPrefix(name, "dot-") 42 | name = "." + name 43 | } 44 | return genny.NewFile(name, f), nil 45 | })) 46 | g.Transformer(genny.Replace("/dot-", "/.")) 47 | 48 | return g, nil 49 | } 50 | -------------------------------------------------------------------------------- /internal/genny/fix/movemain_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "os" 5 | "path/filepath" 6 | "testing" 7 | 8 | "github.com/gobuffalo/genny/v2/gentest" 9 | "github.com/gobuffalo/meta" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func TestMoveMain(t *testing.T) { 14 | r := require.New(t) 15 | 16 | tt := []struct { 17 | Name string 18 | warnings []string 19 | }{ 20 | { 21 | Name: "buffalo0_11", 22 | warnings: []string{"app.Start has been removed in v0.11.0. Use app.Serve Instead. [main.go]"}, 23 | }, 24 | { 25 | Name: "buffaloPre0_18api", 26 | warnings: []string{}, 27 | }, 28 | { 29 | Name: "buffaloPre0_18web", 30 | warnings: []string{}, 31 | }, 32 | } 33 | 34 | for _, tc := range tt { 35 | t.Run(tc.Name, func(t *testing.T) { 36 | run := gentest.NewRunner() 37 | 38 | err := run.Disk.AddFS(os.DirFS(filepath.Join("_fixtures", tc.Name))) 39 | r.NoError(err) 40 | 41 | opts := &Options{ 42 | App: meta.Named("coke", "."), 43 | } 44 | 45 | g := MoveMain(opts) 46 | run.WithRun(g) 47 | 48 | r.NoError(run.Run()) 49 | 50 | results := run.Results() 51 | _, err = results.Find("cmd/app/main.go") 52 | r.NoError(err) 53 | 54 | _, err = results.Find("main.go") 55 | r.Error(err) 56 | }) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /internal/plugins/plugcmds/available_test.go: -------------------------------------------------------------------------------- 1 | package plugcmds 2 | 3 | import ( 4 | "bytes" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/gobuffalo/events" 9 | "github.com/spf13/cobra" 10 | "github.com/stretchr/testify/require" 11 | ) 12 | 13 | func Test_Available_Add(t *testing.T) { 14 | r := require.New(t) 15 | 16 | a := NewAvailable() 17 | err := a.Add("generate", &cobra.Command{ 18 | Use: "foo", 19 | Short: "generates foo", 20 | Aliases: []string{"f"}, 21 | }) 22 | r.NoError(err) 23 | 24 | r.Len(a.Commands(), 2) 25 | } 26 | 27 | func Test_Available_Encode(t *testing.T) { 28 | r := require.New(t) 29 | 30 | bb := &bytes.Buffer{} 31 | 32 | a := NewAvailable() 33 | err := a.Add("generate", &cobra.Command{ 34 | Use: "foo", 35 | Short: "generates foo", 36 | Aliases: []string{"f"}, 37 | }) 38 | r.NoError(err) 39 | 40 | r.NoError(a.Encode(bb)) 41 | const exp = `[{"name":"foo","use_command":"foo","buffalo_command":"generate","description":"generates foo","aliases":["f"]}]` 42 | r.Equal(exp, strings.TrimSpace(bb.String())) 43 | } 44 | 45 | func Test_Available_Listen(t *testing.T) { 46 | r := require.New(t) 47 | 48 | a := NewAvailable() 49 | err := a.Listen(func(e events.Event) error { 50 | return nil 51 | }) 52 | r.NoError(err) 53 | 54 | r.Len(a.Commands(), 2) 55 | } 56 | -------------------------------------------------------------------------------- /internal/genny/ci/templates/dot-circleci/config.yml.tmpl: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: circleci/golang:1.12 6 | {{ if eq .opts.DBType "postgres" -}} 7 | - image: circleci/postgres:9.6-alpine 8 | environment: 9 | POSTGRES_USER: postgres 10 | POSTGRES_DB: {{.opts.App.Name.File}}_test 11 | {{- end }} 12 | 13 | environment: 14 | TEST_RESULTS: /tmp/test-results 15 | 16 | steps: 17 | - checkout 18 | - run: mkdir -p $TEST_RESULTS 19 | 20 | - restore_cache: 21 | keys: 22 | - v1-pkg-cache 23 | 24 | - run: go get github.com/jstemmer/go-junit-report 25 | 26 | - run: go get github.com/gobuffalo/buffalo/buffalo 27 | - run: go mod download 28 | 29 | - run: 30 | name: Run unit tests 31 | command: | 32 | trap "go-junit-report <${TEST_RESULTS}/go-test.out > ${TEST_RESULTS}/go-test-report.xml" EXIT 33 | buffalo test | tee ${TEST_RESULTS}/go-test.out 34 | 35 | - save_cache: 36 | key: v1-pkg-cache 37 | paths: 38 | - "/go/pkg" 39 | 40 | - store_artifacts: 41 | path: /tmp/test-results 42 | destination: raw-test-output 43 | 44 | - store_test_results: 45 | path: /tmp/test-results 46 | -------------------------------------------------------------------------------- /internal/genny/fix/embed_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2/gentest" 7 | "github.com/gobuffalo/meta" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_FixEmbed_ApiProject(t *testing.T) { 12 | r := require.New(t) 13 | 14 | run := gentest.NewRunner() 15 | 16 | opts := &Options{ 17 | App: meta.App{ 18 | Root: ".", 19 | AsAPI: true, 20 | }, 21 | } 22 | g := FixEmbed(opts) 23 | run.WithRun(g) 24 | 25 | r.NoError(run.Run()) 26 | results := run.Results() 27 | 28 | f, err := results.Find("locales/embed.go") 29 | r.NoError(err) 30 | r.Contains(f.String(), "buffalo.NewFS") 31 | } 32 | 33 | func Test_FixEmbed_WebProject(t *testing.T) { 34 | r := require.New(t) 35 | 36 | run := gentest.NewRunner() 37 | 38 | opts := &Options{ 39 | App: meta.App{ 40 | Root: ".", 41 | }, 42 | } 43 | g := FixEmbed(opts) 44 | run.WithRun(g) 45 | 46 | r.NoError(run.Run()) 47 | results := run.Results() 48 | 49 | f, err := results.Find("locales/embed.go") 50 | r.NoError(err) 51 | r.Contains(f.String(), "buffalo.NewFS") 52 | 53 | f, err = results.Find("public/embed.go") 54 | r.NoError(err) 55 | r.Contains(f.String(), "buffalo.NewFS") 56 | 57 | f, err = results.Find("templates/embed.go") 58 | r.NoError(err) 59 | r.Contains(f.String(), "buffalo.NewFS") 60 | } 61 | -------------------------------------------------------------------------------- /internal/genny/add/add_test.go: -------------------------------------------------------------------------------- 1 | package add 2 | 3 | import ( 4 | "bytes" 5 | "go/build" 6 | "path/filepath" 7 | "strings" 8 | "testing" 9 | 10 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 11 | "github.com/gobuffalo/genny/v2" 12 | "github.com/gobuffalo/genny/v2/gentest" 13 | "github.com/gobuffalo/meta" 14 | "github.com/stretchr/testify/require" 15 | ) 16 | 17 | func Test_New(t *testing.T) { 18 | r := require.New(t) 19 | 20 | g, err := New(&Options{ 21 | App: meta.New("."), 22 | Plugins: []plugdeps.Plugin{ 23 | {Binary: "buffalo-pop", GoGet: "github.com/gobuffalo/buffalo-pop/v3@latest"}, 24 | {Binary: "buffalo-hello.rb", Local: "./plugins/buffalo-hello.rb"}, 25 | }, 26 | }) 27 | r.NoError(err) 28 | 29 | run := gentest.NewRunner() 30 | c := build.Default 31 | run.Disk.Add(genny.NewFile(filepath.Join(c.GOPATH, "bin", "buffalo-pop"), &bytes.Buffer{})) 32 | r.NoError(run.With(g)) 33 | 34 | r.NoError(run.Run()) 35 | 36 | res := run.Results() 37 | 38 | ecmds := []string{} 39 | r.Len(res.Commands, len(ecmds)) 40 | for i, c := range res.Commands { 41 | r.Equal(ecmds[i], strings.Join(c.Args, " ")) 42 | } 43 | 44 | efiles := []string{"bin/buffalo-pop", "config/buffalo-plugins.toml"} 45 | r.Len(res.Files, len(efiles)) 46 | for i, f := range res.Files { 47 | r.True(strings.HasSuffix(f.Name(), efiles[i])) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /internal/cmd/plugins/list.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "sort" 9 | "text/tabwriter" 10 | 11 | pluginsin "github.com/gobuffalo/cli/internal/plugins" 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | var listCmd = &cobra.Command{ 16 | Use: "list", 17 | Short: "a list of installed buffalo plugins", 18 | RunE: func(cmd *cobra.Command, args []string) error { 19 | list, err := pluginsin.Available() 20 | if err != nil { 21 | return err 22 | } 23 | 24 | var cmds pluginsin.Commands 25 | 26 | for _, l := range list { 27 | cmds = append(cmds, l...) 28 | } 29 | 30 | sort.Slice(cmds, func(i, j int) bool { 31 | c1 := cmds[i] 32 | c2 := cmds[j] 33 | 34 | return c1.Name+c1.Name < c2.Name+c2.Name 35 | }) 36 | 37 | w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.Debug) 38 | fmt.Fprintln(w, "Bin\tCommand\tDescription") 39 | fmt.Fprintln(w, "---\t---\t---") 40 | 41 | for _, c := range cmds { 42 | if c.Name == "" { 43 | continue 44 | } 45 | sb := &bytes.Buffer{} 46 | sb.WriteString("buffalo ") 47 | if c.BuffaloCommand != "root" { 48 | sb.WriteString(c.BuffaloCommand) 49 | sb.WriteString(" ") 50 | } 51 | sb.WriteString(c.Name) 52 | fmt.Fprintf(w, "%s\t%s\t%s\n", filepath.Base(c.Binary), sb.String(), c.Description) 53 | } 54 | 55 | return w.Flush() 56 | }, 57 | } 58 | -------------------------------------------------------------------------------- /internal/genny/build/validate_test.go: -------------------------------------------------------------------------------- 1 | package build 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2/gentest" 7 | "github.com/psanford/memfs" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_TemplateValidator_Good(t *testing.T) { 12 | r := require.New(t) 13 | 14 | tvs := []TemplateValidator{PlushValidator} 15 | 16 | goodFS := memfs.New() 17 | r.NoError(goodFS.MkdirAll("_ignored", 0o755)) 18 | r.NoError(goodFS.WriteFile("_ignored/c.html", []byte("c"), 0o644)) 19 | r.NoError(goodFS.WriteFile("a.html", []byte("a"), 0o644)) 20 | r.NoError(goodFS.WriteFile("b.html", []byte("b"), 0o644)) 21 | 22 | run := gentest.NewRunner() 23 | run.WithRun(ValidateTemplates(goodFS, tvs)) 24 | r.NoError(run.Run()) 25 | } 26 | 27 | func Test_TemplateValidator_Bad(t *testing.T) { 28 | r := require.New(t) 29 | 30 | tvs := []TemplateValidator{PlushValidator} 31 | 32 | badFS := memfs.New() 33 | r.NoError(badFS.WriteFile("a.html", []byte("A Hello <%= broken!>%>>"), 0o644)) 34 | r.NoError(badFS.WriteFile("b.md", []byte("B Hello <%= broken!>%>>"), 0o644)) 35 | 36 | run := gentest.NewRunner() 37 | run.WithRun(ValidateTemplates(badFS, tvs)) 38 | 39 | err := run.Run() 40 | r.Error(err) 41 | r.Equal("template error in file a.html: line 1: no prefix parse function for > found\ntemplate error in file b.md: line 1: no prefix parse function for > found", err.Error()) 42 | } 43 | -------------------------------------------------------------------------------- /internal/genny/assets/webpack/templates/package.json.tmpl: -------------------------------------------------------------------------------- 1 | { 2 | "name": "buffalo", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "webpack --watch", 8 | "build": "webpack --mode production --progress" 9 | }, 10 | "repository": "github.com/gobuffalo/buffalo", 11 | "dependencies": { 12 | "@fortawesome/fontawesome-free": "^5.12.0", 13 | "@popperjs/core": "^2.0.0", 14 | "bootstrap": "^5.0.0", 15 | "jquery": "^3.6.0", 16 | "jquery-ujs": "^1.2.2" 17 | }, 18 | "devDependencies": { 19 | "@babel/cli": "^7.0.0", 20 | "@babel/core": "^7.0.0", 21 | "@babel/preset-env": "^7.0.0", 22 | "autoprefixer": "^9.7.6", 23 | "babel-loader": "^8.1.0", 24 | "copy-webpack-plugin": "~6.4.1", 25 | "css-loader": "~3.5.1", 26 | "expose-loader": "^3.0.0", 27 | "file-loader": "~6.0.0", 28 | "glob": "^7.2.0", 29 | "gopherjs-loader": "^0.0.1", 30 | "mini-css-extract-plugin": "^2.0.0", 31 | "npm-install-webpack-plugin": "4.0.5", 32 | "postcss-loader": "^3.0.0", 33 | "sass": "^1.0.0", 34 | "sass-loader": "~10.2.0", 35 | "style-loader": "~1.1.3", 36 | "terser-webpack-plugin": "~2.3.1", 37 | "url-loader": "~4.1.0", 38 | "webpack": "~5.65.0", 39 | "webpack-cli": "^4.0.0", 40 | "webpack-livereload-plugin": "^3.0.0", 41 | "webpack-manifest-plugin": "^4.0.0" 42 | } 43 | } -------------------------------------------------------------------------------- /internal/cmd/info/info.go: -------------------------------------------------------------------------------- 1 | package info 2 | 3 | import ( 4 | "context" 5 | "os/exec" 6 | "runtime" 7 | "strings" 8 | "time" 9 | 10 | "github.com/gobuffalo/clara/v2/genny/rx" 11 | "github.com/gobuffalo/cli/internal/genny/info" 12 | "github.com/gobuffalo/genny/v2" 13 | "github.com/spf13/cobra" 14 | ) 15 | 16 | func runE(cmd *cobra.Command, args []string) error { 17 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 18 | defer cancel() 19 | 20 | run := genny.WetRunner(ctx) 21 | 22 | _, err := run.LookPath("clara") 23 | if err == nil { 24 | // use the clara binary if available 25 | run.WithRun(func(r *genny.Runner) error { 26 | return r.Exec(exec.Command("clara")) 27 | }) 28 | } else { 29 | // no clara binary, so use the one bundled with buffalo 30 | copts := infoOptions.Clara 31 | rx.GoMinimums = []string{">=" + minGoVersion(false)} 32 | if err := run.WithNew(rx.New(copts)); err != nil { 33 | return err 34 | } 35 | } 36 | 37 | iopts := infoOptions.Info 38 | if err := run.WithNew(info.New(iopts)); err != nil { 39 | return err 40 | } 41 | 42 | return run.Run() 43 | } 44 | 45 | func minGoVersion(useBuilderVersion bool) string { 46 | // TODO: can we make this rule? 47 | if useBuilderVersion { 48 | version := strings.TrimPrefix(runtime.Version(), "go") 49 | return strings.Join(strings.Split(version, ".")[0:2], ".") 50 | } 51 | return "1.17" 52 | } 53 | -------------------------------------------------------------------------------- /internal/genny/fix/embed.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "html/template" 7 | 8 | "github.com/gobuffalo/cli/internal/genny/newapp/api" 9 | "github.com/gobuffalo/cli/internal/genny/newapp/web" 10 | "github.com/gobuffalo/genny/v2" 11 | ) 12 | 13 | func FixEmbed(opts *Options) genny.RunFn { 14 | return func(r *genny.Runner) error { 15 | fmt.Println("~~~ Checking embed.go files ~~~") 16 | 17 | files := []string{"locales/embed.go", "public/embed.go", "templates/embed.go"} 18 | templates, err := web.Templates() 19 | if err != nil { 20 | return err 21 | } 22 | 23 | if opts.App.AsAPI { 24 | files = []string{"locales/embed.go"} 25 | 26 | templates, err = api.Templates() 27 | if err != nil { 28 | return err 29 | } 30 | } else { 31 | f := genny.NewFileS("templates/home/delete_me.txt", "you can delete this file") 32 | if err := r.File(f); err != nil { 33 | return err 34 | } 35 | } 36 | 37 | for _, name := range files { 38 | tmpl, err := template.New("embed.go").ParseFS(templates, name+".tmpl") 39 | if err != nil { 40 | return err 41 | } 42 | 43 | bb := &bytes.Buffer{} 44 | if err := tmpl.ExecuteTemplate(bb, "embed.go.tmpl", nil); err != nil { 45 | return err 46 | } 47 | 48 | f := genny.NewFile(name, bb) 49 | if err := r.File(f); err != nil { 50 | return err 51 | } 52 | } 53 | return nil 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | PkgGoDev 5 | Standard Test 6 | Go Report Card 7 |

8 | 9 | # Buffalo CLI 10 | 11 | This is the repo for the Buffalo CLI. The Buffalo CLI is a tool to develop, test and deploy your Buffalo applications. 12 | 13 | ## Installation 14 | 15 | To install the Buffalo CLI you can run the following command: 16 | 17 | ```bash 18 | go install github.com/gobuffalo/cli/cmd/buffalo@latest 19 | ``` 20 | 21 | 22 | 23 | ## Usage 24 | 25 | Once installed, the Buffalo CLI can be used by invoking the `buffalo` command. To know more about the available commands, run the `buffalo help` command. or you can also get details on a specific command by running `buffalo help `. 26 | -------------------------------------------------------------------------------- /internal/genny/resource/actions.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/gobuffalo/flect/name" 8 | "github.com/gobuffalo/genny/v2" 9 | "github.com/gobuffalo/genny/v2/gogen" 10 | ) 11 | 12 | func addResource(pres presenter) genny.RunFn { 13 | return func(r *genny.Runner) error { 14 | f, err := r.FindFile("actions/app.go") 15 | if err != nil { 16 | return err 17 | } 18 | 19 | stmt := fmt.Sprintf("app.Resource(\"/%s\", %sResource{})", pres.Name.URL(), pres.Name.Resource()) 20 | f, err = gogen.AddInsideBlock(f, "appOnce.Do(func() {", stmt) 21 | if err != nil { 22 | if strings.Contains(err.Error(), "could not find desired block") { 23 | f, err = gogen.AddInsideBlock(f, "if app == nil {", stmt) 24 | if err != nil { 25 | return err 26 | } else { 27 | r.Logger.Warnf("This app was built with CLI v0.18.8 or older. See https://gobuffalo.io/documentation/known-issues/#cli-v0.18.8") 28 | } 29 | } else { 30 | return err 31 | } 32 | } 33 | 34 | return r.File(f) 35 | } 36 | } 37 | 38 | func actions(opts *Options) []name.Ident { 39 | actions := []name.Ident{ 40 | name.New("list"), 41 | name.New("show"), 42 | name.New("create"), 43 | name.New("update"), 44 | name.New("destroy"), 45 | } 46 | 47 | if opts.App.AsWeb { 48 | actions = append(actions, name.New("new"), name.New("edit")) 49 | } 50 | 51 | return actions 52 | } 53 | -------------------------------------------------------------------------------- /Dockerfile.build: -------------------------------------------------------------------------------- 1 | FROM golang:1.18 2 | 3 | EXPOSE 3000 4 | 5 | RUN apt-get update \ 6 | && apt-get install -y -q build-essential sqlite3 libsqlite3-dev postgresql libpq-dev vim 7 | 8 | # Installing Node 12 9 | RUN curl -sL https://deb.nodesource.com/setup_12.x | bash 10 | RUN apt-get update && apt-get install nodejs 11 | 12 | # Installing Postgres 13 | RUN sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list' \ 14 | && wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | apt-key add - \ 15 | && apt-get update \ 16 | && apt-get install -y -q postgresql postgresql-contrib libpq-dev\ 17 | && rm -rf /var/lib/apt/lists/* \ 18 | && service postgresql start && \ 19 | # Setting up password for postgres 20 | su -c "psql -c \"ALTER USER postgres WITH PASSWORD 'postgres';\"" - postgres 21 | 22 | # Installing yarn 23 | RUN npm install -g --no-progress yarn \ 24 | && yarn config set yarn-offline-mirror /npm-packages-offline-cache \ 25 | && yarn config set yarn-offline-mirror-pruning true 26 | 27 | # Install golangci 28 | RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.24.0 29 | 30 | # Installing buffalo binary 31 | COPY buffalo /go/bin/buffalo 32 | 33 | WORKDIR / 34 | RUN go install github.com/gobuffalo/buffalo-pop/v3@latest 35 | 36 | RUN mkdir /src 37 | WORKDIR /src -------------------------------------------------------------------------------- /internal/cmd/generate/mailer.go: -------------------------------------------------------------------------------- 1 | package generate 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/gobuffalo/cli/internal/genny/mail" 7 | "github.com/gobuffalo/flect/name" 8 | "github.com/gobuffalo/genny/v2" 9 | "github.com/gobuffalo/genny/v2/gogen" 10 | "github.com/gobuffalo/meta" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var mailOptions = struct { 15 | dryRun bool 16 | *mail.Options 17 | }{ 18 | Options: &mail.Options{}, 19 | } 20 | 21 | // MailCmd for generating mailers 22 | var MailCmd = &cobra.Command{ 23 | Use: "mailer [name]", 24 | Short: "Generate a new mailer for Buffalo", 25 | RunE: func(cmd *cobra.Command, args []string) error { 26 | mailOptions.App = meta.New(".") 27 | mailOptions.Name = name.New(args[0]) 28 | gg, err := mail.New(mailOptions.Options) 29 | if err != nil { 30 | return err 31 | } 32 | 33 | run := genny.WetRunner(context.Background()) 34 | if mailOptions.dryRun { 35 | run = genny.DryRunner(context.Background()) 36 | } 37 | 38 | g, err := gogen.Fmt(mailOptions.App.Root) 39 | if err != nil { 40 | return err 41 | } 42 | if err := run.With(g); err != nil { 43 | return err 44 | } 45 | 46 | gg.With(run) 47 | return run.Run() 48 | }, 49 | } 50 | 51 | func init() { 52 | MailCmd.Flags().BoolVarP(&mailOptions.dryRun, "dry-run", "d", false, "dry run of the generator") 53 | MailCmd.Flags().BoolVar(&mailOptions.SkipInit, "skip-init", false, "skip initializing mailers/") 54 | } 55 | -------------------------------------------------------------------------------- /internal/genny/vcs/vcs_test.go: -------------------------------------------------------------------------------- 1 | package vcs 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_New_Bzr(t *testing.T) { 12 | r := require.New(t) 13 | 14 | g, err := New(&Options{ 15 | Provider: "bzr", 16 | }) 17 | r.NoError(err) 18 | 19 | run := gentest.NewRunner() 20 | r.NoError(run.With(g)) 21 | r.NoError(run.Run()) 22 | 23 | res := run.Results() 24 | r.Len(res.Files, 1) 25 | 26 | f := res.Files[0] 27 | r.Equal(".bzrignore", f.Name()) 28 | 29 | cmds := []string{ 30 | "bzr init", 31 | "bzr add . -q", 32 | "bzr commit -q -m Initial Commit", 33 | } 34 | 35 | r.Len(res.Commands, len(cmds)) 36 | for i, c := range res.Commands { 37 | r.Equal(cmds[i], strings.Join(c.Args, " ")) 38 | } 39 | } 40 | 41 | func Test_New_Git(t *testing.T) { 42 | r := require.New(t) 43 | 44 | g, err := New(&Options{ 45 | Provider: "git", 46 | }) 47 | r.NoError(err) 48 | 49 | run := gentest.NewRunner() 50 | r.NoError(run.With(g)) 51 | r.NoError(run.Run()) 52 | 53 | res := run.Results() 54 | r.Len(res.Files, 1) 55 | 56 | f := res.Files[0] 57 | r.Equal(".gitignore", f.Name()) 58 | 59 | cmds := []string{ 60 | "git init", 61 | "git add .", 62 | "git commit -q -m Initial Commit", 63 | } 64 | 65 | r.Len(res.Commands, len(cmds)) 66 | for i, c := range res.Commands { 67 | r.Equal(cmds[i], strings.Join(c.Args, " ")) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /internal/plugins/plugins_test.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "context" 5 | "os" 6 | "strings" 7 | "testing" 8 | "time" 9 | 10 | "github.com/gobuffalo/envy" 11 | "github.com/stretchr/testify/require" 12 | ) 13 | 14 | func TestAskBin_respectsTimeout(t *testing.T) { 15 | r := require.New(t) 16 | 17 | from, err := envy.MustGet("BUFFALO_PLUGIN_PATH") 18 | if err != nil { 19 | t.Skipf("BUFFALO_PLUGIN_PATH not set.") 20 | return 21 | } 22 | 23 | if fileEntries, err := os.ReadDir(from); err == nil { 24 | found := false 25 | for _, e := range fileEntries { 26 | if strings.HasPrefix(e.Name(), "buffalo-") { 27 | from = e.Name() 28 | found = true 29 | break 30 | } 31 | } 32 | if !found { 33 | t.Skipf("no plugins found") 34 | return 35 | } 36 | } else { 37 | r.Error(err, "plugin path not able to be read") 38 | return 39 | } 40 | 41 | const tooShort = time.Millisecond 42 | impossible, cancel := context.WithTimeout(context.Background(), tooShort) 43 | defer cancel() 44 | 45 | done := make(chan struct{}) 46 | go func() { 47 | askBin(impossible, from) 48 | close(done) 49 | }() 50 | 51 | select { 52 | case <-time.After(tooShort + 80*time.Millisecond): 53 | r.Fail("did not time-out quickly enough") 54 | case <-done: 55 | t.Log("timed-out successfully") 56 | } 57 | 58 | if _, ok := findInCache(from); ok { 59 | r.Fail("expected plugin not to be added to cache on failure, but it was in cache") 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /internal/cmd/plugins/remove.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "fmt" 7 | "strings" 8 | 9 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 10 | "github.com/gobuffalo/genny/v2" 11 | "github.com/gobuffalo/meta" 12 | "github.com/spf13/cobra" 13 | ) 14 | 15 | var removeOptions = struct { 16 | dryRun bool 17 | vendor bool 18 | }{} 19 | 20 | var removeCmd = &cobra.Command{ 21 | Use: "remove", 22 | Short: "removes plugin from config/buffalo-plugins.toml", 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | if len(args) == 0 { 25 | return fmt.Errorf("you must specify at least one plugin") 26 | } 27 | run := genny.WetRunner(context.Background()) 28 | if removeOptions.dryRun { 29 | run = genny.DryRunner(context.Background()) 30 | } 31 | 32 | app := meta.New(".") 33 | plugs, err := plugdeps.List(app) 34 | if err != nil && !errors.Is(err, plugdeps.ErrMissingConfig) { 35 | return err 36 | } 37 | 38 | for _, bin := range args { 39 | bin = strings.TrimSpace(bin) 40 | plugs.Remove(plugdeps.Plugin{ 41 | Binary: bin, 42 | }) 43 | } 44 | 45 | run.WithRun(NewEncodePluginsRunner(app, plugs)) 46 | return run.Run() 47 | }, 48 | } 49 | 50 | func init() { 51 | removeCmd.Flags().BoolVarP(&removeOptions.dryRun, "dry-run", "d", false, "dry run") 52 | removeCmd.Flags().BoolVar(&removeOptions.vendor, "vendor", false, "will install plugin binaries into ./plugins [WINDOWS not currently supported]") 53 | } 54 | -------------------------------------------------------------------------------- /internal/genny/docker/docker.go: -------------------------------------------------------------------------------- 1 | package docker 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "strings" 7 | "text/template" 8 | 9 | "github.com/gobuffalo/genny/v2" 10 | "github.com/gobuffalo/genny/v2/gogen" 11 | ) 12 | 13 | //go:embed templates/* 14 | var templates embed.FS 15 | 16 | // Templates used for generating Dockerfile 17 | // (exported mostly for the "fix" command) 18 | func Templates() (fs.FS, error) { 19 | return fs.Sub(templates, "templates") 20 | } 21 | 22 | func New(opts *Options) (*genny.Generator, error) { 23 | g := genny.New() 24 | 25 | if err := opts.Validate(); err != nil { 26 | return g, err 27 | } 28 | 29 | data := map[string]interface{}{ 30 | "opts": opts, 31 | } 32 | 33 | sub, err := Templates() 34 | if err != nil { 35 | return g, err 36 | } 37 | 38 | if err := g.FS(sub); err != nil { 39 | return g, err 40 | } 41 | 42 | helpers := template.FuncMap{} 43 | t := gogen.TemplateTransformer(data, helpers) 44 | 45 | g.Transformer(t) 46 | g.Transformer(genny.Dot()) 47 | 48 | // TODO: workaround for 1.16, remove when we upgrade to 1.17 and rename "dot-*" files back to "-dot-*" 49 | g.Transformer(genny.NewTransformer("*", func(f genny.File) (genny.File, error) { 50 | name := f.Name() 51 | if strings.HasPrefix(name, "dot-") { 52 | name = strings.TrimPrefix(name, "dot-") 53 | name = "." + name 54 | } 55 | return genny.NewFile(name, f), nil 56 | })) 57 | 58 | g.Transformer(genny.Replace("/dot-", "/.")) 59 | 60 | return g, nil 61 | } 62 | -------------------------------------------------------------------------------- /internal/cmd/plugins/add.go: -------------------------------------------------------------------------------- 1 | package plugins 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | 7 | "github.com/gobuffalo/cli/internal/genny/add" 8 | "github.com/gobuffalo/cli/internal/plugins/plugdeps" 9 | "github.com/gobuffalo/genny/v2" 10 | "github.com/gobuffalo/meta" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var addOptions = struct { 15 | dryRun bool 16 | buildTags []string 17 | }{} 18 | 19 | var addCmd = &cobra.Command{ 20 | Use: "add", 21 | Short: "adds plugins to config/buffalo-plugins.toml", 22 | RunE: func(cmd *cobra.Command, args []string) error { 23 | run := genny.WetRunner(context.Background()) 24 | if addOptions.dryRun { 25 | run = genny.DryRunner(context.Background()) 26 | } 27 | 28 | app := meta.New(".") 29 | plugs, err := plugdeps.List(app) 30 | if err != nil && !errors.Is(err, plugdeps.ErrMissingConfig) { 31 | return err 32 | } 33 | 34 | tags := app.BuildTags("", addOptions.buildTags...) 35 | for _, a := range args { 36 | plugs.Add(plugdeps.NewPlugin(a, tags)) 37 | } 38 | g, err := add.New(&add.Options{ 39 | App: app, 40 | Plugins: plugs.List(), 41 | }) 42 | if err != nil { 43 | return err 44 | } 45 | if err := run.With(g); err != nil { 46 | return err 47 | } 48 | 49 | return run.Run() 50 | }, 51 | } 52 | 53 | func init() { 54 | addCmd.Flags().BoolVarP(&addOptions.dryRun, "dry-run", "d", false, "dry run") 55 | addCmd.Flags().StringSliceVarP(&addOptions.buildTags, "tags", "t", []string{}, "build tags") 56 | } 57 | -------------------------------------------------------------------------------- /internal/genny/fix/docker.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "html/template" 7 | 8 | "github.com/gobuffalo/cli/internal/genny/docker" 9 | "github.com/gobuffalo/genny/v2" 10 | ) 11 | 12 | func FixDocker(opts *Options) genny.RunFn { 13 | return func(r *genny.Runner) error { 14 | if !opts.App.WithDocker { 15 | return nil 16 | } 17 | 18 | fmt.Println("~~~ Checking Dockerfile ~~~") 19 | 20 | templates, err := docker.Templates() 21 | if err != nil { 22 | return err 23 | } 24 | 25 | tmpl, err := template.New("Dockerfile").ParseFS(templates, "Dockerfile.tmpl") 26 | if err != nil { 27 | return err 28 | } 29 | 30 | dockerOpts := &docker.Options{ 31 | App: opts.App, 32 | } 33 | if err := dockerOpts.Validate(); err != nil { 34 | return err 35 | } 36 | 37 | bb := &bytes.Buffer{} 38 | if err := tmpl.ExecuteTemplate(bb, "Dockerfile.tmpl", map[string]interface{}{ 39 | "opts": dockerOpts, 40 | }); err != nil { 41 | return err 42 | } 43 | 44 | f, err := r.FindFile("Dockerfile") 45 | if err != nil { 46 | return nil 47 | } 48 | 49 | if string(f.String()) == bb.String() { 50 | return nil 51 | } 52 | 53 | if !opts.YesToAll && !ask("Your Dockerfile is different from the latest Buffalo template.\nWould you like to replace yours with the latest template?") { 54 | fmt.Println("\tSkipping Dockerfile") 55 | return nil 56 | } 57 | 58 | if _, err := f.Write(bb.Bytes()); err != nil { 59 | return err 60 | } 61 | return r.File(f) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /internal/genny/assets/standard/standard_test.go: -------------------------------------------------------------------------------- 1 | package standard 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2" 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/stretchr/testify/require" 9 | ) 10 | 11 | func Test_New(t *testing.T) { 12 | r := require.New(t) 13 | 14 | g, err := New(&Options{}) 15 | r.NoError(err) 16 | 17 | run := gentest.NewRunner() 18 | run.Disk.Add(genny.NewFileS("templates/application.plush.html", layout)) 19 | run.LookPathFn = func(s string) (string, error) { 20 | return s, nil 21 | } 22 | 23 | r.NoError(run.With(g)) 24 | r.NoError(run.Run()) 25 | 26 | res := run.Results() 27 | r.Len(res.Commands, 0) 28 | 29 | files := []string{ 30 | "public/assets/application.css", 31 | "public/assets/application.js", 32 | "public/assets/buffalo.css", 33 | "public/assets/images/favicon.ico", 34 | "public/assets/images/logo.svg", 35 | "templates/application.plush.html", 36 | } 37 | 38 | r.Len(res.Files, len(files)) 39 | for i, f := range res.Files { 40 | r.Equal(files[i], f.Name()) 41 | } 42 | 43 | layout, err := res.Find("templates/application.plush.html") 44 | r.NoError(err) 45 | r.Contains(layout.String(), "href=\"https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css\"") 46 | } 47 | 48 | const layout = ` 49 | 50 | 51 | Buffalo - Foo 52 | <%= stylesheetTag("buffalo.css") %> 53 | <%= stylesheetTag("application.css") %> 54 | 55 | 56 | 57 | 58 | ` 59 | -------------------------------------------------------------------------------- /internal/genny/ci/templates/dot-gitlab-ci.yml.tmpl: -------------------------------------------------------------------------------- 1 | before_script: 2 | {{- if eq .opts.DBType "postgres" }} 3 | - apt-get update && apt-get install -y postgresql-client 4 | {{- else if eq .opts.DBType "mysql" }} 5 | - apt-get update && apt-get install -y mysql-client 6 | {{- end }} 7 | - mkdir -p public/assets 8 | - go get -u github.com/gobuffalo/buffalo/buffalo 9 | - go mod download 10 | 11 | stages: 12 | - test 13 | 14 | .test-vars: &test-vars 15 | variables: 16 | GO_ENV: "test" 17 | {{- if eq .opts.DBType "postgres" }} 18 | POSTGRES_DB: "{{.opts.App.Name.File}}_test" 19 | POSTGRES_USER: runner 20 | POSTGRES_PASSSWORD: "" 21 | POSTGRES_HOST_AUTH_METHOD: trust 22 | TEST_DATABASE_URL: "postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}?sslmode=disable" 23 | {{- else if eq .opts.DBType "mysql" }} 24 | MYSQL_DATABASE: "{{.opts.App.Name.File}}_test" 25 | MYSQL_ROOT_PASSWORD: "root" 26 | TEST_DATABASE_URL: "{{.testDbUrl}}" 27 | {{- end }} 28 | 29 | # Golang version choice helper 30 | .use-golang-image: &use-golang-latest 31 | image: golang:latest 32 | 33 | .use-golang-image: &use-golang-1-15 34 | image: golang:1.15 35 | 36 | test: 37 | # Change to "<<: *use-golang-latest" to use the latest Go version 38 | <<: *use-golang-1-15 39 | <<: *test-vars 40 | stage: test 41 | services: 42 | {{- if eq .opts.DBType "mysql" }} 43 | - mysql:5 44 | {{- else if eq .opts.DBType "postgres" }} 45 | - postgres:latest 46 | {{- end }} 47 | script: 48 | - buffalo test 49 | -------------------------------------------------------------------------------- /internal/genny/fix/plush.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | 9 | "github.com/gobuffalo/genny/v2" 10 | ) 11 | 12 | // UpdatePlushTemplates will update foo.html templates to foo.plush.html templates 13 | func UpdatePlushTemplates(opts *Options) genny.RunFn { 14 | return func(r *genny.Runner) error { 15 | fmt.Println("~~~ Adding .plush extension to .html/.js/.md files ~~~") 16 | err := walkDisk(r.Disk, "templates", func(path string, info os.FileInfo, err error) error { 17 | if err != nil { 18 | return err 19 | } 20 | 21 | if info.IsDir() { 22 | return nil 23 | } 24 | 25 | dir := filepath.Dir(path) 26 | base := filepath.Base(path) 27 | 28 | var exts []string 29 | ext := filepath.Ext(base) 30 | switch ext { 31 | case ".html": 32 | case ".js": 33 | case ".md": 34 | default: 35 | return nil 36 | } 37 | 38 | for len(ext) != 0 { 39 | if ext == ".plush" || ext == ".fizz" { 40 | return nil 41 | } 42 | exts = append([]string{ext}, exts...) 43 | base = strings.TrimSuffix(base, ext) 44 | ext = filepath.Ext(base) 45 | } 46 | exts = append([]string{base, ".plush"}, exts...) 47 | pathNew := filepath.Join(dir, strings.Join(exts, "")) 48 | 49 | fo, err := r.FindFile(path) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | fn := genny.NewFile(pathNew, fo) 55 | if err := r.File(fn); err != nil { 56 | return err 57 | } 58 | return r.Delete(path) 59 | }) 60 | return err 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /internal/plugins/plugdeps/plugin.go: -------------------------------------------------------------------------------- 1 | package plugdeps 2 | 3 | import ( 4 | "encoding/json" 5 | "os" 6 | "regexp" 7 | "strings" 8 | 9 | "github.com/gobuffalo/meta" 10 | ) 11 | 12 | // bin, module version, and tag 13 | var re = regexp.MustCompile(`.*(buffalo-[^/@]+)/?(v[0-9]+)?@?(.*)?`) 14 | 15 | // Plugin represents a Go plugin for Buffalo applications 16 | type Plugin struct { 17 | Binary string `toml:"binary" json:"binary"` 18 | GoGet string `toml:"go_get,omitempty" json:"go_get,omitempty"` 19 | Local string `toml:"local,omitempty" json:"local,omitempty"` 20 | Commands []Command `toml:"command,omitempty" json:"commands,omitempty"` 21 | Tags meta.BuildTags `toml:"tags,omitempty" json:"tags,omitempty"` 22 | } 23 | 24 | // String implementation of fmt.Stringer 25 | func (p Plugin) String() string { 26 | b, _ := json.Marshal(p) 27 | return string(b) 28 | } 29 | 30 | func (p Plugin) key() string { 31 | // p.Binary should be uniq and it can be used as the key 32 | return p.Binary 33 | } 34 | 35 | func NewPlugin(mod string, tags ...meta.BuildTags) Plugin { 36 | mod = strings.TrimSpace(mod) 37 | match := re.FindStringSubmatch(mod) 38 | bin := match[1] 39 | tag := match[3] 40 | plug := Plugin{ 41 | Binary: bin, 42 | GoGet: mod, 43 | } 44 | if len(tags) > 0 { 45 | plug.Tags = tags[0] 46 | } 47 | if _, err := os.Stat(mod); err == nil { 48 | plug.Local = mod 49 | plug.GoGet = "" 50 | } 51 | if plug.GoGet != "" && tag == "" { 52 | plug.GoGet = mod + "@latest" 53 | } 54 | return plug 55 | } 56 | -------------------------------------------------------------------------------- /internal/genny/ci/options.go: -------------------------------------------------------------------------------- 1 | package ci 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/gobuffalo/cli/internal/runtime" 8 | "github.com/gobuffalo/meta" 9 | "github.com/gobuffalo/pop/v6" 10 | ) 11 | 12 | // Available CI implementations 13 | var Available = []string{"circleci", "github", "gitlab", "travis"} 14 | 15 | // Options for CI 16 | type Options struct { 17 | App meta.App 18 | DBType string 19 | Provider string 20 | Version string 21 | } 22 | 23 | // Validate that options are usuable 24 | func (opts *Options) Validate() error { 25 | if opts.App.IsZero() { 26 | opts.App = meta.New(".") 27 | } 28 | 29 | if len(opts.Version) == 0 { 30 | opts.Version = runtime.Version 31 | } 32 | 33 | if len(opts.Provider) == 0 { 34 | return fmt.Errorf("no provider chosen") 35 | } 36 | opts.Provider = strings.ToLower(opts.Provider) 37 | 38 | var found bool 39 | for _, a := range Available { 40 | if opts.Provider == a { 41 | found = true 42 | break 43 | } 44 | if opts.Provider == a+"-ci" { 45 | opts.Provider = a 46 | found = true 47 | break 48 | } 49 | } 50 | if !found { 51 | return fmt.Errorf("unknown provider %s expecting one of %s", opts.Provider, strings.Join(Available, ", ")) 52 | } 53 | 54 | found = false 55 | for _, d := range pop.AvailableDialects { 56 | if d == opts.DBType { 57 | found = true 58 | break 59 | } 60 | } 61 | if !found { 62 | return fmt.Errorf("unknown dialect %q expecting one of %s", opts.DBType, strings.Join(pop.AvailableDialects, ", ")) 63 | } 64 | return nil 65 | } 66 | -------------------------------------------------------------------------------- /internal/genny/docker/templates/Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | # This is a multi-stage Dockerfile and requires >= Docker 17.05 2 | # https://docs.docker.com/engine/userguide/eng-image/multistage-build/ 3 | FROM gobuffalo/buffalo:{{.opts.Version}} as builder 4 | 5 | ENV GOPROXY http://proxy.golang.org 6 | 7 | RUN mkdir -p /src/{{.opts.App.PackagePkg}} 8 | WORKDIR /src/{{.opts.App.PackagePkg}} 9 | 10 | {{if .opts.App.WithWebpack -}} 11 | # this will cache the npm install step, unless package.json changes 12 | ADD package.json . 13 | {{if .opts.App.WithYarn -}} 14 | ADD yarn.lock .yarnrc.yml ./ 15 | RUN mkdir .yarn 16 | COPY .yarn .yarn 17 | RUN yarn install 18 | {{else -}} 19 | RUN npm install --no-progress 20 | {{end -}} 21 | {{end -}} 22 | 23 | # Copy the Go Modules manifests 24 | COPY go.mod go.mod 25 | COPY go.sum go.sum 26 | # cache deps before building and copying source so that we don't need to re-download as much 27 | # and so that source changes don't invalidate our downloaded layer 28 | RUN go mod download 29 | 30 | ADD . . 31 | RUN buffalo build --static -o /bin/app 32 | 33 | FROM alpine 34 | RUN apk add --no-cache bash 35 | RUN apk add --no-cache ca-certificates 36 | 37 | WORKDIR /bin/ 38 | 39 | COPY --from=builder /bin/app . 40 | 41 | # Uncomment to run the binary in "production" mode: 42 | # ENV GO_ENV=production 43 | 44 | # Bind the app to 0.0.0.0 so it can be seen from outside the container 45 | ENV ADDR=0.0.0.0 46 | 47 | EXPOSE 3000 48 | 49 | # Uncomment to run the migrations before running the binary: 50 | # CMD /bin/app migrate; /bin/app 51 | CMD exec /bin/app 52 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | builds: 2 | - main: ./cmd/buffalo/main.go 3 | binary: buffalo 4 | env: 5 | - CGO_ENABLED=0 6 | ldflags: 7 | - -s -w -X "github.com/gobuffalo/cli/internal/runtime.Version={{ .Tag }}" 8 | goos: 9 | - darwin 10 | - linux 11 | - windows 12 | goarch: 13 | - amd64 14 | - 386 15 | - arm 16 | - arm64 17 | goarm: 18 | - 6 19 | - 7 20 | archives: 21 | - name_template: "buffalo_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}{{ if .Mips }}_{{ .Mips }}{{ end }}" 22 | replacements: 23 | '386': i386 24 | darwin: Darwin 25 | linux: Linux 26 | windows: Windows 27 | amd64: x86_64 28 | checksum: 29 | name_template: checksums.txt 30 | snapshot: 31 | name_template: '{{ .Tag }}-next' 32 | changelog: 33 | sort: asc 34 | filters: 35 | exclude: 36 | - '^docs:' 37 | - '^test:' 38 | brews: 39 | - name: 'buffalo' 40 | tap: 41 | owner: 'gobuffalo' 42 | name: 'homebrew-tap' 43 | install: | 44 | bin.install "buffalo" 45 | 46 | dockers: 47 | - 48 | image_templates: 49 | - gobuffalo/buffalo:{{ .Tag }} 50 | - gobuffalo/buffalo:latest 51 | dockerfile: 'Dockerfile.build' 52 | goos: linux 53 | goarch: amd64 54 | use: docker 55 | 56 | - 57 | image_templates: 58 | - gobuffalo/buffalo:{{ .Tag }}-slim 59 | - gobuffalo/buffalo:latest-slim 60 | dockerfile: 'Dockerfile.slim.build' 61 | goos: linux 62 | goarch: amd64 63 | use: docker 64 | 65 | -------------------------------------------------------------------------------- /internal/genny/newapp/core/templates/README.md.tmpl: -------------------------------------------------------------------------------- 1 | # Welcome to Buffalo 2 | 3 | Thank you for choosing Buffalo for your web development needs. 4 | 5 | {{ if .opts.App.WithPop -}} 6 | ## Database Setup 7 | 8 | It looks like you chose to set up your application using a database! Fantastic! 9 | 10 | The first thing you need to do is open up the "database.yml" file and edit it to use the correct usernames, passwords, hosts, etc... that are appropriate for your environment. 11 | 12 | You will also need to make sure that **you** start/install the database of your choice. Buffalo **won't** install and start it for you. 13 | 14 | ### Create Your Databases 15 | 16 | Ok, so you've edited the "database.yml" file and started your database, now Buffalo can create the databases in that file for you: 17 | 18 | ```console 19 | buffalo pop create -a 20 | ``` 21 | 22 | {{ end -}} 23 | 24 | ## Starting the Application 25 | 26 | Buffalo ships with a command that will watch your application and automatically rebuild the Go binary and any assets for you. To do that run the "buffalo dev" command: 27 | 28 | ```console 29 | buffalo dev 30 | ``` 31 | 32 | If you point your browser to [http://127.0.0.1:3000](http://127.0.0.1:3000) you should see a "Welcome to Buffalo!" page. 33 | 34 | **Congratulations!** You now have your Buffalo application up and running. 35 | 36 | ## What Next? 37 | 38 | We recommend you heading over to [http://gobuffalo.io](http://gobuffalo.io) and reviewing all of the great documentation there. 39 | 40 | Good luck! 41 | 42 | [Powered by Buffalo](http://gobuffalo.io) 43 | -------------------------------------------------------------------------------- /internal/genny/fix/webpack_test.go: -------------------------------------------------------------------------------- 1 | package fix 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/gobuffalo/genny/v2" 7 | "github.com/gobuffalo/genny/v2/gentest" 8 | "github.com/gobuffalo/meta" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func Test_WebpackCheck_NoOverwriteExisting(t *testing.T) { 13 | r := require.New(t) 14 | 15 | opts := &Options{ 16 | App: meta.App{ 17 | Root: ".", 18 | WithWebpack: true, 19 | }, 20 | } 21 | 22 | run := gentest.NewRunner() 23 | bb, err := defaultWebpack(opts.App) 24 | r.NoError(err) 25 | fileContents := bb.String() 26 | r.NoError(run.File(genny.NewFileS("webpack.config.js", fileContents))) 27 | 28 | run.WithRun(WebpackCheck(opts)) 29 | r.NoError(run.Run()) 30 | 31 | results := run.Results() 32 | f := results.Files[0] 33 | r.Equal("webpack.config.js", f.Name()) 34 | r.Equal(fileContents, f.String()) 35 | } 36 | 37 | func Test_WebpackCheck_UpdatingFile(t *testing.T) { 38 | r := require.New(t) 39 | 40 | opts := &Options{ 41 | App: meta.App{ 42 | Root: ".", 43 | WithWebpack: true, 44 | }, 45 | YesToAll: true, 46 | } 47 | 48 | bb, err := defaultWebpack(opts.App) 49 | r.NoError(err) 50 | fileContents := bb.String() 51 | 52 | run := gentest.NewRunner() 53 | r.NoError(run.File(genny.NewFileS("webpack.config.js", "console.log('hello world')"))) 54 | 55 | run.WithRun(WebpackCheck(opts)) 56 | r.NoError(run.Run()) 57 | 58 | results := run.Results() 59 | 60 | f := results.Files[0] 61 | r.Equal("webpack.config.js", f.Name()) 62 | r.Equal(fileContents, f.String()) 63 | } 64 | --------------------------------------------------------------------------------