vektah / dataloaden

go generate based DataLoader
MIT License
528 stars 79 forks source link

Fails to generate files in an empty directory #35

Open susisu opened 5 years ago

susisu commented 5 years ago

This is almost the same issue reported in #30.

dataloaden retrieves a package name in the current working directory when generating a file. But, if no packages are found in the working directory, the generated file has no (empty) package name and is broken.

I got the error below (same as #30) when I tried to generate in a newly created directory.

$ pwd
/path/to/example.com
$ mkdir dataloader; cd dataloader
$ go run github.com/vektah/dataloaden UserLoader uint64 *example.com/model.User
unable to gofmt:/path/to/example.com/dataloader/userloader_gen.go:6:1: expected 'IDENT', found 'import'
exit status 2
ddouglas commented 5 years ago

Just pulled my hair out for a few minutes before i realized what was going on. If the file that is being generated is the first file in the directory, it appears that dataloaden does not know what to put in the package declaration at the top of the file, so it outputs an empty string (assuming, haven't looked at the code). gofmt is then ran to sort the imports and the compiler complains because the package name is empty and everything is reverted

To fix this, I simply created an empty file in the directory and put a package declaration in it.

gen.go

package generated

Delete the file afterwards and all subsequent dataloaden generations should be fine.

ddouglas commented 5 years ago

Here is an example of a file generated without running gofmt process

https://github.com/vektah/dataloaden/blob/9d6b85cf15084a11c813eb0ee91c604b0e4a1de0/pkg/generator/generator.go#L147


// Code generated by github.com/vektah/dataloaden, DO NOT EDIT.

package 

import (
    "sync"
    "time"

    "github.com/ddouglas/monocle"
)

// CorporationLoaderConfig captures the config to create a new CorporationLoader
type CorporationLoaderConfig struct {
    // Fetch is a method that provides the data for the loader 
    Fetch func(keys []int) ([][]*monocle.Corporation, []error)

    // Wait is how long wait before sending a batch
    Wait time.Duration

    // MaxBatch will limit the maximum number of keys to send in one batch, 0 = not limit
    MaxBatch int
}

Notice the package declaration at the top of the file is empty.

And here is the error when running gofmt myself from the cli

root@localhostis:generated# gofmt corporationloader_gen.go
corporationloader_gen.go:6:1: expected 'IDENT', found 'import'

I am not 100% sure how to fix this....best of luck to anybody else that ends up here from Google

To bypass I simply commented out the import.Process and just passed in the []byte from the buffer

    // src, err := imports.Process(filepath, buf.Bytes(), nil)
    // if err != nil {
    //  return errors.Wrap(err, "unable to gofmt")
    // }

    if err := ioutil.WriteFile(filepath, buf.Bytes(), 0644); err != nil {
        return errors.Wrap(err, "writing output")
    }

Now you can go through all of that to generate the file or use the method I outlines in my last comment and you will be perfectly fine till this gets fixed.