Repository: Azure/draft
Pull request #222 (2023-07-06 17:40:34)

add repo name reading support
# Description
Add a method for reading a repo's name to the RepoReader Interface, which will allow a sensible default for the name of the generated deployment

For the implementation on the filesystem reporeader, it uses the repo root dir name as an approximation of the repo name.
Later integration could include vcs or git integration to extract the name from a remote url

## Type of change

Please delete options that are not relevant.

- [x] New feature (non-breaking change which adds functionality)

# How Has This Been Tested?

- Existing integration and unit tests
- Added tests for new method and fulfilled interface changes

# Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream modules



kyliel: Attach comment from bacongobbler on the other thread. 
--
We're playing around with the idea of packaging up several projects including Draft in a nicely bundled .msi, .pkg and .deb at some point, so eventually that step to copy Draft off to a directory on your $PATH will eventually go away if that comes to fruition.That may also be our draftd upgrade story... at least if the bundled package also includes minikube and upgrades the components during the .msi installer.


bacongobbler: I have a work-in-progress homebrew repository that would install Draft, Minikube, Helm and others locally without having to worry about moving the binaries onto your $PATH. This only works for macOS, though. I'm still trying to figure out if it's the right path we want to go, but I figured I'd just bump this ticket and say we are working on it :)
bacongobbler: I just realized we have a duplicate issue at #161, so I'm closing this in favour of that ticket. Thank you @kyliel!

Patch:
diff --git a/pkg/reporeader/readers/localfsreader.go b/pkg/reporeader/readers/localfsreader.go
index 27cbb98..c684b9c 100644
--- a/pkg/reporeader/readers/localfsreader.go
+++ b/pkg/reporeader/readers/localfsreader.go
@@ -13,6 +13,16 @@ import (
 type LocalFSReader struct {
 }
 
+// GetRepoName returns the name of the current directory, which is an approximation of the repo name
+func (*LocalFSReader) GetRepoName() (string, error) {
+	wd, err := os.Getwd()
+	if err != nil {
+		return "", fmt.Errorf("unable to get working directory: %v", err)
+	}
+	dirName := filepath.Base(wd)
+	return dirName, nil
+}
+
 type LocalFileFinder struct {
 	Patterns   []string
 	FoundFiles []string
diff --git a/pkg/reporeader/reporeader.go b/pkg/reporeader/reporeader.go
index 9c746e2..ffab238 100644
--- a/pkg/reporeader/reporeader.go
+++ b/pkg/reporeader/reporeader.go
@@ -11,6 +11,7 @@ type RepoReader interface {
 	// FindFiles returns a list of files that match the given patterns searching up to
 	// maxDepth nested sub-directories. maxDepth of 0 limits files to the root dir.
 	FindFiles(path string, patterns []string, maxDepth int) ([]string, error)
+	GetRepoName() (string, error)
 }
 
 // VariableExtractor is an interface that can be implemented for extracting variables from a repo's files
@@ -20,12 +21,21 @@ type VariableExtractor interface {
 	GetName() string
 }
 
-// TestRepoReader is a RepoReader that can be used for testing, and takes a list of relative file paths with their contents
-type TestRepoReader struct {
+// FakeRepoReader is a RepoReader that can be used for testing, and takes a list of relative file paths with their contents
+type FakeRepoReader struct {
 	Files map[string][]byte
 }
 
-func (r TestRepoReader) Exists(path string) bool {
+// GetRepoName returns the name of the repo
+func (FakeRepoReader) GetRepoName() (string, error) {
+	return "test-repo", nil
+}
+
+var _ RepoReader = FakeRepoReader{
+	Files: map[string][]byte{},
+}
+
+func (r FakeRepoReader) Exists(path string) bool {
 	if r.Files != nil {
 		_, ok := r.Files[path]
 		return ok
@@ -33,14 +43,14 @@ func (r TestRepoReader) Exists(path string) bool {
 	return false
 }
 
-func (r TestRepoReader) ReadFile(path string) ([]byte, error) {
+func (r FakeRepoReader) ReadFile(path string) ([]byte, error) {
 	if r.Files != nil {
 		return r.Files[path], nil
 	}
 	return nil, nil
 }
 
-func (r TestRepoReader) FindFiles(path string, patterns []string, maxDepth int) ([]string, error) {
+func (r FakeRepoReader) FindFiles(path string, patterns []string, maxDepth int) ([]string, error) {
 	var files []string
 	if r.Files == nil {
 		return files, nil


Test patch:
diff --git a/cmd/create_test.go b/cmd/create_test.go
index 45343ca..99c96f8 100644
--- a/cmd/create_test.go
+++ b/cmd/create_test.go
@@ -98,7 +98,7 @@ func TestRun(t *testing.T) {
 
 func TestRunCreateDockerfileWithRepoReader(t *testing.T) {
 
-	testRepoReader := &reporeader.TestRepoReader{Files: map[string][]byte{
+	testRepoReader := &reporeader.FakeRepoReader{Files: map[string][]byte{
 		"foo.py":  []byte("print('Hello World')"),
 		"main.py": []byte("print('Hello World')"),
 	}}
diff --git a/pkg/languages/defaults/gradle_test.go b/pkg/languages/defaults/gradle_test.go
index e4dc0d3..ee0b2ba 100644
--- a/pkg/languages/defaults/gradle_test.go
+++ b/pkg/languages/defaults/gradle_test.go
@@ -25,7 +25,7 @@ func TestGradleExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract gradle jre version with spaces",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"build.gradle": []byte("group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility=\"11\" targetCompatibility='11'"),
 					},
@@ -40,7 +40,7 @@ func TestGradleExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract gradle jre version with new lines",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"build.gradle": []byte("group = 'com.example'\nversion = '0.0.1-SNAPSHOT'\nsourceCompatibility=\"11\"\ntargetCompatibility='11'"),
 					},
@@ -55,7 +55,7 @@ func TestGradleExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract gradle jre version with tabs",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"build.gradle": []byte("group = 'com.example'\tversion = '0.0.1-SNAPSHOT'\tsourceCompatibility= \"12\" \ntargetCompatibility='11'"),
 					},
@@ -70,7 +70,7 @@ func TestGradleExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract gradle jre version with double spaces",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"build.gradle": []byte("group = 'com.example'  version = '0.0.1-SNAPSHOT'  sourceCompatibility=\"12\"\ntargetCompatibility='11'"),
 					},
@@ -85,7 +85,7 @@ func TestGradleExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract gradle jre version reading from a file",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"build.gradle": content,
 					},
diff --git a/pkg/languages/defaults/python_test.go b/pkg/languages/defaults/python_test.go
index 99fd70a..996f776 100644
--- a/pkg/languages/defaults/python_test.go
+++ b/pkg/languages/defaults/python_test.go
@@ -54,7 +54,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract first python file as entrypoint",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"foo.py": []byte("print('hello world')"),
 						"bar.py": []byte("print('hello world')"),
@@ -69,7 +69,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract python file containing the string \"if __name__ == '__main__'\" as the entrypoint",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"foo.py": []byte("print('hello world')"),
 						"bar.py": []byte("if __name__ == '__main__' : print('hello world')"),
@@ -84,7 +84,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract python file containing the string \"if __name__==\"__main__\"\" as the entrypoint",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"foo.py": []byte("print('hello world')"),
 						"bar.py": []byte("if __name__==\"__main__\": print('hello world')"),
@@ -99,7 +99,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "extract python file named app.py as the entrypoint",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"foo.py": []byte("print('Hello World')"),
 						"app.py": []byte("print('Hello World')"),
@@ -114,7 +114,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "no extraction if no python files",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"foo.notpy": []byte("print('hello world')"),
 						"bar":       []byte("print('hello world')"),
@@ -127,7 +127,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "empty extraction with no files",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{},
 				},
 			},
@@ -137,7 +137,7 @@ func TestPythonExtractor_ReadDefaults(t *testing.T) {
 		{
 			name: "ignore files below depth root depth",
 			args: args{
-				r: reporeader.TestRepoReader{
+				r: reporeader.FakeRepoReader{
 					Files: map[string][]byte{
 						"dir/foo.py": []byte("print('hello world')"),
 					},