func TestGenerateWithRelativePaths(t *testing.T) { outputDir, err := ioutil.TempDir("", "thriftrw-generate-test") require.NoError(t, err) defer os.RemoveAll(outputDir) thriftRoot, err := os.Getwd() require.NoError(t, err) module, err := compile.Compile("testdata/thrift/structs.thrift") require.NoError(t, err) opts := []*Options{ { OutputDir: outputDir, PackagePrefix: "go.uber.org/thriftrw/gen", ThriftRoot: "testdata", }, { OutputDir: "testdata", PackagePrefix: "go.uber.org/thriftrw/gen", ThriftRoot: thriftRoot, }, } for _, opt := range opts { err := Generate(module, opt) if assert.Error(t, err, "expected code generation with %v to fail", opt) { assert.Contains(t, err.Error(), "must be an absolute path") } } }
func TestCodeIsUpToDate(t *testing.T) { // This test just verifies that the generated code in testdata/ is up to // date. If this test failed, run 'make' in the testdata/ directory and // commit the changes. thriftRoot, err := filepath.Abs("testdata/thrift") require.NoError(t, err, "could not resolve absolute path to testdata/thrift") thriftFiles, err := filepath.Glob(thriftRoot + "/*.thrift") require.NoError(t, err) outputDir, err := ioutil.TempDir("", "thriftrw-golden-test") require.NoError(t, err) defer os.RemoveAll(outputDir) for _, thriftFile := range thriftFiles { pkgRelPath := strings.TrimSuffix(filepath.Base(thriftFile), ".thrift") currentPackageDir := filepath.Join("testdata", pkgRelPath) newPackageDir := filepath.Join(outputDir, pkgRelPath) currentHash, err := dirhash(currentPackageDir) require.NoError(t, err, "could not hash %q", currentPackageDir) module, err := compile.Compile(thriftFile) require.NoError(t, err, "failed to compile %q", thriftFile) err = Generate(module, &Options{ OutputDir: outputDir, PackagePrefix: "go.uber.org/thriftrw/gen/testdata", ThriftRoot: thriftRoot, NoRecurse: true, }) require.NoError(t, err, "failed to generate code for %q", thriftFile) newHash, err := dirhash(newPackageDir) require.NoError(t, err, "could not hash %q", newPackageDir) if newHash != currentHash { // TODO(abg): Diff the two directories? t.Fatalf( "Generated code for %q is out of date. "+ "Please run 'make' in gen/testdata.", thriftFile) } } }
func main() { log.SetFlags(0) // don't include timestamps, etc. in the output var opts options parser := flags.NewParser(&opts, flags.Default) parser.Usage = "[OPTIONS] FILE" args, err := parser.Parse() if err != nil { return // message already printed by go-flags } if opts.DisplayVersion { fmt.Printf("thriftrw v%s\n", version.Version) os.Exit(0) } if len(args) != 1 { parser.WriteHelp(os.Stdout) os.Exit(1) } inputFile := args[0] if _, err := os.Stat(inputFile); err != nil { if os.IsNotExist(err) { log.Fatalf("File %q does not exist: %v", inputFile, err) } log.Fatalf("Could not stat file %q: %v", inputFile, err) } gopts := opts.GOpts if len(gopts.OutputDirectory) == 0 { gopts.OutputDirectory = "." } gopts.OutputDirectory, err = filepath.Abs(gopts.OutputDirectory) if err != nil { log.Fatalf("Unable to resolve absolute path for %q: %v", gopts.OutputDirectory, err) } if gopts.PackagePrefix == "" { gopts.PackagePrefix, err = determinePackagePrefix(gopts.OutputDirectory) if err != nil { log.Fatalf( "Could not determine a package prefix automatically: %v\n"+ "A package prefix is required to use correct import paths in the generated code.\n"+ "Use the --pkg-prefix option to provide a package prefix manually.", err) } } module, err := compile.Compile(inputFile) if err != nil { // TODO(abg): For nested compile errors, split causal chain across // multiple lines. log.Fatalf("Failed to compile %q: %v", inputFile, err) } if gopts.ThriftRoot == "" { gopts.ThriftRoot, err = findCommonAncestor(module) if err != nil { log.Fatalf( "Could not find a common parent directory for %q and the Thrift files "+ "imported by it.\nThis directory is required to generate a consistent "+ "hierarchy for generated packages.\nUse the --thrift-root option to "+ "provide this path.", err) } } else { gopts.ThriftRoot, err = filepath.Abs(gopts.ThriftRoot) if err != nil { log.Fatalf("Unable to resolve absolute path for %q: %v", gopts.ThriftRoot, err) } if err := verifyAncestry(module, gopts.ThriftRoot); err != nil { log.Fatalf( "An included Thrift file is not contained in the %q directory tree: %v", gopts.ThriftRoot, err) } } pluginHandle, err := gopts.Plugins.Handle() if err != nil { log.Fatalf("Failed to initialize plugins: %v", err) } if gopts.GeneratePluginAPI { pluginHandle = append(pluginHandle, pluginapigen.Handle) } defer pluginHandle.Close() generatorOptions := gen.Options{ OutputDir: gopts.OutputDirectory, PackagePrefix: gopts.PackagePrefix, ThriftRoot: gopts.ThriftRoot, NoRecurse: gopts.NoRecurse, NoVersionCheck: gopts.NoVersionCheck, Plugin: pluginHandle, } if err := gen.Generate(module, &generatorOptions); err != nil { log.Fatalf("Failed to generate code: %v", err) } }