Feat: Remove Requirement for Dotfile (#84)
This MR removes the requirement for a dotfile (the dotfile is now optional and will override the configuration provided via environment variables). The requirement for providing a project ID is also eliminated, by parsing the namespace and project name from the SSH or HTTPS remote, and then using that to query Gitlab for a matching project.
This commit is contained in:
committed by
GitHub
parent
38df51bfbc
commit
80b597e56a
164
cmd/client.go
164
cmd/client.go
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"os"
|
||||
@@ -18,7 +19,6 @@ type Client struct {
|
||||
mergeId int
|
||||
gitlabInstance string
|
||||
authToken string
|
||||
logPath string
|
||||
git *gitlab.Client
|
||||
}
|
||||
|
||||
@@ -27,85 +27,32 @@ type DebugSettings struct {
|
||||
GoResponse bool `json:"go_response"`
|
||||
}
|
||||
|
||||
var requestLogger retryablehttp.RequestLogHook = func(l retryablehttp.Logger, r *http.Request, i int) {
|
||||
logPath := os.Args[len(os.Args)-1]
|
||||
/* This will parse and validate the project settings and then initialize the Gitlab client */
|
||||
func (c *Client) initGitlabClient() error {
|
||||
|
||||
file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
token := r.Header.Get("Private-Token")
|
||||
r.Header.Set("Private-Token", "REDACTED")
|
||||
res, err := httputil.DumpRequest(r, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r.Header.Set("Private-Token", token)
|
||||
|
||||
_, err = file.Write([]byte("\n-- REQUEST --\n")) //nolint:all
|
||||
_, err = file.Write(res) //nolint:all
|
||||
_, err = file.Write([]byte("\n")) //nolint:all
|
||||
}
|
||||
|
||||
var responseLogger retryablehttp.ResponseLogHook = func(l retryablehttp.Logger, response *http.Response) {
|
||||
logPath := os.Args[len(os.Args)-1]
|
||||
|
||||
file, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
res, err := httputil.DumpResponse(response, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if len(os.Args) < 6 {
|
||||
return errors.New("Must provide gitlab url, port, auth token, debug settings, and log path")
|
||||
}
|
||||
|
||||
_, err = file.Write([]byte("\n-- RESPONSE --\n")) //nolint:all
|
||||
_, err = file.Write(res) //nolint:all
|
||||
_, err = file.Write([]byte("\n")) //nolint:all
|
||||
}
|
||||
|
||||
/* This will initialize the client with the token and check for the basic project ID and command arguments */
|
||||
func (c *Client) init(branchName string) error {
|
||||
|
||||
if len(os.Args) < 5 {
|
||||
return errors.New("Must provide project ID, gitlab instance, port, and auth token!")
|
||||
gitlabInstance := os.Args[1]
|
||||
if gitlabInstance == "" {
|
||||
return errors.New("GitLab instance URL cannot be empty")
|
||||
}
|
||||
|
||||
projectId := os.Args[1]
|
||||
gitlabInstance := os.Args[2]
|
||||
authToken := os.Args[4]
|
||||
debugSettings := os.Args[5]
|
||||
authToken := os.Args[3]
|
||||
if authToken == "" {
|
||||
return errors.New("Auth token cannot be empty")
|
||||
}
|
||||
|
||||
/* Parse debug settings and initialize logger handlers */
|
||||
debugSettings := os.Args[4]
|
||||
var debugObject DebugSettings
|
||||
err := json.Unmarshal([]byte(debugSettings), &debugObject)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Could not parse debug settings: %w, %s", err, debugSettings)
|
||||
}
|
||||
|
||||
logPath := os.Args[len(os.Args)-1]
|
||||
|
||||
if projectId == "" {
|
||||
return errors.New("Project ID cannot be empty")
|
||||
}
|
||||
|
||||
if gitlabInstance == "" {
|
||||
return errors.New("GitLab instance URL cannot be empty")
|
||||
}
|
||||
|
||||
if authToken == "" {
|
||||
return errors.New("Auth token cannot be empty")
|
||||
}
|
||||
|
||||
c.gitlabInstance = gitlabInstance
|
||||
c.projectId = projectId
|
||||
c.authToken = authToken
|
||||
c.logPath = logPath
|
||||
|
||||
var apiCustUrl = fmt.Sprintf(c.gitlabInstance + "/api/v4")
|
||||
var apiCustUrl = fmt.Sprintf(gitlabInstance + "/api/v4")
|
||||
|
||||
gitlabOptions := []gitlab.ClientOptionFunc{
|
||||
gitlab.WithBaseURL(apiCustUrl),
|
||||
@@ -125,13 +72,40 @@ func (c *Client) init(branchName string) error {
|
||||
return fmt.Errorf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
c.gitlabInstance = gitlabInstance
|
||||
c.authToken = authToken
|
||||
c.git = git
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/* This will fetch the project ID and merge request ID using the client */
|
||||
func (c *Client) initProjectSettings(remoteUrl string, namespace string, projectName string, branchName string) error {
|
||||
|
||||
idStr := namespace + "/" + projectName
|
||||
opt := gitlab.GetProjectOptions{}
|
||||
project, _, err := c.git.Projects.GetProject(idStr, &opt)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf(fmt.Sprintf("Error getting project at %s", remoteUrl), err)
|
||||
}
|
||||
if project == nil {
|
||||
return fmt.Errorf(fmt.Sprintf("Could not find project at %s", remoteUrl), err)
|
||||
}
|
||||
|
||||
if project == nil {
|
||||
return fmt.Errorf("No projects you are a member of contained remote URL %s", remoteUrl)
|
||||
}
|
||||
|
||||
c.projectId = fmt.Sprint(project.ID)
|
||||
|
||||
options := gitlab.ListProjectMergeRequestsOptions{
|
||||
Scope: gitlab.String("all"),
|
||||
State: gitlab.String("opened"),
|
||||
SourceBranch: &branchName,
|
||||
}
|
||||
|
||||
mergeRequests, _, err := git.MergeRequests.ListProjectMergeRequests(c.projectId, &options)
|
||||
mergeRequests, _, err := c.git.MergeRequests.ListProjectMergeRequests(c.projectId, &options)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to list merge requests: %w", err)
|
||||
}
|
||||
@@ -147,7 +121,6 @@ func (c *Client) init(branchName string) error {
|
||||
}
|
||||
|
||||
c.mergeId = mergeIdInt
|
||||
c.git = git
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -165,3 +138,54 @@ func (c *Client) handleError(w http.ResponseWriter, err error, message string, s
|
||||
c.handleError(w, err, "Could not encode response", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
var requestLogger retryablehttp.RequestLogHook = func(l retryablehttp.Logger, r *http.Request, i int) {
|
||||
file := openLogFile()
|
||||
defer file.Close()
|
||||
|
||||
token := r.Header.Get("Private-Token")
|
||||
r.Header.Set("Private-Token", "REDACTED")
|
||||
res, err := httputil.DumpRequest(r, true)
|
||||
if err != nil {
|
||||
log.Fatalf("Error dumping request: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
r.Header.Set("Private-Token", token)
|
||||
|
||||
_, err = file.Write([]byte("\n-- REQUEST --\n")) //nolint:all
|
||||
_, err = file.Write(res) //nolint:all
|
||||
_, err = file.Write([]byte("\n")) //nolint:all
|
||||
}
|
||||
|
||||
var responseLogger retryablehttp.ResponseLogHook = func(l retryablehttp.Logger, response *http.Response) {
|
||||
file := openLogFile()
|
||||
defer file.Close()
|
||||
|
||||
res, err := httputil.DumpResponse(response, true)
|
||||
if err != nil {
|
||||
log.Fatalf("Error dumping response: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
_, err = file.Write([]byte("\n-- RESPONSE --\n")) //nolint:all
|
||||
_, err = file.Write(res) //nolint:all
|
||||
_, err = file.Write([]byte("\n")) //nolint:all
|
||||
}
|
||||
|
||||
func openLogFile() *os.File {
|
||||
logFile := os.Args[len(os.Args)-1]
|
||||
file, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
log.Printf("Log file %s does not exist", logFile)
|
||||
} else if os.IsPermission(err) {
|
||||
log.Printf("Permission denied for log file %s", logFile)
|
||||
} else {
|
||||
log.Printf("Error opening log file %s: %v", logFile, err)
|
||||
}
|
||||
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return file
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user