github.com/taubyte/tau-cli@v0.1.13-0.20240326000942-487f0d57edfc/cli/commands/resources/project/helpers.go (about)

     1  package project
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"io"
     7  	"sync"
     8  
     9  	"github.com/google/go-github/v53/github"
    10  	"github.com/pterm/pterm"
    11  	git "github.com/taubyte/go-simple-git"
    12  	projectFlags "github.com/taubyte/tau-cli/flags/project"
    13  	"github.com/taubyte/tau-cli/i18n"
    14  	projectI18n "github.com/taubyte/tau-cli/i18n/project"
    15  	repositoryI18n "github.com/taubyte/tau-cli/i18n/repository"
    16  	projectLib "github.com/taubyte/tau-cli/lib/project"
    17  	"github.com/taubyte/tau-cli/singletons/config"
    18  	"github.com/urfave/cli/v2"
    19  	"golang.org/x/oauth2"
    20  )
    21  
    22  // See if they have cloned the project, if not show help
    23  func checkProjectClonedHelp(name string) {
    24  	project, err := config.Projects().Get(name)
    25  	if err != nil || len(project.Location) == 0 {
    26  		i18n.Help().BeSureToCloneProject()
    27  	}
    28  }
    29  
    30  type dualRepoHandler struct {
    31  	ctx         *cli.Context
    32  	projectName string
    33  	repository  projectLib.ProjectRepository
    34  	action      func(*git.Repository) error
    35  	errorFormat func(string) error
    36  }
    37  
    38  // Run will parse for config-only || code-only
    39  // then Runs a go routine to commit the action on both
    40  // config and code repositories asynchronously or run config/code only
    41  func (h *dualRepoHandler) Run() error {
    42  	config, code, err := projectFlags.ParseConfigCodeFlags(h.ctx)
    43  	if err != nil {
    44  		return err
    45  	}
    46  
    47  	var (
    48  		configErr error
    49  		codeErr   error
    50  	)
    51  
    52  	var wg sync.WaitGroup
    53  
    54  	if config {
    55  		wg.Add(1)
    56  		go func() {
    57  			defer wg.Done()
    58  
    59  			var configRepo *git.Repository
    60  
    61  			configRepo, configErr = h.repository.Config()
    62  			if configErr != nil {
    63  				return
    64  			}
    65  
    66  			configErr = h.action(configRepo)
    67  			if configErr != nil {
    68  				pterm.Error.Printfln(projectI18n.ConfigRepo, configErr)
    69  			}
    70  		}()
    71  	}
    72  
    73  	if code {
    74  		wg.Add(1)
    75  		go func() {
    76  			defer wg.Done()
    77  
    78  			var codeRepo *git.Repository
    79  
    80  			codeRepo, codeErr = h.repository.Code()
    81  			if codeErr != nil {
    82  				return
    83  			}
    84  
    85  			codeErr = h.action(codeRepo)
    86  			if codeErr != nil {
    87  				pterm.Error.Printfln(projectI18n.CodeRepo, codeErr)
    88  			}
    89  		}()
    90  	}
    91  
    92  	wg.Wait()
    93  	if configErr != nil || codeErr != nil {
    94  		return h.errorFormat(h.projectName)
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func newGithubClient(ctx context.Context, token string) *github.Client {
   101  	ts := oauth2.StaticTokenSource(
   102  		&oauth2.Token{AccessToken: token},
   103  	)
   104  
   105  	tc := oauth2.NewClient(ctx, ts)
   106  	return github.NewClient(tc)
   107  }
   108  
   109  // Var to allow override in tests
   110  var ListRepos = func(ctx context.Context, token, user string) ([]*github.Repository, error) {
   111  	client := newGithubClient(ctx, token)
   112  	repos, _, err := client.Repositories.List(ctx, "", &github.RepositoryListOptions{
   113  		Visibility:  "all",
   114  		Affiliation: "owner,collaborator,organization_member",
   115  	})
   116  	if err != nil {
   117  		return nil, repositoryI18n.ErrorListRepositories(user, err)
   118  	}
   119  
   120  	return repos, nil
   121  }
   122  
   123  func removeFromGithub(ctx context.Context, token, user, name string) error {
   124  	client := newGithubClient(ctx, token)
   125  	if res, err := client.Repositories.Delete(ctx, user, name); err != nil {
   126  		var deleteRes deleteRes
   127  		data, err := io.ReadAll(res.Body)
   128  		if err == nil {
   129  			if err = json.Unmarshal(data, &deleteRes); err == nil && deleteRes.Message == adminRights {
   130  				pterm.Error.Println(adminRights[:len(adminRights)-1] + " to delete")
   131  				pterm.Info.Println(
   132  					"Add token with delete permissions\n" +
   133  						pterm.FgGreen.Sprint("$ tau login --new -n {profile-name} -p github -d -t {token}"))
   134  				return repositoryI18n.ErrorAdminRights
   135  			}
   136  
   137  		}
   138  		return repositoryI18n.ErrorDeleteRepository(name, err)
   139  	}
   140  
   141  	return nil
   142  }
   143  
   144  type deleteRes struct {
   145  	Message string `json:"message"`
   146  }
   147  
   148  var adminRights = "Must have admin rights to Repository."