Skip to content

Commit feefdf6

Browse files
authored
Merge pull request #939 from petrmvala/feat/repository-file-datasource
feat: Add gitlab_repository_file data source
2 parents e75bcb3 + e5478a3 commit feefdf6

File tree

7 files changed

+304
-56
lines changed

7 files changed

+304
-56
lines changed

docs/data-sources/repository_file.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "gitlab_repository_file Data Source - terraform-provider-gitlab"
4+
subcategory: ""
5+
description: |-
6+
The gitlab_repository_file data source allows details of a file in a repository to be retrieved.
7+
Upstream API: GitLab REST API docs https://docs.gitlab.com/ee/api/repository_files.html
8+
---
9+
10+
# gitlab_repository_file (Data Source)
11+
12+
The `gitlab_repository_file` data source allows details of a file in a repository to be retrieved.
13+
14+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/repository_files.html)
15+
16+
## Example Usage
17+
18+
```terraform
19+
data "gitlab_repository_file" "example" {
20+
project = "example"
21+
ref = "main"
22+
file_path = "README.md"
23+
}
24+
```
25+
26+
<!-- schema generated by tfplugindocs -->
27+
## Schema
28+
29+
### Required
30+
31+
- **file_path** (String) The full path of the file. It must be relative to the root of the project without a leading slash `/`.
32+
- **project** (String) The name or ID of the project.
33+
- **ref** (String) The name of branch, tag or commit.
34+
35+
### Optional
36+
37+
- **id** (String) The ID of this resource.
38+
39+
### Read-Only
40+
41+
- **blob_id** (String) The blob id.
42+
- **commit_id** (String) The commit id.
43+
- **content** (String) base64 encoded file content. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).
44+
- **content_sha256** (String) File content sha256 digest.
45+
- **encoding** (String) The file content encoding.
46+
- **file_name** (String) The filename.
47+
- **last_commit_id** (String) The last known commit id.
48+
- **size** (Number) The file size.
49+
50+

docs/resources/repository_file.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ resource "gitlab_repository_file" "this" {
4949
- **commit_message** (String) Commit message.
5050
- **content** (String) base64 encoded file content. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).
5151
- **file_path** (String) The full path of the file. It must be relative to the root of the project without a leading slash `/`.
52-
- **project** (String) The ID of the project.
52+
- **project** (String) The name or ID of the project.
5353

5454
### Optional
5555

@@ -60,7 +60,14 @@ resource "gitlab_repository_file" "this" {
6060

6161
### Read-Only
6262

63-
- **encoding** (String) Content encoding.
63+
- **blob_id** (String) The blob id.
64+
- **commit_id** (String) The commit id.
65+
- **content_sha256** (String) File content sha256 digest.
66+
- **encoding** (String) The file content encoding.
67+
- **file_name** (String) The filename.
68+
- **last_commit_id** (String) The last known commit id.
69+
- **ref** (String) The name of branch, tag or commit.
70+
- **size** (Number) The file size.
6471

6572
## Import
6673

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data "gitlab_repository_file" "example" {
2+
project = "example"
3+
ref = "main"
4+
file_path = "README.md"
5+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"log"
7+
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
gitlab "github.com/xanzy/go-gitlab"
11+
)
12+
13+
var _ = registerDataSource("gitlab_repository_file", func() *schema.Resource {
14+
return &schema.Resource{
15+
Description: `The ` + "`gitlab_repository_file`" + ` data source allows details of a file in a repository to be retrieved.
16+
17+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/repository_files.html)`,
18+
19+
ReadContext: dataSourceGitlabRepositoryFileRead,
20+
Schema: datasourceSchemaFromResourceSchema(gitlabRepositoryFileGetSchema(), "project", "file_path", "ref"),
21+
}
22+
})
23+
24+
func dataSourceGitlabRepositoryFileRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
25+
client := meta.(*gitlab.Client)
26+
project := d.Get("project").(string)
27+
filePath := d.Get("file_path").(string)
28+
29+
options := &gitlab.GetFileOptions{
30+
Ref: gitlab.String(d.Get("ref").(string)),
31+
}
32+
33+
repositoryFile, resp, err := client.RepositoryFiles.GetFile(project, filePath, options, gitlab.WithContext(ctx))
34+
if err != nil {
35+
log.Printf("[DEBUG] file %s not found, response %v", filePath, resp)
36+
return diag.FromErr(err)
37+
}
38+
39+
d.SetId(fmt.Sprintf("%s:%s:%s", project, repositoryFile.Ref, repositoryFile.FilePath))
40+
41+
stateMap := gitlabRepositoryFileToStateMap(project, repositoryFile)
42+
if err := setStateMapInResourceData(stateMap, d); err != nil {
43+
return diag.FromErr(err)
44+
}
45+
return nil
46+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package provider
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
)
10+
11+
func TestAccDataGitlabRepositoryFile_basic(t *testing.T) {
12+
testAccCheck(t)
13+
project := testAccCreateProject(t)
14+
resource.Test(t, resource.TestCase{
15+
PreCheck: func() { testAccPreCheck(t) },
16+
ProviderFactories: providerFactories,
17+
Steps: []resource.TestStep{
18+
{
19+
Config: testAccDataGitlabRepositoryFile(project.PathWithNamespace),
20+
Check: resource.ComposeTestCheckFunc(
21+
testAccDataSourceGitlabRepositoryFile("gitlab_repository_file.foo", "data.gitlab_repository_file.foo"),
22+
),
23+
},
24+
},
25+
})
26+
}
27+
28+
func testAccDataSourceGitlabRepositoryFile(src, n string) resource.TestCheckFunc {
29+
return func(s *terraform.State) error {
30+
31+
file := s.RootModule().Resources[src]
32+
fileAttr := file.Primary.Attributes
33+
34+
search := s.RootModule().Resources[n]
35+
searchAttr := search.Primary.Attributes
36+
37+
testAttributes := []string{
38+
"project",
39+
"file_path",
40+
"size",
41+
"encoding",
42+
"content",
43+
"ref",
44+
"blob_id",
45+
"commit_id",
46+
"content_sha256",
47+
"last_commit_id",
48+
}
49+
50+
for _, attribute := range testAttributes {
51+
if searchAttr[attribute] != fileAttr[attribute] {
52+
return fmt.Errorf("expected file's parameter `%s` to be: %s, but got: `%s`", attribute, fileAttr[attribute], searchAttr[attribute])
53+
}
54+
}
55+
return nil
56+
}
57+
}
58+
59+
func testAccDataGitlabRepositoryFile(project string) string {
60+
return fmt.Sprintf(`
61+
resource "gitlab_repository_file" "foo" {
62+
project = "%s"
63+
file_path = "testfile-meow"
64+
branch = "main"
65+
content = base64encode("Meow goes the cat")
66+
commit_message = "feat: Meow"
67+
}
68+
69+
data "gitlab_repository_file" "foo" {
70+
project = gitlab_repository_file.foo.project
71+
file_path = gitlab_repository_file.foo.file_path
72+
ref = "main"
73+
}
74+
`, project)
75+
}

internal/provider/resource_gitlab_repository_file.go

Lines changed: 34 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -34,57 +34,37 @@ var _ = registerResource("gitlab_repository_file", func() *schema.Resource {
3434
// However, we don't support the `encoding` parameter as it seems to be broken.
3535
// Only a value of `base64` is supported, all others, including the documented default `text`, lead to
3636
// a `400 {error: encoding does not have a valid value}` error.
37-
Schema: map[string]*schema.Schema{
38-
"project": {
39-
Description: "The ID of the project.",
40-
Type: schema.TypeString,
41-
Required: true,
42-
ForceNew: true,
37+
Schema: constructSchema(
38+
map[string]*schema.Schema{
39+
"branch": {
40+
Description: "Name of the branch to which to commit to.",
41+
Type: schema.TypeString,
42+
Required: true,
43+
ForceNew: true,
44+
},
45+
"start_branch": {
46+
Description: "Name of the branch to start the new commit from.",
47+
Type: schema.TypeString,
48+
Optional: true,
49+
},
50+
"author_email": {
51+
Description: "Email of the commit author.",
52+
Type: schema.TypeString,
53+
Optional: true,
54+
},
55+
"author_name": {
56+
Description: "Name of the commit author.",
57+
Type: schema.TypeString,
58+
Optional: true,
59+
},
60+
"commit_message": {
61+
Description: "Commit message.",
62+
Type: schema.TypeString,
63+
Required: true,
64+
},
4365
},
44-
"file_path": {
45-
Description: "The full path of the file. It must be relative to the root of the project without a leading slash `/`.",
46-
Type: schema.TypeString,
47-
Required: true,
48-
ForceNew: true,
49-
},
50-
"branch": {
51-
Description: "Name of the branch to which to commit to.",
52-
Type: schema.TypeString,
53-
Required: true,
54-
ForceNew: true,
55-
},
56-
"start_branch": {
57-
Description: "Name of the branch to start the new commit from.",
58-
Type: schema.TypeString,
59-
Optional: true,
60-
},
61-
"author_email": {
62-
Description: "Email of the commit author.",
63-
Type: schema.TypeString,
64-
Optional: true,
65-
},
66-
"author_name": {
67-
Description: "Name of the commit author.",
68-
Type: schema.TypeString,
69-
Optional: true,
70-
},
71-
"content": {
72-
Description: "base64 encoded file content. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).",
73-
Type: schema.TypeString,
74-
Required: true,
75-
ValidateFunc: validateBase64Content,
76-
},
77-
"commit_message": {
78-
Description: "Commit message.",
79-
Type: schema.TypeString,
80-
Required: true,
81-
},
82-
"encoding": {
83-
Description: "Content encoding.",
84-
Type: schema.TypeString,
85-
Computed: true,
86-
},
87-
},
66+
gitlabRepositoryFileGetSchema(),
67+
),
8868
}
8969
})
9070

@@ -136,11 +116,11 @@ func resourceGitlabRepositoryFileRead(ctx context.Context, d *schema.ResourceDat
136116
}
137117

138118
d.SetId(resourceGitLabRepositoryFileBuildId(project, branch, repositoryFile.FilePath))
139-
d.Set("project", project)
140-
d.Set("file_path", repositoryFile.FilePath)
141119
d.Set("branch", repositoryFile.Ref)
142-
d.Set("encoding", repositoryFile.Encoding)
143-
d.Set("content", repositoryFile.Content)
120+
stateMap := gitlabRepositoryFileToStateMap(project, repositoryFile)
121+
if err = setStateMapInResourceData(stateMap, d); err != nil {
122+
return diag.FromErr(err)
123+
}
144124

145125
return nil
146126
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package provider
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
5+
"github.com/xanzy/go-gitlab"
6+
)
7+
8+
func gitlabRepositoryFileGetSchema() map[string]*schema.Schema {
9+
return map[string]*schema.Schema{
10+
"project": {
11+
Description: "The name or ID of the project.",
12+
Type: schema.TypeString,
13+
Required: true,
14+
ForceNew: true,
15+
},
16+
"file_path": {
17+
Description: "The full path of the file. It must be relative to the root of the project without a leading slash `/`.",
18+
Type: schema.TypeString,
19+
Required: true,
20+
ForceNew: true,
21+
},
22+
"ref": {
23+
Description: "The name of branch, tag or commit.",
24+
Type: schema.TypeString,
25+
Computed: true,
26+
},
27+
"file_name": {
28+
Description: "The filename.",
29+
Type: schema.TypeString,
30+
Computed: true,
31+
},
32+
"size": {
33+
Description: "The file size.",
34+
Type: schema.TypeInt,
35+
Computed: true,
36+
},
37+
"encoding": {
38+
Description: "The file content encoding.",
39+
Type: schema.TypeString,
40+
Computed: true,
41+
},
42+
"content": {
43+
Description: "base64 encoded file content. No other encoding is currently supported, because of a [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/342430).",
44+
Type: schema.TypeString,
45+
Required: true,
46+
ValidateFunc: validateBase64Content,
47+
},
48+
"content_sha256": {
49+
Description: "File content sha256 digest.",
50+
Type: schema.TypeString,
51+
Computed: true,
52+
},
53+
"blob_id": {
54+
Description: "The blob id.",
55+
Type: schema.TypeString,
56+
Computed: true,
57+
},
58+
"commit_id": {
59+
Description: "The commit id.",
60+
Type: schema.TypeString,
61+
Computed: true,
62+
},
63+
"last_commit_id": {
64+
Description: "The last known commit id.",
65+
Type: schema.TypeString,
66+
Computed: true,
67+
},
68+
}
69+
}
70+
71+
func gitlabRepositoryFileToStateMap(project string, repositoryFile *gitlab.File) map[string]interface{} {
72+
stateMap := make(map[string]interface{})
73+
stateMap["project"] = project
74+
stateMap["file_name"] = repositoryFile.FileName
75+
stateMap["file_path"] = repositoryFile.FilePath
76+
stateMap["size"] = repositoryFile.Size
77+
stateMap["encoding"] = repositoryFile.Encoding
78+
stateMap["content"] = repositoryFile.Content
79+
stateMap["content_sha256"] = repositoryFile.SHA256
80+
stateMap["ref"] = repositoryFile.Ref
81+
stateMap["blob_id"] = repositoryFile.BlobID
82+
stateMap["commit_id"] = repositoryFile.CommitID
83+
stateMap["last_commit_id"] = repositoryFile.LastCommitID
84+
return stateMap
85+
}

0 commit comments

Comments
 (0)