diff --git a/travis/client.go b/travis/client.go index 30a5bfe..30a7c5a 100644 --- a/travis/client.go +++ b/travis/client.go @@ -1,6 +1,7 @@ package travis import ( + "errors" "net/http" "sync" @@ -40,6 +41,6 @@ func (r *roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { } func isNotFound(err error) bool { - errResp, ok := err.(*travis.ErrorResponse) - return ok && errResp.ErrorType == "not_found" + var errResp *travis.ErrorResponse + return errors.As(err, &errResp) && errResp.ErrorType == "not_found" } diff --git a/travis/client_test.go b/travis/client_test.go new file mode 100644 index 0000000..dd3a662 --- /dev/null +++ b/travis/client_test.go @@ -0,0 +1,3 @@ +package travis + +var IsNotFound = isNotFound diff --git a/travis/data_source_user.go b/travis/data_source_user.go index 72a7e47..a156c1b 100644 --- a/travis/data_source_user.go +++ b/travis/data_source_user.go @@ -148,7 +148,7 @@ func dataSourceTravisRead(ctx context.Context, d *schema.ResourceData, m interfa ctx = tflog.SetField(ctx, "userID", userID) if waitSync { - _, _, err := client.User.Sync(ctx, uint(userID)) + _, _, err := client.User.Sync(ctx, userID) if err != nil { return diag.Errorf("failed to sync user %v: %v", userID, err) } diff --git a/travis/data_source_user_test.go b/travis/data_source_user_test.go index 69d4ddd..4302490 100644 --- a/travis/data_source_user_test.go +++ b/travis/data_source_user_test.go @@ -1,7 +1,6 @@ -package travis +package travis_test import ( - _ "embed" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" diff --git a/travis/provider_test.go b/travis/provider_test.go index 706a81c..1f516d7 100644 --- a/travis/provider_test.go +++ b/travis/provider_test.go @@ -1,10 +1,11 @@ -package travis +package travis_test import ( "os" "regexp" "testing" + "github.com/bgpat/terraform-provider-travis/travis" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) @@ -21,23 +22,25 @@ var ( ) func init() { - testAccProvider = Provider() + testAccProvider = travis.Provider() testAccProviders = map[string]*schema.Provider{ "travis": testAccProvider, } } func TestProvider(t *testing.T) { - if err := Provider().InternalValidate(); err != nil { + if err := travis.Provider().InternalValidate(); err != nil { t.Fatal(err) } } func TestProvider_impl(t *testing.T) { - var _ *schema.Provider = Provider() + var _ *schema.Provider = travis.Provider() } func testAccPreCheck(t *testing.T) { + t.Helper() + if v := os.Getenv("TRAVIS_TOKEN"); v == "" { t.Fatal("TRAVIS_TOKEN must be set for acceptance tests") } diff --git a/travis/resource_cron.go b/travis/resource_cron.go index 3798857..892a8e3 100644 --- a/travis/resource_cron.go +++ b/travis/resource_cron.go @@ -21,58 +21,58 @@ func resourceCron() *schema.Resource { DeleteContext: resourceCronDelete, Schema: map[string]*schema.Schema{ - "repository_id": &schema.Schema{ + "repository_id": { Type: schema.TypeInt, Optional: true, Description: "Value uniquely identifying the repository.", ForceNew: true, ExactlyOneOf: []string{"repository_slug"}, }, - "repository_slug": &schema.Schema{ + "repository_slug": { Type: schema.TypeString, Optional: true, Description: "Same as {repository.owner.name}/{repository.name}.", ForceNew: true, ExactlyOneOf: []string{"repository_id"}, }, - "branch": &schema.Schema{ + "branch": { Type: schema.TypeString, Required: true, Description: "The branch to which this cron job belongs.", ForceNew: true, }, - "interval": &schema.Schema{ + "interval": { Type: schema.TypeString, Required: true, Description: "Interval at which this cron runs. Can be daily, weekly, or monthly.", ForceNew: true, ValidateFunc: validation.StringInSlice([]string{"daily", "weekly", "monthly"}, false), }, - "dont_run_if_recent_build_exists": &schema.Schema{ + "dont_run_if_recent_build_exists": { Type: schema.TypeBool, Optional: true, Description: "Whether a cron build should run if there has been a build on this branch in the last 24 hours.", ForceNew: true, }, - "last_run": &schema.Schema{ + "last_run": { Type: schema.TypeString, Description: "When the cron ran last.", Computed: true, ForceNew: true, }, - "next_run": &schema.Schema{ + "next_run": { Type: schema.TypeString, Description: "When the cron is scheduled to run next.", Computed: true, ForceNew: true, }, - "created_at": &schema.Schema{ + "created_at": { Type: schema.TypeString, Description: "When the cron was created.", Computed: true, ForceNew: true, }, - "active": &schema.Schema{ + "active": { Type: schema.TypeBool, Description: "Whether the cron is active.", Computed: true, @@ -105,7 +105,9 @@ func resourceCronCreate(ctx context.Context, d *schema.ResourceData, m interface } else { return diag.Errorf("one of repository_id or repository_slug must be specified") } - assignCron(cron, d) + if err := assignCron(cron, d); err != nil { + return diag.Errorf("failed to assign cron: %v", err) + } return nil } @@ -136,7 +138,9 @@ func resourceCronRead(ctx context.Context, d *schema.ResourceData, m interface{} } else { return diag.Errorf("one of repository_id or repository_slug must be specified") } - assignCron(cron, d) + if err := assignCron(cron, d); err != nil { + return diag.Errorf("failed to assign cron: %v", err) + } return nil } @@ -162,15 +166,30 @@ func generateCronBody(d *schema.ResourceData) *travis.CronBody { } } -func assignCron(cron *travis.Cron, d *schema.ResourceData) { +func assignCron(cron *travis.Cron, d *schema.ResourceData) error { d.SetId(strconv.FormatUint(uint64(*cron.Id), 10)) - d.Set("branch", cron.Branch.Name) - d.Set("interval", cron.Interval) - d.Set("dont_run_if_recent_build_exists", cron.DontRunIfRecentBuildExists) - d.Set("last_run", cron.LastRun) - d.Set("next_run", cron.NextRun) - d.Set("created_at", cron.CreatedAt) - d.Set("active", cron.Active) + if err := d.Set("branch", cron.Branch.Name); err != nil { + return err + } + if err := d.Set("interval", cron.Interval); err != nil { + return err + } + if err := d.Set("dont_run_if_recent_build_exists", cron.DontRunIfRecentBuildExists); err != nil { + return err + } + if err := d.Set("last_run", cron.LastRun); err != nil { + return err + } + if err := d.Set("next_run", cron.NextRun); err != nil { + return err + } + if err := d.Set("created_at", cron.CreatedAt); err != nil { + return err + } + if err := d.Set("active", cron.Active); err != nil { + return err + } + return nil } func importCron(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { @@ -189,16 +208,22 @@ func importCron(ctx context.Context, d *schema.ResourceData, m interface{}) ([]* if err != nil { return nil, fmt.Errorf("error getting cron in branch (%q) of repo id (%d): %w", branch, repoID, err) } - d.Set("repository_id", repoID) + if err := d.Set("repository_id", repoID); err != nil { + return nil, err + } } else { cron, _, err = client.Crons.FindByRepoSlug(ctx, repo, branch, nil) if err != nil { return nil, fmt.Errorf("error getting cron in branch (%q) of repo slug (%q): %w", branch, repo, err) } - d.Set("repository_slug", repo) + if err := d.Set("repository_slug", repo); err != nil { + return nil, err + } } - assignCron(cron, d) + if err := assignCron(cron, d); err != nil { + return nil, err + } return []*schema.ResourceData{d}, nil } diff --git a/travis/resource_cron_test.go b/travis/resource_cron_test.go index 29078c3..ddd6cd6 100644 --- a/travis/resource_cron_test.go +++ b/travis/resource_cron_test.go @@ -1,4 +1,4 @@ -package travis +package travis_test import ( "context" @@ -9,6 +9,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/shuheiktgw/go-travis" + + tptravis "github.com/bgpat/terraform-provider-travis/travis" ) func TestAccResourceCron_basic(t *testing.T) { @@ -22,7 +24,7 @@ func TestAccResourceCron_basic(t *testing.T) { { Config: testAccCronResource(testBranch, "daily", false), Check: resource.ComposeTestCheckFunc( - testAccCheckCronResourceExists("travis_cron.foo", &cron), + testAccCheckCronResourceExists(&cron), resource.TestCheckResourceAttr("travis_cron.foo", "repository_slug", testRepoSlug), resource.TestCheckResourceAttr("travis_cron.foo", "branch", testBranch), resource.TestCheckResourceAttr("travis_cron.foo", "interval", "daily"), @@ -32,7 +34,7 @@ func TestAccResourceCron_basic(t *testing.T) { { Config: testAccCronResource(testBranch, "weekly", false), Check: resource.ComposeTestCheckFunc( - testAccCheckCronResourceExists("travis_cron.foo", &cron), + testAccCheckCronResourceExists(&cron), resource.TestCheckResourceAttr("travis_cron.foo", "repository_slug", testRepoSlug), resource.TestCheckResourceAttr("travis_cron.foo", "branch", testBranch), resource.TestCheckResourceAttr("travis_cron.foo", "interval", "weekly"), @@ -42,7 +44,7 @@ func TestAccResourceCron_basic(t *testing.T) { { Config: testAccCronResource(testBranch, "monthly", false), Check: resource.ComposeTestCheckFunc( - testAccCheckCronResourceExists("travis_cron.foo", &cron), + testAccCheckCronResourceExists(&cron), resource.TestCheckResourceAttr("travis_cron.foo", "repository_slug", testRepoSlug), resource.TestCheckResourceAttr("travis_cron.foo", "branch", testBranch), resource.TestCheckResourceAttr("travis_cron.foo", "interval", "monthly"), @@ -52,7 +54,7 @@ func TestAccResourceCron_basic(t *testing.T) { { Config: testAccCronResource(testBranch, "daily", true), Check: resource.ComposeTestCheckFunc( - testAccCheckCronResourceExists("travis_cron.foo", &cron), + testAccCheckCronResourceExists(&cron), resource.TestCheckResourceAttr("travis_cron.foo", "repository_slug", testRepoSlug), resource.TestCheckResourceAttr("travis_cron.foo", "branch", testBranch), resource.TestCheckResourceAttr("travis_cron.foo", "interval", "daily"), @@ -64,7 +66,7 @@ func TestAccResourceCron_basic(t *testing.T) { } func testAccCheckCronResourceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*Client) + client := testAccProvider.Meta().(*tptravis.Client) for _, rs := range s.RootModule().Resources { if rs.Type != "travis_cron" { continue @@ -77,7 +79,7 @@ func testAccCheckCronResourceDestroy(s *terraform.State) error { if err == nil && cron != nil { return fmt.Errorf("cron %v still exists", rs.Primary.ID) } - if err != nil && !isNotFound(err) { + if err != nil && !tptravis.IsNotFound(err) { return err } return nil @@ -85,7 +87,8 @@ func testAccCheckCronResourceDestroy(s *terraform.State) error { return nil } -func testAccCheckCronResourceExists(resourceName string, cron *travis.Cron) resource.TestCheckFunc { +func testAccCheckCronResourceExists(cron *travis.Cron) resource.TestCheckFunc { + resourceName := "travis_cron.foo" return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] if !ok { @@ -94,7 +97,7 @@ func testAccCheckCronResourceExists(resourceName string, cron *travis.Cron) reso if rs.Primary.ID == "" { return fmt.Errorf("cron ID is not set") } - client := testAccProvider.Meta().(*Client) + client := testAccProvider.Meta().(*tptravis.Client) id, err := strconv.ParseUint(rs.Primary.ID, 10, 64) if err != nil { return err diff --git a/travis/resource_env_var.go b/travis/resource_env_var.go index 8204e7f..47a00b2 100644 --- a/travis/resource_env_var.go +++ b/travis/resource_env_var.go @@ -20,34 +20,34 @@ func resourceEnvVar() *schema.Resource { DeleteContext: resourceEnvVarDelete, Schema: map[string]*schema.Schema{ - "repository_id": &schema.Schema{ + "repository_id": { Type: schema.TypeInt, Optional: true, Description: "Value uniquely identifying the repository.", ForceNew: true, ExactlyOneOf: []string{"repository_slug"}, }, - "repository_slug": &schema.Schema{ + "repository_slug": { Type: schema.TypeString, Optional: true, Description: "Same as {repository.owner.name}/{repository.name}.", ForceNew: true, ExactlyOneOf: []string{"repository_id"}, }, - "name": &schema.Schema{ + "name": { Type: schema.TypeString, Required: true, Description: "The environment variable name, e.g. FOO.", ForceNew: true, }, - "public_value": &schema.Schema{ + "public_value": { Type: schema.TypeString, Optional: true, Description: "The environment variable's value, e.g. bar.", ExactlyOneOf: []string{"value"}, ForceNew: true, }, - "value": &schema.Schema{ + "value": { Type: schema.TypeString, Optional: true, Description: "The environment variable's value, e.g. bar.", @@ -55,13 +55,13 @@ func resourceEnvVar() *schema.Resource { ExactlyOneOf: []string{"public_value"}, ForceNew: true, }, - "public": &schema.Schema{ + "public": { Type: schema.TypeBool, Description: "Whether this environment variable should be publicly visible or not.", Computed: true, ForceNew: true, }, - "branch": &schema.Schema{ + "branch": { Type: schema.TypeString, Optional: true, Description: "The env_var's branch.", @@ -74,11 +74,13 @@ func resourceEnvVar() *schema.Resource { value := d.Get("value").(string) switch { case publicValue != "" && value == "": // public: true - d.SetNew("public", true) - d.Clear("value") + if err := d.SetNew("public", true); err != nil { + return err + } case value != "" && publicValue == "": // public: false - d.SetNew("public", false) - d.Clear("public_value") + if err := d.SetNew("public", false); err != nil { + return err + } } return nil }, @@ -108,7 +110,9 @@ func resourceEnvVarCreate(ctx context.Context, d *schema.ResourceData, m interfa } else { return diag.Errorf("one of repository_id or repository_slug must be specified") } - assignEnvVar(envVar, d) + if err := assignEnvVar(envVar, d); err != nil { + return diag.Errorf("failed to assign env_var: %v", err) + } return nil } @@ -139,7 +143,9 @@ func resourceEnvVarRead(ctx context.Context, d *schema.ResourceData, m interface } else { return diag.Errorf("one of repository_id or repository_slug must be specified") } - assignEnvVar(envVar, d) + if err := assignEnvVar(envVar, d); err != nil { + return diag.Errorf("failed to assign env_var: %v", err) + } return nil } @@ -182,17 +188,30 @@ func generateEnvVarBody(d *schema.ResourceData) *travis.EnvVarBody { } } -func assignEnvVar(envVar *travis.EnvVar, d *schema.ResourceData) { +func assignEnvVar(envVar *travis.EnvVar, d *schema.ResourceData) error { d.SetId(*envVar.Id) - d.Set("name", envVar.Name) + if err := d.Set("name", envVar.Name); err != nil { + return err + } if *envVar.Public { - d.Set("public_value", envVar.Value) - d.Set("value", nil) + if err := d.Set("public_value", envVar.Value); err != nil { + return err + } + if err := d.Set("value", nil); err != nil { + return err + } } else { - d.Set("public_value", nil) + if err := d.Set("public_value", nil); err != nil { + return err + } + } + if err := d.Set("public", envVar.Public); err != nil { + return err + } + if err := d.Set("branch", envVar.Branch); err != nil { + return err } - d.Set("public", envVar.Public) - d.Set("branch", envVar.Branch) + return nil } func importEnvVar(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { @@ -212,11 +231,17 @@ func importEnvVar(ctx context.Context, d *schema.ResourceData, m interface{}) ([ for _, envVar := range envVars { if *envVar.Name == name { - assignEnvVar(envVar, d) + if err := assignEnvVar(envVar, d); err != nil { + return nil, err + } if repoID, err := strconv.Atoi(repo); err == nil { - d.Set("repository_id", repoID) + if err := d.Set("repository_id", repoID); err != nil { + return nil, err + } } else { - d.Set("repository_slug", repo) + if err := d.Set("repository_slug", repo); err != nil { + return nil, err + } } return []*schema.ResourceData{d}, nil } diff --git a/travis/resource_env_var_test.go b/travis/resource_env_var_test.go index 7b6c530..4e9d31d 100644 --- a/travis/resource_env_var_test.go +++ b/travis/resource_env_var_test.go @@ -1,4 +1,4 @@ -package travis +package travis_test import ( "context" @@ -9,6 +9,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/shuheiktgw/go-travis" + + tptravis "github.com/bgpat/terraform-provider-travis/travis" ) func TestAccResourceEnvVar_basic(t *testing.T) { @@ -72,7 +74,7 @@ func TestAccResourceEnvVar_basic(t *testing.T) { } func testAccCheckEnvVarResourceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*Client) + client := testAccProvider.Meta().(*tptravis.Client) for _, rs := range s.RootModule().Resources { if rs.Type != "travis_env_var" { continue @@ -82,7 +84,7 @@ func testAccCheckEnvVarResourceDestroy(s *terraform.State) error { if err == nil && envVar != nil { return fmt.Errorf("env var %q still exists", rs.Primary.Attributes["name"]) } - if err != nil && !isNotFound(err) { + if err != nil && !tptravis.IsNotFound(err) { return err } return nil @@ -99,7 +101,7 @@ func testAccCheckEnvVarResourceExists(resourceName string, envVar *travis.EnvVar if rs.Primary.ID == "" { return fmt.Errorf("env var ID is not set") } - client := testAccProvider.Meta().(*Client) + client := testAccProvider.Meta().(*tptravis.Client) result, _, err := client.EnvVars.FindByRepoSlug(context.Background(), testRepoSlug, rs.Primary.ID) if err != nil { return err diff --git a/travis/resource_key_pair.go b/travis/resource_key_pair.go index f5e1e68..81bc4cf 100644 --- a/travis/resource_key_pair.go +++ b/travis/resource_key_pair.go @@ -75,7 +75,9 @@ func resourceKeyPairCreate(ctx context.Context, d *schema.ResourceData, m interf } else { return diag.Errorf("one of repository_id or repository_slug must be specified") } - assignKeyPair(keyPair, d) + if err := assignKeyPair(keyPair, d); err != nil { + return diag.Errorf("failed to assign key_pair: %v", err) + } return nil } @@ -106,7 +108,9 @@ func resourceKeyPairRead(ctx context.Context, d *schema.ResourceData, m interfac } else { return diag.Errorf("one of repository_id or repository_slug must be specified") } - assignKeyPair(keyPair, d) + if err := assignKeyPair(keyPair, d); err != nil { + return diag.Errorf("failed to assign key_pair: %v", err) + } return nil } @@ -168,12 +172,17 @@ func generateKeyPairBody(d *schema.ResourceData) *travis.KeyPairBody { } } -func assignKeyPair(keyPair *travis.KeyPair, d *schema.ResourceData) { +func assignKeyPair(keyPair *travis.KeyPair, d *schema.ResourceData) error { if val, ok := d.GetOk("repository_id"); ok { d.SetId(val.(string)) } else if val, ok := d.GetOk("repository_slug"); ok { d.SetId(val.(string)) } - d.Set("public_key", keyPair.PublicKey) - d.Set("fingerprint", keyPair.Fingerprint) + if err := d.Set("public_key", keyPair.PublicKey); err != nil { + return err + } + if err := d.Set("fingerprint", keyPair.Fingerprint); err != nil { + return err + } + return nil } diff --git a/travis/resource_key_pair_test.go b/travis/resource_key_pair_test.go index 5b06fff..4ef6946 100644 --- a/travis/resource_key_pair_test.go +++ b/travis/resource_key_pair_test.go @@ -1,4 +1,4 @@ -package travis +package travis_test import ( "context" @@ -14,6 +14,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/shuheiktgw/go-travis" "golang.org/x/crypto/ssh" + + tptravis "github.com/bgpat/terraform-provider-travis/travis" ) func TestAccResourceKeyPair_basic(t *testing.T) { @@ -41,7 +43,7 @@ func TestAccResourceKeyPair_basic(t *testing.T) { } func testAccCheckKeyPairResourceDestroy(s *terraform.State) error { - client := testAccProvider.Meta().(*Client) + client := testAccProvider.Meta().(*tptravis.Client) for _, rs := range s.RootModule().Resources { if rs.Type != "travis_key_pair" { continue @@ -51,7 +53,7 @@ func testAccCheckKeyPairResourceDestroy(s *terraform.State) error { if err == nil && keyPair != nil { return fmt.Errorf("key pair %q still exists", slug) } - if err != nil && !isNotFound(err) { + if err != nil && !tptravis.IsNotFound(err) { return err } return nil @@ -68,7 +70,7 @@ func testAccCheckKeyPairResourceExists(resourceName string, keyPair *travis.KeyP if rs.Primary.ID == "" { return fmt.Errorf("key pair is not set") } - client := testAccProvider.Meta().(*Client) + client := testAccProvider.Meta().(*tptravis.Client) result, _, err := client.KeyPair.FindByRepoSlug(context.Background(), testRepoSlug) if err != nil { return err @@ -89,9 +91,11 @@ resource "travis_key_pair" "foo" { } func makeKeyPair(t *testing.T) (string, string, string) { + t.Helper() + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { - t.Fatal(fmt.Errorf("Cannot generate RSA key\n")) + t.Fatal("Cannot generate RSA key") } publicKey := &privateKey.PublicKey sshPublicKey, err := ssh.NewPublicKey(publicKey)