Repository: segmentio/terraform-docs (go)

Issue:
Error: open main.tf: no such file or directory (use with pre-commit)
Hi!

### Prerequisites

- [x] This issue describes a bug.

### Description

Since version 0.9.0, terraform-docs seems to require a `main.tf`. In my company standards, some of our projects does not have a `maint.tf`… 

#### Actual Behavior

When a project does
```
$ pre-commit run -a

Error: open main.tf: no such file or directory
```

#### Expected Behavior

Not sure the problem come from terraform-docs because it still runs as is, however only terraform-docs has changed. Within pre-commit: v0.8.2 works, v0.9.0 does not.
Maybe you could give me useful information.

### Version

erraform-docs version v0.9.0 89b129b linux/amd64 BuildDate: 2020-03-31T20:19:01+0000


Pull request:
Don't crash when reading header if 'main.tf' not found
### Prerequisites

Put an `x` into the box(es) that apply:

- [x] This pull request fixes a bug.
- [ ] This pull request adds a feature.
- [ ] This pull request enhances existing functionality.
- [ ] This pull request introduces breaking change.

For more information, see the [Contributing Guide](https://github.com/segmentio/terraform-docs/tree/master/CONTRIBUTING.md).

### Description

There was a regression added in #217 in which if there's no `main.tf` file available in the module, executing any commands of `terraform-docs` fails with `Error: open main.tf: no such file or directory` error. This PR handles the situation and:

- silently ignore the error if the file missing is `main.tf`
- shows error and exit 1 if the file missing is anything else (i.e. `--header-from` was explicitly set by the user)

### Issues Resolved

Fixes #232 

### Checklist

Put an `x` into all boxes that apply:

- [ ] I have read the [Contributing Guidelines](https://github.com/segmentio/terraform-docs/tree/master/CONTRIBUTING.md).

#### Tests

- [x] I have added tests to cover my changes.
- [x] All tests pass when I run `make test`.

#### Documentation

- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.

#### Code Style

- [ ] My code follows the code style of this project.


Patch:
diff --git a/cmd/root.go b/cmd/root.go
index 226650c..1054337 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -13,11 +13,13 @@ var settings = print.NewSettings()
 var options = module.NewOptions()
 
 var rootCmd = &cobra.Command{
-	Args:    cobra.NoArgs,
-	Use:     "terraform-docs",
-	Short:   "A utility to generate documentation from Terraform modules in various output formats",
-	Long:    "A utility to generate documentation from Terraform modules in various output formats",
-	Version: version.Version(),
+	Args:          cobra.NoArgs,
+	Use:           "terraform-docs",
+	Short:         "A utility to generate documentation from Terraform modules in various output formats",
+	Long:          "A utility to generate documentation from Terraform modules in various output formats",
+	Version:       version.Version(),
+	SilenceUsage:  true,
+	SilenceErrors: true,
 	PersistentPreRun: func(cmd *cobra.Command, args []string) {
 		oppositeBool := func(name string) bool {
 			val, _ := cmd.Flags().GetBool(name)
@@ -67,7 +69,10 @@ func init() {
 // Execute adds all child commands to the root command and sets flags appropriately.
 // This is called by main.main(). It only needs to happen once to the rootCmd.
 func Execute() error {
-	return rootCmd.Execute()
+	if err := rootCmd.Execute(); err != nil {
+		fmt.Printf("Error: %s\n", err.Error())
+	}
+	return nil
 }
 
 // RootCmd represents the base command when called without any subcommands
diff --git a/internal/module/module.go b/internal/module/module.go
index 791d2a1..5bb7a48 100644
--- a/internal/module/module.go
+++ b/internal/module/module.go
@@ -72,7 +72,10 @@ func loadHeader(options *Options) (string, error) {
 	filename := filepath.Join(options.Path, options.HeaderFromFile)
 	_, err := ioutil.ReadFile(filename)
 	if err != nil {
-		return "", err
+		if options.HeaderFromFile != "main.tf" {
+			return "", err // user explicitly asked for a file which doesn't exist
+		}
+		return "", nil // absorb the error to not break workflow of users who don't have 'main.tf at all
 	}
 	lines := reader.Lines{
 		FileName: filename,


Test patch:
diff --git a/internal/module/module_test.go b/internal/module/module_test.go
index 22e5821..7361bf2 100644
--- a/internal/module/module_test.go
+++ b/internal/module/module_test.go
@@ -75,6 +75,13 @@ func TestLoadHeader(t *testing.T) {
 			expected: "Custom Header:\n\nExample of 'foo_bar' module in `foo_bar.tf`.\n\n- list item 1\n- list item 2",
 			wantErr:  false,
 		},
+		{
+			name:     "load module header from path",
+			path:     "no-inputs",
+			header:   "main.tf",
+			expected: "",
+			wantErr:  false,
+		},
 		{
 			name:     "load module header from path",
 			path:     "full-example",