Beispiel #1
0
// Exists checks for codebase existence by using the basic pkg rev Exists()
// routine to see if the specified codebase (at any specified rev, or from
// the default VCS rev) can be found.  If so it'll return the fullest URI
// it can to that codebase pkg repo, otherwise an error is returned.
// Config file and env var settings can help to find the codebase, ie:
// * DVLN_CODEBASE_PATH in env or codebase_path in cfg file
// -  > space separated list of paths to prepend to the codebase name
// -  > eg: "github.com/dvln git+ssh://host.com/path/to/clones /some/local/dir"
// -     - note: 'hub' and 'hub:<uri>' reserved for future user/central dvln hub
// -  > all values are *always* forward slash regardless of platform
// -  > 'dvln' as the codebase would result in looking, in order, here:
// -     > "github.com/dvln/dvln[.git]"
// -     > "git+ssh://host.com/clone/path/dvln[.git]"
// -     > "/some/local/dir/dvln[.git]"
// -     > "dvln"
// -  > final fallback will be on the individual dvln itself
// Based on the above existence checks it'll return:
// - string: URI: full path (on filesystem) or URL (if remote), "" if not found
// - locality: where it exists (LocalDir, RemoteURL, NonExistent)
// - error: any error that is detected in scanning for the workspace
func (cb *Defn) Exists(codebaseVerSel string) (string, Locality, error) {
	//eriknow, make some choices around codebase existence checks...
	//         should be a challenge, that's for sure
	var err error
	exists := false
	if codebaseVerSel != "" {
		exists, err = file.Exists(codebaseVerSel)
	}
	wkspcRootDir := ""
	if !exists {
		wkspcRootDir = globs.GetString("wkspcRootDir")
	}
	if wkspcRootDir == "" {
		wkspcRootDir = globs.GetString("dvlnCfgDir")
	}
	if codebaseVerSel == "" || !exists || err != nil {
		if err == nil {
			out.Debugln("No codebase file to read, skipping (considered normal)")
		} else {
			out.Debugf("No codebase file to read, skipping (abnormal, unexpected err: %s)\n", err)
		}
		return "", NonExistent, err
	}
	return codebaseVerSel, LocalDir, nil
}
Beispiel #2
0
Datei: git.go Projekt: dvln/vcs
// GitHookInstalled is used to check if a given hook is installed as
// specified, it does nothing more,  Params:
//	h (*GitHookMgr): the hook mgr structure (find location of repo/etc)
//	path (string): where is the hook we wish to install?
//	name (string): what is the "git name" for the hook?
//	link (bool): is hook a symlink to hookPath, or full copy/install?
// Returns boolean, true if hook is installed as specified, false otherwise
func GitHookInstalled(h *GitHookMgr, path, name string, link bool) bool {
	cachedPathHashes := make(map[string]string)
	repoPath, _, err := h.Exists(LocalPath)
	hookInstalled := false
	hookInstallPath := ""
	if err == nil && repoPath != "" { // if the local path exists...
		hookInstallPath = filepath.Join(repoPath, ".git", "hooks", name)
		if isBareRepo(repoPath) {
			hookInstallPath = filepath.Join(repoPath, "hooks", name)
		}
		if link { // if client wants a link, see if link is there already...
			fileInfo, err := os.Lstat(hookInstallPath)
			if err != nil {
				return false // if not there then installed is false
			}
			if fileInfo.Mode()&os.ModeSymlink == 0 {
				return false // if not a symlink then installed is false
			}
			originFile, err := os.Readlink(hookInstallPath)
			if err != nil {
				return false // if cannot read link, installed is false
			}
			if originFile != path {
				return false // target is not what we wanted, installed is false
			}
			hookInstalled = true
		} else { // user wants copy of file, see if there and sha matches..
			if there, err := file.Exists(hookInstallPath); err != nil || !there {
				return false // err checking existence|not there, not installed
			}
			installed, err := ioutil.ReadFile(hookInstallPath)
			hasher := sha256.New()
			hasher.Write(installed)
			installedFileHash := hex.EncodeToString(hasher.Sum(nil))
			if err != nil {
				return false // failed to read file, assume not installed
			}
			wantedFileHash := ""
			if cachedHash, ok := cachedPathHashes[path]; ok {
				wantedFileHash = cachedHash // only gen the hash of the target file once per pass
			} else {
				wanted, err2 := ioutil.ReadFile(path)
				if err2 != nil {
					return false // failed to read file, assume not installed
				}
				hasher = sha256.New()
				hasher.Write(wanted)
				wantedFileHash = hex.EncodeToString(hasher.Sum(nil))
			}
			if installedFileHash != wantedFileHash {
				return false // sha's differ, assume rev we want not installed
			}
			hookInstalled = true
		}
	}
	return hookInstalled
}
Beispiel #3
0
Datei: git.go Projekt: dvln/vcs
// GitHookInstall is used to install a hook into a git clone, params:
//	h (*GitHookMgr): the hook mgr structure (find location of repo/etc)
//	path (string): where is the hook we wish to install?
//	name (string): what is the "git name" for the hook?
//	link (bool): is hook a symlink to hookPath, or full copy/install?
// Returns full path/name to git hook installed along w/any error seen
func GitHookInstall(h *GitHookMgr, path, name string, link bool) (string, error) {
	repoPath, _, err := h.Exists(LocalPath)
	hookInstallPath := ""
	if err == nil && repoPath != "" { // if the local path exists...
		hookInstallPath = filepath.Join(repoPath, ".git", "hooks", name)
		if isBareRepo(repoPath) {
			hookInstallPath = filepath.Join(repoPath, "hooks", name)
		}
		if there, err := file.Exists(hookInstallPath); err == nil && there {
			err = os.Remove(hookInstallPath)
			if err != nil {
				return "", out.WrapErr(err, "Failed to remove previously installed hook", 4510)
			}
		}
		if there, err := file.Exists(path); err != nil || !there {
			if err != nil {
				return "", out.WrapErr(err, "Hook install failed checking source hook existence", 4511)
			}
			return "", out.NewErrf(4512, "Hook install failed, hook source path does not exist:\n  path: %s", path)
		}
		oldUmask := syscall.Umask(0)
		defer syscall.Umask(oldUmask)
		if link { // if symlink desired, try and create that
			err = os.Symlink(path, hookInstallPath)
			if err != nil {
				err = out.WrapErrf(err, 4513, "Hook install failed, failed to set up symlink:\n  linktgt: %s\n  link: %s\n", path, hookInstallPath)
			}
		} else { // otherwise try and copy in the hook file
			_, err = file.CopyFileSetPerms(path, hookInstallPath, 0775)
			if err != nil {
				err = out.WrapErrf(err, 4514, "Hook install failed, failed to copy hook file:\n  hook source path %s\n  hook install path: %s\n", path, hookInstallPath)
			}
		}
	}
	return hookInstallPath, err
}
Beispiel #4
0
Datei: git.go Projekt: dvln/vcs
// findGitDirs expects to be pointed at a git workspace, either
// bare or standard.  It'll find the gitdir and worktree dirs
// and return them, if it fails it'll return non-nil err.  Params:
//	path (string): path to the git workspace
// Returns:
//	gitDir (string): path to git metadata location
//	workTreeDir (string): working tree, "" if bare clone
//	err (error): a valid error if unable to find a git repo
func findGitDirs(path string) (string, string, error) {
	gitDir := filepath.Join(path, ".git") // see if std git clone
	var err error
	var exists bool
	if exists, err = dir.Exists(gitDir); exists && err == nil {
		return gitDir, path, nil
	}
	gitRefsDir := filepath.Join(path, "refs")
	if exists, err = dir.Exists(gitRefsDir); exists && err == nil {
		gitConfigFile := filepath.Join(path, "config")
		if exists, err = file.Exists(gitConfigFile); exists && err == nil {
			return path, "", nil
		}
	}

	if err == nil {
		return "", "", out.WrapErrf(ErrNoExist, 4500, "Unable to find valid git clone under path: %s", path)
	}
	return "", "", out.WrapErrf(ErrNoExist, 4500, "Unable to find valid git clone under path: %s\n  existence err: %s", path, err)
}
Beispiel #5
0
// This tests non-bare git repo's with the various bits of git functionality within the
// VCS package... at least those items applicable to non-bare git repo's which is pretty
// much all features
func TestGit(t *testing.T) {
	tempDir, err := ioutil.TempDir("", "go-vcs-git-tests")
	if err != nil {
		t.Fatal(err)
	}
	defer func() {
		err = os.RemoveAll(tempDir)
		if err != nil {
			t.Error(err)
		}
	}()
	testClone := filepath.Join(tempDir, "VCSTestRepo")

	mirror := true
	gitGetter, err := NewGitGetter("https://github.com/dvln/git-test-repo", "", testClone, !mirror)
	if err != nil {
		t.Fatalf("Unable to instantiate new Git VCS reader, Err: %s", err)
	}

	if gitGetter.Vcs() != Git {
		t.Error("Git is detecting the wrong type")
	}

	// Check the basic getters.
	if gitGetter.Remote() != "https://github.com/dvln/git-test-repo" {
		t.Error("Remote not set properly")
	}
	if gitGetter.LocalRepoPath() != testClone {
		t.Error("Local disk location not set properly")
	}

	// Do an initial mirror clone.
	results, err := gitGetter.Get()
	if err != nil {
		t.Fatalf("Unable to clone Git repo using VCS reader Get(). Err was: %s, details:\n%s", err, results)
	}

	// Verify Git repo exists in the workspace
	path, _, err := gitGetter.Exists(LocalPath)
	if err != nil {
		t.Fatalf("Existence check failed on git repo: %s", err)
	}
	if path == "" {
		t.Error("Problem seeing if Git repo exists in workspace")
	}

	// Test internal lookup mechanism used outside of Git specific functionality.
	ltype, err := DetectVcsFromFS(testClone)
	if err != nil {
		t.Error("detectVcsFromFS unable to detect Git repo")
	}
	if ltype != Git {
		t.Errorf("detectVcsFromFS detected %s instead of Git type", ltype)
	}

	// Test NewReader on existing checkout. This should simply provide a working
	// instance without error based on looking at the local directory.
	gitReader, err := NewReader("https://github.com/dvln/git-test-repo", testClone)
	if err != nil {
		t.Fatal(err)
	}
	if gitReader == nil {
		t.Fatal("gitReader interface was unexpectedly nil")
	}

	// See if the new git VCS reader was instantiated in the workspace
	path, _, err = gitReader.Exists(LocalPath)
	if err != nil {
		t.Errorf("Existence check failed on git repo: %s", err)
	}
	if path == "" {
		t.Error("The git reader was not correctly instantiated in the workspace")
	}

	// Perform an update operation
	gitUpdater, err := NewUpdater("https://github.com/dvln/git-test-repo", "origin", testClone, !mirror, RebaseFalse, nil)
	if err != nil {
		t.Fatal(err)
	}
	results, err = gitUpdater.Update()
	if err != nil {
		t.Fatalf("Failed to run git update, error: %s, results:\n%s", err, results)
	}

	// Set the version (checkout) using a short sha1 that should exist
	results, err = gitReader.RevSet("3f690c9")
	if err != nil {
		t.Fatalf("Unable to update Git repo version. Err was: %s, results:\n%s", err, results)
	}

	// Use RevRead to verify we are on the right version.
	v, _, err := gitReader.RevRead(CoreRev)
	if string(v[0].Core()) != "3f690c91af378fbd09628f9833abb1c3d6828c5e" {
		t.Errorf("Error checking checked out Git version, found: \"%s\"\n", string(v[0].Core()))
	}
	if err != nil {
		t.Error(err)
	}

	// Verify that we can set the version something other than short hash
	_, err = gitReader.RevSet("master")
	if err != nil {
		t.Errorf("Unable to update Git repo version. Err was %s", err)
	}
	_, err = gitReader.RevSet("28d488c8deda544076f56b279824657fa691ef01")
	if err != nil {
		t.Errorf("Unable to update Git repo version. Err was %s", err)
	}
	v, _, err = gitReader.RevRead(CoreRev)
	if string(v[0].Core()) != "28d488c8deda544076f56b279824657fa691ef01" {
		t.Errorf("Error checking checked out Git version, found: \"%s\"\n", string(v[0].Core()))
	}
	if err != nil {
		t.Error(err)
	}

	// Install a git hook, verify existence, then remove it, verify gone
	gitHookMgr, err := NewHookMgr(testClone)
	if err != nil {
		t.Fatalf("Failed to set up a new git hook manager, err:\n %s\n", err)
	}
	// First do a run with an invalid source path, insure that fails (this
	// is not a bare repo so that will not be found as it doesn't exist)
	hookSrc := filepath.Join(testClone, "hooks", "pre-push.sample")
	link := true
	hookLinkPath, err := gitHookMgr.Install(hookSrc, "pre-push", link)
	if err == nil {
		t.Fatal("Hook install of link should have failed as target is not there")
	}
	// Now do a run with the real non-bare path that should exist...
	hookSrc = filepath.Join(testClone, ".git", "hooks", "pre-push.sample")
	hookLinkPath, err = gitHookMgr.Install(hookSrc, "pre-push", link)
	if err != nil {
		t.Fatalf("Failed to install git hook symlink, error:\n%s\n", err)
	}
	fileInfo, err := os.Lstat(hookLinkPath)
	if err != nil {
		t.Fatalf("Should have set up a hook symlink but os.Lstat failed, err: %s\n", err)
	}
	if fileInfo.Mode()&os.ModeSymlink == 0 {
		t.Fatal("Should have created a symlink but file created was not a symlink")
	}
	originFile, err := os.Readlink(hookLinkPath)
	if err != nil {
		t.Fatalf("Should have created a symlink but failed to resolve symlink, err: %s", err)
	}
	if originFile != hookSrc {
		t.Fatalf("Installed hook symlink not pointing correctly:\n  found: %s\n  need: %s\n", originFile, hookSrc)
	}
	err = gitHookMgr.Remove("pre-push")
	if err != nil {
		t.Fatalf("Failed to remove hook symlink, err: %s", err)
	}
	if there, err := file.Exists(hookLinkPath); err != nil || there {
		t.Fatalf("Removal of hook symlink seems to have failed (err: %s, there: %s)\n", err, there)
	}

	// Now lets try a copy type hook install and removal
	hookCopyPath, err := gitHookMgr.Install(hookSrc, "pre-push", !link)
	if err != nil {
		t.Fatalf("Failed to install (copy) git hook\n  src:%s\n  tgt:%s\n  err: %s\n", hookSrc, hookCopyPath, err)
	}
	fileInfo, err = os.Stat(hookCopyPath)
	if err != nil {
		t.Fatalf("Should have just copied file but os.Stat failed, err: %s\n", err)
	}
	srcFileInfo, err := os.Stat(hookSrc)
	if err != nil {
		t.Fatalf("Should have copied a symlink but os.Stat failed, err: %s\n", err)
	}
	if fileInfo.Size() != srcFileInfo.Size() {
		t.Fatal("File size of copied file not matching source")
	}
	err = gitHookMgr.Remove("pre-push")
	if err != nil {
		t.Fatalf("Failed to remove hook file, err: %s", err)
	}
	if there, err := file.Exists(hookCopyPath); err != nil || there {
		t.Fatalf("Removal of hook file seems to have failed (err: %s, there: %s)\n", err, there)
	}
}