From 9e058f2be242dc91d6ea001ee85f8bdc24ceae8e Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Mon, 19 Jun 2023 10:18:06 +0200 Subject: [PATCH 1/5] Indexer does not ignore .git --- pkg/util/file_indexer.go | 2 +- pkg/util/file_indexer_test.go | 28 ---------------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/pkg/util/file_indexer.go b/pkg/util/file_indexer.go index 505d51f804b..0e10fbd9612 100644 --- a/pkg/util/file_indexer.go +++ b/pkg/util/file_indexer.go @@ -462,7 +462,7 @@ func recursiveChecker(pathOptions recursiveCheckerPathOptions, ignoreRules []str if stat.IsDir() { - if stat.Name() == DotOdoDirectory || stat.Name() == ".git" { + if stat.Name() == DotOdoDirectory { return IndexerRet{}, nil } diff --git a/pkg/util/file_indexer_test.go b/pkg/util/file_indexer_test.go index f43eba74400..a5a2f35720f 100644 --- a/pkg/util/file_indexer_test.go +++ b/pkg/util/file_indexer_test.go @@ -256,24 +256,6 @@ func createAndStat(fileName, tempDirectoryName string, fs filesystem.Filesystem) return file, stat, nil } -func createGitFolderAndFiles(tempDirectoryName string, fs filesystem.Filesystem) error { - err := fs.MkdirAll(filepath.Join(tempDirectoryName, ".git"), 0755) - if err != nil { - return err - } - - err = fs.MkdirAll(filepath.Join(tempDirectoryName, DotOdoDirectory), 0755) - if err != nil { - return err - } - - _, err = fs.Create(filepath.Join(tempDirectoryName, ".git", "someFile.txt")) - if err != nil { - return err - } - return nil -} - func Test_recursiveChecker(t *testing.T) { fs := filesystem.DefaultFs{} @@ -282,11 +264,6 @@ func Test_recursiveChecker(t *testing.T) { t.Errorf("unexpected error: %v", err) } - err = createGitFolderAndFiles(tempDirectoryName, fs) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - jsFileName := "red.js" jsFile, jsFileStat, err := createAndStat(jsFileName, tempDirectoryName, fs) if err != nil { @@ -1179,11 +1156,6 @@ func Test_runIndexerWithExistingFileIndex(t *testing.T) { t.Errorf("unexpected error: %v", err) } - err = createGitFolderAndFiles(tempDirectoryName, fs) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - jsFileName := "red.js" jsFile, jsFileStat, err := createAndStat(jsFileName, tempDirectoryName, fs) if err != nil { From e10854a3cb4eed81e70e0d6c7282ad0e613a035c Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Mon, 19 Jun 2023 10:19:18 +0200 Subject: [PATCH 2/5] add --sync-git-dir flag to odo dev --- pkg/odo/cli/dev/dev.go | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pkg/odo/cli/dev/dev.go b/pkg/odo/cli/dev/dev.go index 9f258960a4d..21fad90d913 100644 --- a/pkg/odo/cli/dev/dev.go +++ b/pkg/odo/cli/dev/dev.go @@ -4,8 +4,6 @@ import ( "context" "errors" "fmt" - apiserver_impl "github.com/redhat-developer/odo/pkg/apiserver-impl" - "github.com/redhat-developer/odo/pkg/odo/cli/feature" "io" "path/filepath" "regexp" @@ -13,6 +11,9 @@ import ( "strconv" "strings" + apiserver_impl "github.com/redhat-developer/odo/pkg/apiserver-impl" + "github.com/redhat-developer/odo/pkg/odo/cli/feature" + "github.com/devfile/api/v2/pkg/apis/workspaces/v1alpha2" "github.com/spf13/cobra" "k8s.io/klog/v2" @@ -74,6 +75,7 @@ type DevOptions struct { noCommandsFlag bool apiServerFlag bool apiServerPortFlag int + syncGitDirFlag bool } var _ genericclioptions.Runnable = (*DevOptions)(nil) @@ -239,6 +241,10 @@ func (o *DevOptions) Run(ctx context.Context) (err error) { // Ignore the devfile, as it will be handled independently o.ignorePaths = ignores + if o.syncGitDirFlag { + o.ignorePaths = removeGitDir(o.ignorePaths) + } + scontext.SetComponentType(ctx, component.GetComponentTypeFromDevfileMetadata(devFileObj.Data.GetMetadata())) scontext.SetLanguage(ctx, devFileObj.Data.GetMetadata().Language) scontext.SetProjectType(ctx, devFileObj.Data.GetMetadata().ProjectType) @@ -278,6 +284,15 @@ func (o *DevOptions) Run(ctx context.Context) (err error) { ) } +func removeGitDir(ignores []string) []string { + for i, entry := range ignores { + if entry == ".git" { + return append(ignores[0:i], ignores[i+1:]...) + } + } + return ignores +} + func (o *DevOptions) HandleSignal(ctx context.Context, cancelFunc context.CancelFunc) error { cancelFunc() // At this point, `ctx.Done()` will be raised, and the cleanup will be done @@ -325,6 +340,7 @@ It forwards endpoints with any exposure values ('public', 'internal' or 'none') "Define custom port mapping for port forwarding. Acceptable formats: LOCAL_PORT:REMOTE_PORT, LOCAL_PORT:CONTAINER_NAME:REMOTE_PORT.") devCmd.Flags().StringVar(&o.addressFlag, "address", "127.0.0.1", "Define custom address for port forwarding.") devCmd.Flags().BoolVar(&o.noCommandsFlag, "no-commands", false, "Do not run any commands; just start the development environment.") + devCmd.Flags().BoolVar(&o.syncGitDirFlag, "sync-git-dir", false, "Synchronize the .git directory to the container. By default, this directory is not synchronized.") if feature.IsExperimentalModeEnabled(ctx) { devCmd.Flags().BoolVar(&o.apiServerFlag, "api-server", false, "Start the API Server; this is an experimental feature") From caafbf87be2a808a5428177cc583e95db29d283f Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Mon, 19 Jun 2023 11:00:06 +0200 Subject: [PATCH 3/5] Integration tests --- tests/helper/helper_dev.go | 4 ++++ tests/integration/cmd_dev_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/tests/helper/helper_dev.go b/tests/helper/helper_dev.go index 2e80dd02c53..73c9a9253b2 100644 --- a/tests/helper/helper_dev.go +++ b/tests/helper/helper_dev.go @@ -132,6 +132,7 @@ type DevSessionOpts struct { CustomAddress string StartAPIServer bool APIServerPort int + SyncGitDir bool } // StartDevMode starts a dev session with `odo dev` @@ -166,6 +167,9 @@ func StartDevMode(options DevSessionOpts) (devSession DevSession, err error) { args = append(args, "--api-server-port", fmt.Sprintf("%d", options.APIServerPort)) } } + if options.SyncGitDir { + args = append(args, "--sync-git-dir") + } args = append(args, options.CmdlineArgs...) cmd := Cmd("odo", args...) cmd.Cmd.Stdin = c.Tty() diff --git a/tests/integration/cmd_dev_test.go b/tests/integration/cmd_dev_test.go index ba0290d3709..920270687b4 100644 --- a/tests/integration/cmd_dev_test.go +++ b/tests/integration/cmd_dev_test.go @@ -166,6 +166,36 @@ echo "$@" for _, podman := range []bool{true, false} { podman := podman + It("should not sync .git directory", helper.LabelPodmanIf(podman, func() { + helper.MakeDir(".git") + err := helper.CreateFileWithContent(filepath.Join(commonVar.Context, ".git", "file.txt"), "aze") + Expect(err).ToNot(HaveOccurred()) + helper.MakeDir("notgit") + err = helper.CreateFileWithContent(filepath.Join(commonVar.Context, "notgit", "otherfile.txt"), "aze") + Expect(err).ToNot(HaveOccurred()) + err = helper.RunDevMode(helper.DevSessionOpts{ + RunOnPodman: podman, + }, func(session *gexec.Session, outContents, errContents string, ports map[string]string) { + component := helper.NewComponent(cmpName, "app", labels.ComponentDevMode, commonVar.Project, commonVar.CliRunner) + component.Exec("runtime", []string{"ls", "/projects/.git/file.txt"}, pointer.Bool(false)) + component.Exec("runtime", []string{"ls", "/projects/notgit/otherfile.txt"}, pointer.Bool(true)) + }) + Expect(err).ToNot(HaveOccurred()) + })) + It("should sync .git directory with --sync-git-dir", helper.LabelPodmanIf(podman, func() { + helper.MakeDir(".git") + err := helper.CreateFileWithContent(filepath.Join(commonVar.Context, ".git", "file.txt"), "aze") + Expect(err).ToNot(HaveOccurred()) + err = helper.RunDevMode(helper.DevSessionOpts{ + RunOnPodman: podman, + SyncGitDir: true, + }, func(session *gexec.Session, outContents, errContents string, ports map[string]string) { + component := helper.NewComponent(cmpName, "app", labels.ComponentDevMode, commonVar.Project, commonVar.CliRunner) + component.Exec("runtime", []string{"ls", "/projects/.git/file.txt"}, pointer.Bool(true)) + }) + Expect(err).ToNot(HaveOccurred()) + })) + It("should use the index information from previous push operation", helper.LabelPodmanIf(podman, func() { // Create a new file A fileAPath, fileAText := helper.CreateSimpleFile(commonVar.Context, "my-file-", ".txt") From 5c60ecd58dfe8cb5a98f379af6fbd58822a95551 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Mon, 19 Jun 2023 15:30:23 +0200 Subject: [PATCH 4/5] Add doc --- docs/website/docs/development/architecture/how-odo-works.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/website/docs/development/architecture/how-odo-works.md b/docs/website/docs/development/architecture/how-odo-works.md index ecdac9d24bc..aed3b991f70 100644 --- a/docs/website/docs/development/architecture/how-odo-works.md +++ b/docs/website/docs/development/architecture/how-odo-works.md @@ -738,7 +738,7 @@ However, this is subject to three things: - the type of volume created depends on the [configuration of `odo`](../../overview/configure#preference-key-table), and more specifically on the value of the `Ephemeral` setting: - if `Ephemeral` is `false`, which is the default setting, `odo` creates a [PersistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) (PVC) (with the default storage class) - if `Ephemeral` is `true`, `odo` creates an [`emptyDir`](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume, tied to the lifetime of the Pod. -- the complete content of the current directory and its sub-directories is pushed to the container, except the files listed in the `.odoignore` file, or, if this file is not present, in the `.gitignore` file. `dev.odo.push.path:target` attributes are also considered to push only selected files. See [Pushing Source Files](../../user-guides/advanced/pushing-specific-files) for more details. +- the complete content of the current directory and its sub-directories is pushed to the container, except the files listed in the `.odoignore` file, or, if this file is not present, in the `.gitignore` file. `dev.odo.push.path:target` attributes are also considered to push only selected files. The directory `.git` is not synchronized by default. If you add the `--sync-git-dir` flag to the `odo dev` command, the `.git` repository will be synchronized to the container, regardless of its presence in `.odoignore` or `.gitignore`. See [Pushing Source Files](../../user-guides/advanced/pushing-specific-files) for more details. | Volume name | Volume Type | Mount Path | Description | |------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|-----------------------------------------------| From a8c8c35188642a51a52724445cb6bc1e6bf031f9 Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Tue, 20 Jun 2023 09:47:45 +0200 Subject: [PATCH 5/5] Force sync of complete .git content --- pkg/odo/cli/dev/dev.go | 3 +++ tests/integration/cmd_dev_test.go | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/odo/cli/dev/dev.go b/pkg/odo/cli/dev/dev.go index 21fad90d913..7519149221c 100644 --- a/pkg/odo/cli/dev/dev.go +++ b/pkg/odo/cli/dev/dev.go @@ -284,7 +284,10 @@ func (o *DevOptions) Run(ctx context.Context) (err error) { ) } +// removeGitDir removes the `.git` entry from the list of paths to ignore +// and adds `!.git`, to force the sync of all files into the .git directory func removeGitDir(ignores []string) []string { + ignores = append(ignores, "!.git") for i, entry := range ignores { if entry == ".git" { return append(ignores[0:i], ignores[i+1:]...) diff --git a/tests/integration/cmd_dev_test.go b/tests/integration/cmd_dev_test.go index 920270687b4..a4d4395a966 100644 --- a/tests/integration/cmd_dev_test.go +++ b/tests/integration/cmd_dev_test.go @@ -182,7 +182,11 @@ echo "$@" }) Expect(err).ToNot(HaveOccurred()) })) - It("should sync .git directory with --sync-git-dir", helper.LabelPodmanIf(podman, func() { + It("should sync .git directory and subfiles with --sync-git-dir", helper.LabelPodmanIf(podman, func() { + gitignorePath := filepath.Join(commonVar.Context, ".gitignore") + if err := helper.CreateFileWithContent(gitignorePath, `file.txt`); err != nil { + fmt.Printf("the .gitignore file was not created, reason %v", err.Error()) + } helper.MakeDir(".git") err := helper.CreateFileWithContent(filepath.Join(commonVar.Context, ".git", "file.txt"), "aze") Expect(err).ToNot(HaveOccurred())