Пример #1
0
// Download downloads the application source code from the GIT repository
// and checkout the Ref specified in the config.
func (c *Clone) Download(config *api.Config) (*api.SourceInfo, error) {
	targetSourceDir := filepath.Join(config.WorkingDir, api.Source)
	config.WorkingSourceDir = targetSourceDir
	var info *api.SourceInfo

	if c.ValidCloneSpec(config.Source) {
		if len(config.ContextDir) > 0 {
			targetSourceDir = filepath.Join(config.WorkingDir, api.ContextTmp)
		}
		glog.V(2).Infof("Cloning into %s", targetSourceDir)
		if err := c.Clone(config.Source, targetSourceDir); err != nil {
			glog.V(1).Infof("Git clone failed: %+v", err)
			return nil, err
		}

		if len(config.Ref) > 0 {
			if err := c.Checkout(targetSourceDir, config.Ref); err != nil {
				return nil, err
			}
			glog.V(1).Infof("Checked out %q", config.Ref)
		}

		if len(config.ContextDir) > 0 {
			originalTargetDir := filepath.Join(config.WorkingDir, api.Source)
			c.RemoveDirectory(originalTargetDir)
			// we want to copy entire dir contents, thus we need to use dir/. construct
			path := filepath.Join(targetSourceDir, config.ContextDir) + string(filepath.Separator) + "."
			err := c.Copy(path, originalTargetDir)
			if err != nil {
				return nil, err
			}
			info = c.GetInfo(targetSourceDir)
			c.RemoveDirectory(targetSourceDir)
		} else {
			info = c.GetInfo(targetSourceDir)
		}

		if len(config.ContextDir) > 0 {
			info.ContextDir = config.ContextDir
		}

		return info, nil
	}
	// we want to copy entire dir contents, thus we need to use dir/. construct
	path := filepath.Join(config.Source, config.ContextDir) + string(filepath.Separator) + "."
	if !c.Exists(path) {
		return nil, errors.NewSourcePathError(path)
	}
	if err := c.Copy(path, targetSourceDir); err != nil {
		return nil, err
	}

	// When building from a local directory (not using GIT clone spec scheme) we
	// skip gathering informations about the source as there is no guarantee that
	// the folder is a GIT repository or it requires context-dir to be set.
	if !config.Quiet {
		glog.Warning("You are using <source> location that is not valid GIT repository. The source code information will not be stored into the output image. Use this image only for local testing and development.")
	}
	return nil, nil
}
Пример #2
0
func TestFetchSource(t *testing.T) {
	type fetchTest struct {
		validCloneSpec   bool
		refSpecified     bool
		cloneExpected    bool
		checkoutExpected bool
		copyExpected     bool
		sourcePath       string
		expectedError    *error
	}

	err := stierr.NewSourcePathError("error")
	tests := []fetchTest{
		// 0
		{
			validCloneSpec:   false,
			refSpecified:     false,
			cloneExpected:    false,
			checkoutExpected: false,
			copyExpected:     false,
			sourcePath:       "invalid/path",
			expectedError:    &err,
		},
		// 1
		{
			validCloneSpec:   false,
			refSpecified:     false,
			cloneExpected:    false,
			checkoutExpected: false,
			copyExpected:     true,
		},
		// 2
		{
			validCloneSpec:   true,
			refSpecified:     false,
			cloneExpected:    true,
			checkoutExpected: false,
			copyExpected:     false,
		},
		// 3
		{
			validCloneSpec:   true,
			refSpecified:     true,
			cloneExpected:    true,
			checkoutExpected: true,
			copyExpected:     false,
		},
	}

	for testNum, ft := range tests {
		bh := testBuildHandler()
		gh := bh.git.(*test.FakeGit)
		fh := bh.fs.(*test.FakeFileSystem)

		bh.config.WorkingDir = "/working-dir"
		gh.ValidCloneSpecResult = ft.validCloneSpec
		if ft.refSpecified {
			bh.config.Ref = "a-branch"
		}
		if len(ft.sourcePath) == 0 {
			bh.config.Source = "a-repo-source"
		} else {
			bh.config.Source = ft.sourcePath
		}

		expectedTargetDir := "/working-dir/upload/src"
		_, e := bh.source.Download(bh.config)
		if ft.expectedError == nil && e != nil {
			t.Errorf("Unexpected error %v [%d]", e, testNum)
		}
		if ft.expectedError != nil {
			if e == nil {
				t.Errorf("Did not get expected error [%d]", testNum)
				continue
			}
			if (*ft.expectedError).(stierr.Error).ErrorCode != e.(stierr.Error).ErrorCode {
				t.Errorf("Expected error code %d, got %d [%d]", (*ft.expectedError).(stierr.Error).ErrorCode, e.(stierr.Error).ErrorCode, testNum)
			}
		}
		if ft.cloneExpected {
			if gh.CloneSource != "a-repo-source" {
				t.Errorf("Clone was not called with the expected source. Got %s, expected %s [%d]", gh.CloneSource, "a-source-repo-source", testNum)
			}
			if gh.CloneTarget != expectedTargetDir {
				t.Errorf("Unexpected target directory for clone operation. Got %s, expected %s [%d]", gh.CloneTarget, expectedTargetDir, testNum)
			}
		}
		if ft.checkoutExpected {
			if gh.CheckoutRef != "a-branch" {
				t.Errorf("Checkout was not called with the expected branch. Got %s, expected %s [%d]", gh.CheckoutRef, "a-branch", testNum)
			}
			if gh.CheckoutRepo != expectedTargetDir {
				t.Errorf("Unexpected target repository for checkout operation. Got %s, expected %s [%d]", gh.CheckoutRepo, expectedTargetDir, testNum)
			}
		}
		if ft.copyExpected {
			if fh.CopySource != "a-repo-source/." {
				t.Errorf("Copy was not called with the expected source. Got %s, expected %s [%d]", fh.CopySource, "a-repo-source/.", testNum)
			}
			if fh.CopyDest != expectedTargetDir {
				t.Errorf("Unexpected target director for copy operation. Got %s, expected %s [%d]", fh.CopyDest, expectedTargetDir, testNum)
			}
		}
	}
}
Пример #3
0
// Download downloads the application source code from the Git repository
// and checkout the Ref specified in the config.
func (c *Clone) Download(config *api.Config) (*api.SourceInfo, error) {
	targetSourceDir := filepath.Join(config.WorkingDir, api.Source)
	config.WorkingSourceDir = targetSourceDir
	var info *api.SourceInfo
	hasRef := len(config.Ref) > 0
	hasSubmodules := !config.DisableRecursive
	cloneConfig := api.CloneConfig{Quiet: true, Recursive: hasSubmodules && !hasRef}

	if c.ValidCloneSpec(config.Source) {
		if len(config.ContextDir) > 0 {
			targetSourceDir = filepath.Join(config.WorkingDir, api.ContextTmp)
			glog.V(1).Infof("Downloading %q (%q) ...", config.Source, config.ContextDir)
		} else {
			glog.V(1).Infof("Downloading %q ...", config.Source)
		}

		// If we have a specific checkout ref, use submodule update instead of recursive
		// Otherwise the versions will be incorrect.
		if hasRef && hasSubmodules {
			glog.V(2).Infof("Cloning sources (deferring submodule init) into %q", targetSourceDir)
		} else if cloneConfig.Recursive {
			glog.V(2).Infof("Cloning sources and all Git submodules into %q", targetSourceDir)
		} else {
			glog.V(2).Infof("Cloning sources into %q", targetSourceDir)
		}

		if err := c.Clone(config.Source, targetSourceDir, cloneConfig); err != nil {
			glog.V(1).Infof("Git clone failed: %+v", err)
			return nil, err
		}

		if hasRef {
			if err := c.Checkout(targetSourceDir, config.Ref); err != nil {
				return nil, err
			}
			glog.V(1).Infof("Checked out %q", config.Ref)
			if hasSubmodules {
				if err := c.SubmoduleUpdate(targetSourceDir, true, true); err != nil {
					return nil, err
				}
				glog.V(1).Infof("Updated submodules for %q", config.Ref)
			}
		}

		if len(config.ContextDir) > 0 {
			originalTargetDir := filepath.Join(config.WorkingDir, api.Source)
			c.RemoveDirectory(originalTargetDir)
			// we want to copy entire dir contents, thus we need to use dir/. construct
			path := filepath.Join(targetSourceDir, config.ContextDir) + string(filepath.Separator) + "."
			err := c.Copy(path, originalTargetDir)
			if err != nil {
				return nil, err
			}
			info = c.GetInfo(targetSourceDir)
			c.RemoveDirectory(targetSourceDir)
		} else {
			info = c.GetInfo(targetSourceDir)
		}

		if len(config.ContextDir) > 0 {
			info.ContextDir = config.ContextDir
		}

		return info, nil
	}
	// we want to copy entire dir contents, thus we need to use dir/. construct
	path := filepath.Join(config.Source, config.ContextDir) + string(filepath.Separator) + "."
	if !c.Exists(path) {
		return nil, errors.NewSourcePathError(path)
	}
	if err := c.Copy(path, targetSourceDir); err != nil {
		return nil, err
	}

	// When building from a local directory (not using Git clone spec scheme) we
	// skip gathering informations about the source as there is no guarantee that
	// the folder is a Git repository or it requires context-dir to be set.
	if !config.Quiet {
		glog.Warning("You are using <source> location that is not valid Git repository. The source code information will not be stored into the output image. Use this image only for local testing and development.")
	}
	return nil, nil
}