Giter VIP home page Giter VIP logo

bud's People

Contributors

012e avatar barelyhuman avatar codenoid avatar cuishuang avatar jfmario avatar joshuatalb avatar mamil avatar matthewmueller avatar syke99 avatar techplexengineer avatar theeyed avatar thepudds avatar tlylt avatar vito avatar wheinze avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bud's Issues

Trouble with nested routes

I ran:

bud new controller associations index show
bud new controller academies index show
bud new controller associations/academies index show

This laid out out the appropriate controllers in the /controller directory. However, I'm getting an error

bud/.app/controller/controller.go:9:2: imported and not used: "bud-test/controller/associations/academies" as academies1

looking at bud/.app/controller/controller.go, we can see that bud-test/controller/associations/academies is imported at as academies1 but that import isn't used. I can't delete it because the framework automatically generates it again.

Is there a correct way to create nested controllers like this?

package controller

import (
	view "bud-test/bud/.app/view"
	controller "bud-test/controller"
	academies "bud-test/controller/academies"
	members "bud-test/controller/academies/members"
	associations "bud-test/controller/associations"
	academies1 "bud-test/controller/associations/academies"
	users "bud-test/controller/users"
	request "github.com/livebud/bud/runtime/controller/request"
	response "github.com/livebud/bud/runtime/controller/response"
	http "net/http"
)

// Controller struct
type Controller struct {
	Index        *IndexAction
	Show         *ShowAction
	Academies    *AcademiesController
	Associations *AssociationsController
	Users        *UsersController
}

// IndexAction struct
type IndexAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (i *IndexAction) Key() string {
	return "/index"
}

// Path is the default RESTful path to this action
func (i *IndexAction) Path() string {
	return "/"
}

// Method is the default RESTful method of this action
func (i *IndexAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (i *IndexAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	i.handler(r).ServeHTTP(w, r)
}

// Handler function
func (i *IndexAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	controllerController := loadController()
	fn := controllerController.Index
	// Call the controller
	stories, err := fn(
		httpRequest.Context(),
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: i.View.Handler("/", map[string]interface{}{"stories": stories}),
		JSON: response.JSON(stories),
	}
}

// ShowAction struct
type ShowAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (s *ShowAction) Key() string {
	return "/show"
}

// Path is the default RESTful path to this action
func (s *ShowAction) Path() string {
	return "/:id"
}

// Method is the default RESTful method of this action
func (s *ShowAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (s *ShowAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.handler(r).ServeHTTP(w, r)
}

// Handler function
func (s *ShowAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
		ID int `json:"id,omitempty"`
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	controllerController := loadController()
	fn := controllerController.Show
	// Call the controller
	story, err := fn(
		httpRequest.Context(),
		in.ID,
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: s.View.Handler("/:id", map[string]interface{}{"story": story}),
		JSON: response.JSON(story),
	}
}

// Controller struct
type AcademiesController struct {
	Index   *AcademiesIndexAction
	Show    *AcademiesShowAction
	Members *AcademiesMembersController
}

// AcademiesIndexAction struct
type AcademiesIndexAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (i *AcademiesIndexAction) Key() string {
	return "/academies/index"
}

// Path is the default RESTful path to this action
func (i *AcademiesIndexAction) Path() string {
	return "/academies"
}

// Method is the default RESTful method of this action
func (i *AcademiesIndexAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (i *AcademiesIndexAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	i.handler(r).ServeHTTP(w, r)
}

// Handler function
func (i *AcademiesIndexAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	academiesController := loadAcademiesController()
	fn := academiesController.Index
	// Call the controller
	academies, err := fn(
		httpRequest.Context(),
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: i.View.Handler("/academies", map[string]interface{}{"academies": academies}),
		JSON: response.JSON(academies),
	}
}

// AcademiesShowAction struct
type AcademiesShowAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (s *AcademiesShowAction) Key() string {
	return "/academies/show"
}

// Path is the default RESTful path to this action
func (s *AcademiesShowAction) Path() string {
	return "/academies/:id"
}

// Method is the default RESTful method of this action
func (s *AcademiesShowAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (s *AcademiesShowAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.handler(r).ServeHTTP(w, r)
}

// Handler function
func (s *AcademiesShowAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
		ID int `json:"id,omitempty"`
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	academiesController := loadAcademiesController()
	fn := academiesController.Show
	// Call the controller
	academy, err := fn(
		httpRequest.Context(),
		in.ID,
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: s.View.Handler("/academies/:id", map[string]interface{}{"academy": academy}),
		JSON: response.JSON(academy),
	}
}

// Controller struct
type AcademiesMembersController struct {
	Index *AcademiesMembersIndexAction
	Show  *AcademiesMembersShowAction
}

// AcademiesMembersIndexAction struct
type AcademiesMembersIndexAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (i *AcademiesMembersIndexAction) Key() string {
	return "/academies/members/index"
}

// Path is the default RESTful path to this action
func (i *AcademiesMembersIndexAction) Path() string {
	return "/academies/:academy_id/members"
}

// Method is the default RESTful method of this action
func (i *AcademiesMembersIndexAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (i *AcademiesMembersIndexAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	i.handler(r).ServeHTTP(w, r)
}

// Handler function
func (i *AcademiesMembersIndexAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	membersController := loadAcademiesMembersController()
	fn := membersController.Index
	// Call the controller
	members, err := fn(
		httpRequest.Context(),
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: i.View.Handler("/academies/:academy_id/members", map[string]interface{}{"members": members}),
		JSON: response.JSON(members),
	}
}

// AcademiesMembersShowAction struct
type AcademiesMembersShowAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (s *AcademiesMembersShowAction) Key() string {
	return "/academies/members/show"
}

// Path is the default RESTful path to this action
func (s *AcademiesMembersShowAction) Path() string {
	return "/academies/:academy_id/members/:id"
}

// Method is the default RESTful method of this action
func (s *AcademiesMembersShowAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (s *AcademiesMembersShowAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.handler(r).ServeHTTP(w, r)
}

// Handler function
func (s *AcademiesMembersShowAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
		ID int `json:"id,omitempty"`
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	membersController := loadAcademiesMembersController()
	fn := membersController.Show
	// Call the controller
	member, err := fn(
		httpRequest.Context(),
		in.ID,
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: s.View.Handler("/academies/:academy_id/members/:id", map[string]interface{}{"member": member}),
		JSON: response.JSON(member),
	}
}

// Controller struct
type AssociationsController struct {
	Index     *AssociationsIndexAction
	Show      *AssociationsShowAction
	Academies *AssociationsAcademiesController
}

// AssociationsIndexAction struct
type AssociationsIndexAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (i *AssociationsIndexAction) Key() string {
	return "/associations/index"
}

// Path is the default RESTful path to this action
func (i *AssociationsIndexAction) Path() string {
	return "/associations"
}

// Method is the default RESTful method of this action
func (i *AssociationsIndexAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (i *AssociationsIndexAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	i.handler(r).ServeHTTP(w, r)
}

// Handler function
func (i *AssociationsIndexAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	associationsController := loadAssociationsController()
	fn := associationsController.Index
	// Call the controller
	associations, err := fn(
		httpRequest.Context(),
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: i.View.Handler("/associations", map[string]interface{}{"associations": associations}),
		JSON: response.JSON(associations),
	}
}

// AssociationsShowAction struct
type AssociationsShowAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (s *AssociationsShowAction) Key() string {
	return "/associations/show"
}

// Path is the default RESTful path to this action
func (s *AssociationsShowAction) Path() string {
	return "/associations/:id"
}

// Method is the default RESTful method of this action
func (s *AssociationsShowAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (s *AssociationsShowAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.handler(r).ServeHTTP(w, r)
}

// Handler function
func (s *AssociationsShowAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
		ID int `json:"id,omitempty"`
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	associationsController := loadAssociationsController()
	fn := associationsController.Show
	// Call the controller
	association, err := fn(
		httpRequest.Context(),
		in.ID,
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: s.View.Handler("/associations/:id", map[string]interface{}{"association": association}),
		JSON: response.JSON(association),
	}
}

// Controller struct
type AssociationsAcademiesController struct {
	Index *AssociationsAcademiesIndexAction
	Show  *AssociationsAcademiesShowAction
}

// AssociationsAcademiesIndexAction struct
type AssociationsAcademiesIndexAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (i *AssociationsAcademiesIndexAction) Key() string {
	return "/associations/academies/index"
}

// Path is the default RESTful path to this action
func (i *AssociationsAcademiesIndexAction) Path() string {
	return "/associations/:association_id/academies"
}

// Method is the default RESTful method of this action
func (i *AssociationsAcademiesIndexAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (i *AssociationsAcademiesIndexAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	i.handler(r).ServeHTTP(w, r)
}

// Handler function
func (i *AssociationsAcademiesIndexAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	academiesController := loadAssociationsAcademiesController()
	fn := academiesController.Index
	// Call the controller
	academies, err := fn(
		httpRequest.Context(),
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: i.View.Handler("/associations/:association_id/academies", map[string]interface{}{"academies": academies}),
		JSON: response.JSON(academies),
	}
}

// AssociationsAcademiesShowAction struct
type AssociationsAcademiesShowAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (s *AssociationsAcademiesShowAction) Key() string {
	return "/associations/academies/show"
}

// Path is the default RESTful path to this action
func (s *AssociationsAcademiesShowAction) Path() string {
	return "/associations/:association_id/academies/:id"
}

// Method is the default RESTful method of this action
func (s *AssociationsAcademiesShowAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (s *AssociationsAcademiesShowAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.handler(r).ServeHTTP(w, r)
}

// Handler function
func (s *AssociationsAcademiesShowAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
		ID int `json:"id,omitempty"`
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	academiesController := loadAssociationsAcademiesController()
	fn := academiesController.Show
	// Call the controller
	academy, err := fn(
		httpRequest.Context(),
		in.ID,
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: s.View.Handler("/associations/:association_id/academies/:id", map[string]interface{}{"academy": academy}),
		JSON: response.JSON(academy),
	}
}

// Controller struct
type UsersController struct {
	Index *UsersIndexAction
	Show  *UsersShowAction
}

// UsersIndexAction struct
type UsersIndexAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (i *UsersIndexAction) Key() string {
	return "/users/index"
}

// Path is the default RESTful path to this action
func (i *UsersIndexAction) Path() string {
	return "/users"
}

// Method is the default RESTful method of this action
func (i *UsersIndexAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (i *UsersIndexAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	i.handler(r).ServeHTTP(w, r)
}

// Handler function
func (i *UsersIndexAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	usersController := loadUsersController()
	fn := usersController.Index
	// Call the controller
	users, err := fn(
		httpRequest.Context(),
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: i.View.Handler("/users", map[string]interface{}{"users": users}),
		JSON: response.JSON(users),
	}
}

// UsersShowAction struct
type UsersShowAction struct {
	View *view.Server
}

// Key is a unique identifier of this action
func (s *UsersShowAction) Key() string {
	return "/users/show"
}

// Path is the default RESTful path to this action
func (s *UsersShowAction) Path() string {
	return "/users/:id"
}

// Method is the default RESTful method of this action
func (s *UsersShowAction) Method() string {
	return "GET"
}

// ServeHTTP fn
func (s *UsersShowAction) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	s.handler(r).ServeHTTP(w, r)
}

// Handler function
func (s *UsersShowAction) handler(httpRequest *http.Request) http.Handler {
	// Define the input struct
	var in struct {
		ID int `json:"id,omitempty"`
	}
	// Unmarshal the request body
	if err := request.Unmarshal(httpRequest, &in); err != nil {
		return &response.Format{
			JSON: response.Status(400).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}
	usersController := loadUsersController()
	fn := usersController.Show
	// Call the controller
	user, err := fn(
		httpRequest.Context(),
		in.ID,
	)
	if err != nil {
		return &response.Format{
			JSON: response.Status(500).Set("Content-Type", "application/json").JSON(map[string]string{"error": err.Error()}),
		}
	}

	// Respond
	return &response.Format{
		HTML: s.View.Handler("/users/:id", map[string]interface{}{"user": user}),
		JSON: response.JSON(user),
	}
}

func loadAcademiesController() *academies.Controller {
	academiesController := &academies.Controller{}
	return academiesController
}

func loadAcademiesMembersController() *members.Controller {
	membersController := &members.Controller{}
	return membersController
}

func loadAssociationsAcademiesController() *academies.Controller {
	academiesController := &academies.Controller{}
	return academiesController
}

func loadAssociationsController() *associations.Controller {
	associationsController := &associations.Controller{}
	return associationsController
}

func loadController() *controller.Controller {
	controllerController := &controller.Controller{}
	return controllerController
}

func loadUsersController() *users.Controller {
	usersController := &users.Controller{}
	return usersController
}

run error

Hello, After I bud build the project, I remove the *.go and go.mod source files. run ./bud/app in the terminal, but it output the error: unable to find go.mod: file does not exist in "/Users/Works/news"

---- for exmaple input the command in the terminal
news % ./bud/app
unable to find go.mod: file does not exist in "/Users/Works/news"

Why the app is running and it needs to depend go.mod?

Linux/arm64 platform support

I tried running the installer in Termux, please add termux support XD.

livebud/bud: platform linux/arm64 is not supported.  Make sure this script is up-to-date and file request at https://github.com/livebud/bud/issues/new

Update the runtime on existing projects for new versions of bud

In v0.1.5, there were some breaking changes to the runtime. If you had an existing application and ran bud run, you'd get the following error:

| conjure: generate "bud/.cli/program/program.go". program: unable to wire > di: unable to wire "github.com/livebud/basic/bud/.cli/program".loadCLI function. parser: unable to import package "bud/.cli/command". conjure: generate "bud/.cli/command/command.go". command: unable to parse. di: unable to wire "github.com/livebud/basic/bud/.cli/command".loadGenerator function. di: unclear how to provide "github.com/livebud/bud/runtime/bud".*Flag.

To fix this, you'll need to run go get -u github.com/livebud/[email protected] to get the current runtime.

The runtime and the CLI are designed to be in lockstep with each other. The CLI should check and update the runtime when it's out of step.

Cryptic panic when livereload server fails to start

There's a couple issues here that need to be fixed:

  1. For some reason the hot reload port wasn't released, despite the application port being released. I'm not able to reproduce this behavior at the moment, so let's just keep an eye on it for now.

  2. Nil pointer panic on *exe.Close

    panic: runtime error: invalid memory address or nil pointer dereference
    				panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0xa0 pc=0x148aa70]
    
    goroutine 66 [running]:
    github.com/livebud/bud/package/exe.(*Cmd).Close(0x0)
    				/Users/m/dev/src/github.com/livebud/bud/package/exe/command.go:24 +0x70
    panic({0x151a1a0, 0x19de710})
    				/usr/local/go/src/runtime/panic.go:838 +0x207
    os/exec.(*Cmd).Wait(0x173cec0?)
    				/usr/local/go/src/os/exec/exec.go:499 +0x18
    github.com/livebud/bud/package/exe.(*Cmd).Wait(...)
    				/Users/m/dev/src/github.com/livebud/bud/package/exe/command.go:39
    github.com/livebud/bud/runtime/command/run.(*Command).startApp(0xc000256f60, {0x173cec0?, 0xc00024d300}, 0xc000243490)
    				/Users/m/dev/src/github.com/livebud/bud/runtime/command/run/run.go:115 +0x3c5
    github.com/livebud/bud/runtime/command/run.(*Command).Run.func2()
    				/Users/m/dev/src/github.com/livebud/bud/runtime/command/run/run.go:37 +0x29
    golang.org/x/sync/errgroup.(*Group).Go.func1()
    				/Users/m/dev/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:74 +0x64
    created by golang.org/x/sync/errgroup.(*Group).Go
    				/Users/m/dev/pkg/mod/golang.org/x/[email protected]/errgroup/errgroup.go:71 +0xa5
    

    The problem is that process is nil for some reason when calling the following:

    defer process.Close()

  3. Need a better error for unable to start the live reload server. Perhaps:

    fmt.Errorf("Error starting the live reload server on %s: %w", address, err)

    Eventually, I'd like to find a free port and propagate the change accordingly, but for now, I think we just supply a better error.

Steps to reproduce

  1. This can be reproduced by altering the following:

func (c *Command) startHot(ctx context.Context, hotServer *hot.Server) error {
// TODO: host should be dynamic
return hotServer.ListenAndServe(ctx, "127.0.0.1:35729")
}

func (c *Command) startHot(ctx context.Context, hotServer *hot.Server) error {
	// TODO: host should be dynamic
+	return fmt.Errorf("failed to listen")
-	return hotServer.ListenAndServe(ctx, "127.0.0.1:35729")
}
  1. Within the bud repository, call go run main.go -C examples/hn run

Removals & renames don't trigger a recompile

Hi @matthewmueller, First of all, Thanks for building this bud !!

I thought of learning this by giving a try, so here is an understanding question:

So, I was able to install the bud, create the app, was able to see bud home page with the nice splash. Now I tried this command bud new controller photos show index and then was able to see the index page in the browser with the nice title. All good until here.

Now, I wanted to rename the photos to photo, so I thought of deleting the folders/files and retype bud new... and deleted the photos directory present in both the controllers & views directory & did go mod tidy and it ended up showing this error:

โฏ go mod tidy
go: finding module for package github.com/kishorevaishnav/shinyroll/controller/photos
github.com/kishorevaishnav/shinyroll/bud imports
        github.com/kishorevaishnav/shinyroll/bud/.app/program imports
        github.com/kishorevaishnav/shinyroll/bud/.app/web imports
        github.com/kishorevaishnav/shinyroll/bud/.app/controller imports
        github.com/kishorevaishnav/shinyroll/controller/photos: no matching versions for query "latest"

I tried to find the word photos in the entire directory and couldn't find any word of it, rather than fixing this or reverting the code, would like to understand where is this cached? & what is the logic behind it. If you can give me some insight and direct me some files to understand will be of great help.

P.S. Apologize if this shouldn't be posted here - not sure where to ask these kind of questions.

Proper hot reload message

Changing a single line of code while running bud run generate 4 lines of Ready on localhost:3000 but not much useful information.
Is it supposed to work like that or something?

What about mimicking vite's?
image

ARM Support

I was doing install script in my macbook air m1
$ curl -sf curl https://raw.githubusercontent.com/livebud/bud/main/install.sh | sh

then I got this error
livebud/bud: platform darwin/arm64 is not supported. Make sure this script is up-to-date and file request at https://github.com/livebud/bud/issues/new

Return helpful errors

Whenever a request doesn't match the controller's signature, we should return a 400 Bad Request with a helpful error:

For example, given the following signature:

func (c *Controller) Create(name, email string) {}

With the following request map:

{
  "name": 123
}

We should return the following response:

{
  "error": "name must be a string and email can't be blank",
  "fields": {
    "name": "must be a string",
    "email": "can't be blank"
  }
}

Errors should also be helpful for nested inputs:

{
  "error": "version can't be blank",
  "fields": {
    "op.params[1].version": "can't be blank"
  }
}

Use js extensions for page entrypoints

Right now we have entrypoints that have the following format: bud/view/{controller}/\_{action}.{ext}, so for bud/view/index.svelte, the entrypoint would look like bud/view/_index.svelte.

This was nice for understanding the mapping, but doesn't play well with tools that use the extension to determine the content-type, since those served svelte files are actually javascript.

Let's change this, perhaps:

  • .bud/view/index.entry.svelte.js: entrypoint for view/index.svelte (includes hydration + event sourcing)
  • .bud/view/index.svelte.js: compiled view/index.svelte component

Nested view URL don't prefix the URL with the nested route

I created nested views with running the command.

bud new controller post index show

It generated the files fine but when I opened the /post URL, the td element didn't include prefix the URL with the /post instead it relative to the root.

image

image

I'm not sure whether I was suppose to update the URL manually or not as it's a minor thing.

I wanna give my time to this project.

Hi @matthewmueller, I was thinking of creating a Django like framework in golang too. I came across your project and it has almost everything that I was looking for.

  • Go
  • Svelte
  • Simplicity

I would like you to know I will be happy to help this project grow. Please do let me know what helps do you need.

Plugins that contain controllers don't compile yet

Given the following plugin with the module path plugin.com

bud-admin/
  controller/
    admin/
      admin.go
plugin.go
go.mod

And an application with the following module path app.com, if you run bud build, you'll get the following:

error: mod: unable to resolve directory for package path "app.com/controller/admin": stat 
controller/admin: no such file or directory

While bud has successfully bundled the admin controller from plugin.com into app.com, it's messed up the import paths:

  • Actual: app.com/controller/admin
  • Expected: plugin.com/controller/admin

Support `setInterval`

Not sure if it's related but localStorage, window, document, setInterval, etc have a weird behavior too.

view: render error ReferenceError: setInterval is not defined

when wrapped inside a if (typeof document != "undefined") or anything that v8 will appreciate, everything is fine, console.log included

Originally posted by @ldlac in #87 (comment)

204 No Content improvements

For example,

func (c *Controller) Create() {
  // do something
}

These functions should return 204 No Content if successful.

Unable to live reload after SSR error

Currently when there's a server-side rendering error, that you subsequently fix, you'll need to refresh the page again. This is likely because the event source isn't hooked up to that error yet.

Steps to reproduce:

  1. Create a view with an error
<script>
  export let _string = ""
  a.b = 'c'
</script>

<h1>{_string}</h1>

<style>
  h1 {
    background: blue;
    padding: 20px;
    color: white;
  }
</style>
  1. Make a change to the controller:
package controller

type Controller struct {
}

func (c *Controller) Index() string {
	return "hello world."
}

func (c *Controller) Show(id string) string {
	return "shows/" + id
}

And you'll see something like ReferenceError: a is not defined in the browser. Even if you fix the problem in Svelte, it won't refresh.

Add M1 binary support

Need to make this happen! Two requests so far from @kuldar and @sid405 ๐Ÿ˜Š

From Sidd:

I was able to get Bud running under Rosetta 2 by starting a Rosetta2 shell: arch -arch x86_64 zsh. I have this aliased to rosetta because I need it every once in a while.

View receiving empty objects

I have made a new controller user bud new controller users index show. This scaffolded the controller and view as expected.
I then modified the controller to :


import (
	context "context"
)

type Controller struct {
	// Dependencies...
}

// User struct
type User struct {
	id        int
	firstName string
	lastName  string
}

// Index of users
// GET /users
func (c *Controller) Index(ctx context.Context) (users []*User, err error) {

	var u1 = User{1, "firstname", "lastname"}
	users = append(users, &u1)
	return users, err

}

// Show user
// GET /users/:id
func (c *Controller) Show(ctx context.Context, id int) (user *User, err error) {
	return &User{}, nil
}

When I go to http://127.0.0.1:3000/users, I only see the scaffolded header "User Index". Unsure of what what happening, since the table wasn't displayed, I added another header:
<h1>{JSON.stringify(users)}</h1> to inspect the content of the users variable inside of index.svelte

This displays with

[{}]

This suggests that an object is being serialized, but the contents of the objects are being discarded somewhere.

Am I doing something wrong?

Plans for shipping with Vue?

According to the demo video, bud is agnostic to front end frameworks, but currently only ships with Svelte and planned to ship with React in the future. Just curious if there are plans to ship with Vue as a friend of mine and I are currently working on a Go/Vue project

Error creating new project

I followed the instruction to install bud, and bud create app doesn't work

bud

  • OS: Arch linux
  • go: version 1.18.2
  • node: v14.19.2

bud tool cache clean vs bud tool cache clear

Notion docs show

# Clear the build cache
bud tool cache clear

cli uses clean instead of clear

$ bud version
     bud: 0.1.1
  svelte: 3.47.0
   react: 18.0.0
$ bud tool cache

  Usage:
    cache [command]

  Commands:
    clean  Clear the cache directory

Move docs off notion into docusaurus or something?

Notion is a dumpster fire, you have full access to github pages and a million other things, please setup something actually usable. Docusaurus, Jekyll, Hugo and a bunch of other SSGs will create docs (can even be searchable) from markdown source (which I'm p sure you can export from Notion).

Doesn't support GOPATH with multiple directories

I've just been attempting to try out bud, but ran into issues before I could get going.
Granted, I've not got far into learning Go, I thought bud would help to give me a gentler start to creating a web app, so I may be missing something that is considered "basic Go knowledge".

I've followed your example to get going:

and I get presented with the following:

~/code/go/src/github.com/techwilk/test-bud$ bud run
| Listening on http://127.0.0.1:3000
| conjure: generate "bud/.cli/program/program.go" > program: unable to wire > di: unable to find definition for param "github.com/livebud/bud/runtime/bud".*Flag within "github.com/techwilk/test-bud/bud/.cli/command".*CLI > stat /home/user/go:/home/user/code/go/pkg/mod/github.com/livebud/[email protected]: no such file or directory

I've previously had Go 1.17, but upgraded to 1.18.2 which didn't change anything.

WSL 2 - Cannot create new project

Been using go for a while and have been looking for a framework like bud for a while.

I installed bud using the install script, then when trying to create a new project using bud create hello the installed runs some things happen however the cli get stuck ( see screenshot).

image

No new folders appear inside of the directory and the terminal is stuck.

Add Example: With DI

Bud's impressive and I understand it's just 0.1, so it would be highly ambitious(and very, very early) to expect a very good documentation, blog and example ecosystem. But, just to give it a consideration as a very low priority task - will it be possible for you to consider adding an example with DI(Env, DB, etc.) ? I'm not a seasoned Go dev, and I think seeing a good example with DI can help anybody like me, even the developers that Bud might inevitably attract due to its affinity towards modern FE frameworks.

Server side rendering

Watched the demo and it was pretty good!

I am curious if you've thought about adding a way of rendering the views server-side instead of using Svelte? For example, using Go's templating system. I realize you lose out on the component capabilities of today's FE frameworks, but as someone who prefers server-side rendered apps, I think this would be a good feature to support. As mentioned it can be another variation that bud supports in addition to svelte, React and others.

Plugins that contain views don't resolve yet

Given the following plugin with the module path plugin.com

bud-admin/
  view/
    index.svelte
plugin.go
go.mod

And an application with the following module path app.com, if you run bud build, you'll get the following:

ssr_test.go:293: err: conjure: generate "bud/view/_ssr.js" > โœ˜ [ERROR] Could not resolve "./view/index.svelte"

svelte:./bud/view/index.svelte:2:28:
	2 โ”‚ import ViewIndexSvelte from "./view/index.svelte"
		โ•ต                             ~~~~~~~~~~~~~~~~~~~~~

I assume this error is because ESBuild doesn't yet support virtual file paths, so it's one of the few places in the codebase where we rely on the underlying filesystem. The actual location of the index view is in the plugin.com module's view/ not your app.com's view/.

If that's the case, the ESBuild resolver should be updated to use the virtual filesystem.

Error: invalid cross-device link

When I did 'bud create ff-bud', I got this error:
| rename /tmp/bud-create-3425471412 ff-bud: invalid cross-device link
Possibly because /tmp is different partition than the current directory. Rename will work only in same partition?

[ERROR] Could not resolve "svelte/internal"

I'm following along the HackerNews video and am encountering build issues.
I'm performing the following steps

mkdir bud-test
cd bud-test
bud create .
bud build
bud run
bud new controller stories:/ index show

When I go to the webpage I'm given the following error

| conjure: generate "bud/.app/view/view.go" > โœ˜ [ERROR] Could not resolve "svelte/internal"

    view/index.svelte:7:7:
      7 โ”‚ } from "svelte/internal";
        โ•ต        ~~~~~~~~~~~~~~~~~

  You can mark the path "svelte/internal" as external to exclude it from the
  bundle, which will remove this error.


โœ˜ [ERROR] Could not resolve "svelte/internal"

    view/show.svelte:2:51:
      2 โ”‚ import { create_ssr_component, each, escape } from "svelte/internal";
        โ•ต                                                    ~~~~~~~~~~~~~~~~~

  You can mark the path "svelte/internal" as external to exclude it from the
  bundle, which will remove this error.

Here are some details about my environment

bud version
โžœ  bud-test bud version  
     bud: 0.1.4
  svelte: 3.47.0
   react: 18.0.0
go version
go version go1.18.3 darwin/arm64

Weird behavior while logging blank exports (Svelte)

Reproduce

  1. Create a project normally
  2. Create any route
bud new controller hello:/ index show
  1. bud run
  2. Add console.log(hellos); in the script tag (index.svelte)
  3. Go to http://127.0.0.1:3000/ and we will see an error message. For the first time:
gob: bad data: field numbers out of bounds
  • Reload. For the second time:

image

  • What the terminal looks like:

image

  • More details:

    • The error message varies between reloads
    • Remove console.log(hellos); doesn't fix the problem unless I bud run again
  • OS: Arch linux

  • Go: v1.18.2

  • Node: v14.19.3

  • bud: 0.1.4

Edit: app made with bud build works normally.

Unused import error in generated controller

I'm attempting to implement persistence. So I create a new folder models. Write a struct. Update the controllers to use that new struct instead of the autogenerated one. Then run bud run. But bud errors out with

bud/.app/controller/controller.go:10:2: imported and not used: "github/donovanrost/bud-test/models"

I don't think that bud needs to do any code generation with this package. Is there a way to tell bud to ignore it?

Unexpected `fmt.Println` behavior on non-change hot reloads

Reproduce

  1. Create a project normally
  2. Create any route bud new controller hello:/ index
  3. Add fmt.Println("anything") in the controller
func (c *Controller) Index(ctx context.Context) (hellos []*Hello, err error) {
	fmt.Println("Hello world")
	return []*Hello{}, nil
}
  1. bud run
    Every time I save my controller.go file, no Hello world message is printed.
  2. Go to http://127.0.0.1:3000
    We will see Hello world message prompted in the terminal. Don't change anything and save one/multiple times controller.go, Hello worlds will be printed out (it's inconsistent, sometime nothing is printed out)

Fix or remove skipped `testdir` tests

I had to disable two tests:

to avoid flakiness in CI. The error that occasionally pops up:

npm ERR! code ENOENT
npm ERR! path /tmp/TestSkip3421263667/001/node_modules/livebud
npm ERR! enoent ENOENT: Cannot cd into '/tmp/TestSkip3421263667/001/node_modules/livebud'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/runner/.npm/_logs/2022-05-15T08_05_47_433Z-debug-0.log
	testdir_test.go:123: err: exit status 1
--- FAIL: TestSkip (2.92s)
FAIL
FAIL	github.com/livebud/bud/internal/testdir	100.571s

I don't think we'll be using NPM after v0.3.0, so I don't think it's worth fixing these tests right now.

Too many return values error on loadController()

Hi, Firstly this project looks great. Really looking forward to working with it.

Getting the error...

bud/.app/controller/controller.go:133:15: too many return values
have (nil, error)

Looks the loadController() is missing a return error definination

func loadController() *controller.Controller { controllerController, err := controller.Load() if err != nil { return nil, err } return controllerController }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.