| 
				
			 | 
			
			
				@@ -12,18 +12,29 @@ import ( 
			 | 
		
	
		
			
			| 
				12
			 | 
			
				12
			 | 
			
			
				 	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh" 
			 | 
		
	
		
			
			| 
				13
			 | 
			
				13
			 | 
			
			
				 ) 
			 | 
		
	
		
			
			| 
				14
			 | 
			
				14
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				15
			 | 
			
				
			 | 
			
			
				-// Sync 
			 | 
		
	
		
			
			| 
				
			 | 
			
				15
			 | 
			
			
				+// Sync synchronises a Git repository using a given configuration. "synchronises" 
			 | 
		
	
		
			
			| 
				
			 | 
			
				16
			 | 
			
			
				+// means that, if the repo from the configuration isn't already cloned in the 
			 | 
		
	
		
			
			| 
				
			 | 
			
				17
			 | 
			
			
				+// directory specified in the configuration, it will clone the repository, 
			 | 
		
	
		
			
			| 
				
			 | 
			
				18
			 | 
			
			
				+// else it will simply pull it in order to be up to date with the remote. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				19
			 | 
			
			
				+// Returns the go-git representation of the repository. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				20
			 | 
			
			
				+// Returns an error if there was an issue loading the SSH private key, checking 
			 | 
		
	
		
			
			| 
				
			 | 
			
				21
			 | 
			
			
				+// whether the clone path already exists, or synchronising the repo with the 
			 | 
		
	
		
			
			| 
				
			 | 
			
				22
			 | 
			
			
				+// remote. 
			 | 
		
	
		
			
			| 
				16
			 | 
			
				23
			 | 
			
			
				 func Sync(cfg config.GitSettings) (r *gogit.Repository, err error) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				24
			 | 
			
			
				+	// Generate an authentication structure instance from the user and private 
			 | 
		
	
		
			
			| 
				
			 | 
			
				25
			 | 
			
			
				+	// key 
			 | 
		
	
		
			
			| 
				17
			 | 
			
				26
			 | 
			
			
				 	auth, err := getAuth(cfg.User, cfg.PrivateKeyPath) 
			 | 
		
	
		
			
			| 
				18
			 | 
			
				27
			 | 
			
			
				 	if err != nil { 
			 | 
		
	
		
			
			| 
				19
			 | 
			
				28
			 | 
			
			
				 		return 
			 | 
		
	
		
			
			| 
				20
			 | 
			
				29
			 | 
			
			
				 	} 
			 | 
		
	
		
			
			| 
				21
			 | 
			
				30
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				31
			 | 
			
			
				+	// Check whether the clone path already exists 
			 | 
		
	
		
			
			| 
				22
			 | 
			
				32
			 | 
			
			
				 	exists, err := dirExists(cfg.ClonePath) 
			 | 
		
	
		
			
			| 
				23
			 | 
			
				33
			 | 
			
			
				 	if err != nil { 
			 | 
		
	
		
			
			| 
				24
			 | 
			
				34
			 | 
			
			
				 		return 
			 | 
		
	
		
			
			| 
				25
			 | 
			
				35
			 | 
			
			
				 	} 
			 | 
		
	
		
			
			| 
				26
			 | 
			
				36
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				+	// If the clone path already exists, pull from the remote, else clone it. 
			 | 
		
	
		
			
			| 
				27
			 | 
			
				38
			 | 
			
			
				 	if exists { 
			 | 
		
	
		
			
			| 
				28
			 | 
			
				39
			 | 
			
			
				 		r, err = pull(cfg.ClonePath, auth) 
			 | 
		
	
		
			
			| 
				29
			 | 
			
				40
			 | 
			
			
				 	} else { 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -33,6 +44,10 @@ func Sync(cfg config.GitSettings) (r *gogit.Repository, err error) { 
			 | 
		
	
		
			
			| 
				33
			 | 
			
				44
			 | 
			
			
				 	return 
			 | 
		
	
		
			
			| 
				34
			 | 
			
				45
			 | 
			
			
				 } 
			 | 
		
	
		
			
			| 
				35
			 | 
			
				46
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				47
			 | 
			
			
				+// getAuth returns the authentication structure instance needed to authenticate 
			 | 
		
	
		
			
			| 
				
			 | 
			
				48
			 | 
			
			
				+// on the remote, using a given user and private key path. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				+// Returns an error if there was an issue reading the private key file or 
			 | 
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				+// parsing it. 
			 | 
		
	
		
			
			| 
				36
			 | 
			
				51
			 | 
			
			
				 func getAuth(user string, privateKeyPath string) (*gitssh.PublicKeys, error) { 
			 | 
		
	
		
			
			| 
				37
			 | 
			
				52
			 | 
			
			
				 	privateKey, err := ioutil.ReadFile(privateKeyPath) 
			 | 
		
	
		
			
			| 
				38
			 | 
			
				53
			 | 
			
			
				 	if err != nil { 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -47,6 +62,9 @@ func getAuth(user string, privateKeyPath string) (*gitssh.PublicKeys, error) { 
			 | 
		
	
		
			
			| 
				47
			 | 
			
				62
			 | 
			
			
				 	return &gitssh.PublicKeys{User: "git", Signer: signer}, nil 
			 | 
		
	
		
			
			| 
				48
			 | 
			
				63
			 | 
			
			
				 } 
			 | 
		
	
		
			
			| 
				49
			 | 
			
				64
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				65
			 | 
			
			
				+// clone clones a Git repository into a given path, using a given auth. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				66
			 | 
			
			
				+// Returns the go-git representation of the Git repository. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				67
			 | 
			
			
				+// Returns an error if there was an issue cloning the repository. 
			 | 
		
	
		
			
			| 
				50
			 | 
			
				68
			 | 
			
			
				 func clone(repo string, clonePath string, auth *gitssh.PublicKeys) (*gogit.Repository, error) { 
			 | 
		
	
		
			
			| 
				51
			 | 
			
				69
			 | 
			
			
				 	return gogit.PlainClone(clonePath, false, &gogit.CloneOptions{ 
			 | 
		
	
		
			
			| 
				52
			 | 
			
				70
			 | 
			
			
				 		URL:  repo, 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -54,22 +72,33 @@ func clone(repo string, clonePath string, auth *gitssh.PublicKeys) (*gogit.Repos 
			 | 
		
	
		
			
			| 
				54
			 | 
			
				72
			 | 
			
			
				 	}) 
			 | 
		
	
		
			
			| 
				55
			 | 
			
				73
			 | 
			
			
				 } 
			 | 
		
	
		
			
			| 
				56
			 | 
			
				74
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				+// pull opens the repository located at a given path, and pulls it from the 
			 | 
		
	
		
			
			| 
				
			 | 
			
				76
			 | 
			
			
				+// remote using a given auth, in order to be up to date with the remote. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				77
			 | 
			
			
				+// Returns with the go-git representation of the repository. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				78
			 | 
			
			
				+// Returns an error if there was an issue opening the repo, getting its work 
			 | 
		
	
		
			
			| 
				
			 | 
			
				79
			 | 
			
			
				+// tree or pulling from the remote. In the latter case, if the error is "already 
			 | 
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				+// up to date" or "non-fast-forward update", doesn't return any error. 
			 | 
		
	
		
			
			| 
				57
			 | 
			
				81
			 | 
			
			
				 func pull(clonePath string, auth *gitssh.PublicKeys) (*gogit.Repository, error) { 
			 | 
		
	
		
			
			| 
				
			 | 
			
				82
			 | 
			
			
				+	// Open the repository 
			 | 
		
	
		
			
			| 
				58
			 | 
			
				83
			 | 
			
			
				 	r, err := gogit.PlainOpen(clonePath) 
			 | 
		
	
		
			
			| 
				59
			 | 
			
				84
			 | 
			
			
				 	if err != nil { 
			 | 
		
	
		
			
			| 
				60
			 | 
			
				85
			 | 
			
			
				 		return nil, err 
			 | 
		
	
		
			
			| 
				61
			 | 
			
				86
			 | 
			
			
				 	} 
			 | 
		
	
		
			
			| 
				62
			 | 
			
				87
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				+	// Get its worktree 
			 | 
		
	
		
			
			| 
				63
			 | 
			
				89
			 | 
			
			
				 	w, err := r.Worktree() 
			 | 
		
	
		
			
			| 
				64
			 | 
			
				90
			 | 
			
			
				 	if err != nil { 
			 | 
		
	
		
			
			| 
				65
			 | 
			
				91
			 | 
			
			
				 		return nil, err 
			 | 
		
	
		
			
			| 
				66
			 | 
			
				92
			 | 
			
			
				 	} 
			 | 
		
	
		
			
			| 
				67
			 | 
			
				93
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				+	// Pull from remote 
			 | 
		
	
		
			
			| 
				68
			 | 
			
				95
			 | 
			
			
				 	err = w.Pull(&gogit.PullOptions{ 
			 | 
		
	
		
			
			| 
				69
			 | 
			
				96
			 | 
			
			
				 		RemoteName: "origin", 
			 | 
		
	
		
			
			| 
				70
			 | 
			
				97
			 | 
			
			
				 		Auth:       auth, 
			 | 
		
	
		
			
			| 
				71
			 | 
			
				98
			 | 
			
			
				 	}) 
			 | 
		
	
		
			
			| 
				72
			 | 
			
				99
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				+	// Don't return with an error for "already up to date" or "non-fast-forward 
			 | 
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				+	// update" 
			 | 
		
	
		
			
			| 
				73
			 | 
			
				102
			 | 
			
			
				 	if err != nil { 
			 | 
		
	
		
			
			| 
				74
			 | 
			
				103
			 | 
			
			
				 		if err == gogit.NoErrAlreadyUpToDate { 
			 | 
		
	
		
			
			| 
				75
			 | 
			
				104
			 | 
			
			
				 			return r, nil 
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -85,6 +114,10 @@ func pull(clonePath string, auth *gitssh.PublicKeys) (*gogit.Repository, error) 
			 | 
		
	
		
			
			| 
				85
			 | 
			
				114
			 | 
			
			
				 	return r, err 
			 | 
		
	
		
			
			| 
				86
			 | 
			
				115
			 | 
			
			
				 } 
			 | 
		
	
		
			
			| 
				87
			 | 
			
				116
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				+// dirExists is a snippet checking if a directory exists on the disk. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				+// Returns with a boolean set to true if the directory exists, false if not. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				119
			 | 
			
			
				+// Returns with an error if there was an issue checking the directory's 
			 | 
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				+// existence. 
			 | 
		
	
		
			
			| 
				88
			 | 
			
				121
			 | 
			
			
				 func dirExists(path string) (bool, error) { 
			 | 
		
	
		
			
			| 
				89
			 | 
			
				122
			 | 
			
			
				 	_, err := os.Stat(path) 
			 | 
		
	
		
			
			| 
				90
			 | 
			
				123
			 | 
			
			
				  
			 | 
		
	
	
		
			
			| 
				
			 | 
			
			
				@@ -95,6 +128,12 @@ func dirExists(path string) (bool, error) { 
			 | 
		
	
		
			
			| 
				95
			 | 
			
				128
			 | 
			
			
				 	return true, err 
			 | 
		
	
		
			
			| 
				96
			 | 
			
				129
			 | 
			
			
				 } 
			 | 
		
	
		
			
			| 
				97
			 | 
			
				130
			 | 
			
			
				  
			 | 
		
	
		
			
			| 
				
			 | 
			
				131
			 | 
			
			
				+// Push uses a given repository and configuration to push the local history of 
			 | 
		
	
		
			
			| 
				
			 | 
			
				132
			 | 
			
			
				+// the said repository to the remote, using an authentication structure instance 
			 | 
		
	
		
			
			| 
				
			 | 
			
				133
			 | 
			
			
				+// created from the configuration to authenticate on the remote. 
			 | 
		
	
		
			
			| 
				
			 | 
			
				134
			 | 
			
			
				+// Returns with an error if there was an issue creating the authentication 
			 | 
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				+// structure instance or pushing to the remote. In the latter case, if the error 
			 | 
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				+// is "already up to date" or "non-fast-forward update", doesn't return any error. 
			 | 
		
	
		
			
			| 
				98
			 | 
			
				137
			 | 
			
			
				 func Push(r *gogit.Repository, cfg config.GitSettings) error { 
			 | 
		
	
		
			
			| 
				99
			 | 
			
				138
			 | 
			
			
				 	auth, err := getAuth(cfg.User, cfg.PrivateKeyPath) 
			 | 
		
	
		
			
			| 
				100
			 | 
			
				139
			 | 
			
			
				 	if err != nil { 
			 |