Skip to content

Commit

Permalink
fix(gen-mig-doc): fix repo url (#4147)
Browse files Browse the repository at this point in the history
* fix repo url

* remove unused tests

---------

Co-authored-by: Pantani <Pantani>
  • Loading branch information
Pantani authored May 16, 2024
1 parent 239d92f commit fb5b081
Show file tree
Hide file tree
Showing 4 changed files with 384 additions and 16 deletions.
12 changes: 9 additions & 3 deletions ignite/internal/tools/gen-mig-diffs/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/ignite/cli/ignite/internal/tools/gen-mig-diffs/pkg/diff"
"github.com/ignite/cli/ignite/internal/tools/gen-mig-diffs/pkg/repo"
"github.com/ignite/cli/ignite/internal/tools/gen-mig-diffs/pkg/scaffold"
"github.com/ignite/cli/ignite/internal/tools/gen-mig-diffs/pkg/url"
"github.com/ignite/cli/ignite/internal/tools/gen-mig-diffs/templates/doc"
)

Expand Down Expand Up @@ -45,7 +46,7 @@ func NewRootCmd() *cobra.Command {
to, _ = cmd.Flags().GetString(flagTo)
repoSource, _ = cmd.Flags().GetString(flagSource)
output, _ = cmd.Flags().GetString(flagOutput)
repoURL, _ = cmd.Flags().GetString(flagRepoURL)
repoURLStr, _ = cmd.Flags().GetString(flagRepoURL)
repoOutput, _ = cmd.Flags().GetString(flagRepoOutput)
scaffoldOutput, _ = cmd.Flags().GetString(flagScaffoldOutput)
scaffoldCache, _ = cmd.Flags().GetString(flagScaffoldCache)
Expand All @@ -64,7 +65,11 @@ func NewRootCmd() *cobra.Command {
if repoSource != "" {
repoOptions = append(repoOptions, repo.WithSource(repoSource))
}
if repoURL != "" {
if repoURLStr != "" {
repoURL, err := url.New(repoURLStr)
if err != nil {
return err
}
repoOptions = append(repoOptions, repo.WithRepoURL(repoURL))
}
if repoOutput != "" {
Expand Down Expand Up @@ -170,11 +175,12 @@ func NewRootCmd() *cobra.Command {
},
}

defaultRepoURL := repo.DefaultRepoURL.String()
cmd.Flags().StringP(flagFrom, "f", "", "Version of Ignite or path to Ignite source code to generate the diff from")
cmd.Flags().StringP(flagTo, "t", "", "Version of Ignite or path to Ignite source code to generate the diff to")
cmd.Flags().StringP(flagOutput, "o", defaultDocPath, "Output directory to save the migration document")
cmd.Flags().StringP(flagSource, "s", "", "Path to Ignite source code repository. Set the source automatically set the cleanup to false")
cmd.Flags().String(flagRepoURL, repo.DefaultRepoURL, "Git URL for the Ignite repository")
cmd.Flags().String(flagRepoURL, defaultRepoURL, "Git URL for the Ignite repository")
cmd.Flags().String(flagRepoOutput, "", "Output path to clone the Ignite repository")
cmd.Flags().String(flagScaffoldOutput, "", "Output path to clone the Ignite repository")
cmd.Flags().String(flagScaffoldCache, "", "Path to cache directory")
Expand Down
35 changes: 22 additions & 13 deletions ignite/internal/tools/gen-mig-diffs/pkg/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"os"
"path/filepath"
"sort"
"strings"
"time"

"github.com/Masterminds/semver/v3"
Expand All @@ -18,13 +17,20 @@ import (
"github.com/ignite/cli/v29/ignite/pkg/cmdrunner/exec"
"github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step"
"github.com/ignite/cli/v29/ignite/pkg/errors"

"github.com/ignite/cli/ignite/internal/tools/gen-mig-diffs/pkg/url"
)

const (
DefaultRepoURL = "https://github.com/ignite/cli.git"
defaultBinaryPath = "dist/ignite"
)

var DefaultRepoURL = url.URL{
Protocol: "ssh",
Host: "github.com",
Path: "ignite/cli",
}

type (
// Generator is used to generate migration diffs.
Generator struct {
Expand All @@ -40,7 +46,7 @@ type (
options struct {
source string
output string
repoURL string
repoURL url.URL
binPath string
}
// Options configures the generator.
Expand Down Expand Up @@ -76,7 +82,7 @@ func WithSource(source string) Options {
}

// WithRepoURL set the repo URL Options.
func WithRepoURL(repoURL string) Options {
func WithRepoURL(repoURL url.URL) Options {
return func(o *options) {
o.repoURL = repoURL
}
Expand All @@ -101,9 +107,6 @@ func (o options) validate() error {
if o.source != "" && (o.repoURL != DefaultRepoURL) {
return errors.New("cannot set source and repo URL at the same time")
}
if o.source != "" {
return errors.New("cannot set source and cleanup the repo")
}
return nil
}

Expand Down Expand Up @@ -138,7 +141,7 @@ func New(from, to *semver.Version, session *cliui.Session, options ...Options) (
session.StartSpinner("Cloning ignite repository...")

source = opts.output
repo, err = git.PlainClone(source, false, &git.CloneOptions{URL: opts.repoURL, Depth: 1})
repo, err = git.PlainClone(source, false, &git.CloneOptions{URL: opts.repoURL.String(), Depth: 1})
if errors.Is(err, git.ErrRepositoryAlreadyExists) {
repo, err = verifyRepoSource(source, opts.repoURL)
}
Expand Down Expand Up @@ -408,7 +411,7 @@ func copyFile(srcPath, dstPath string) error {

// verifyRepoSource checks if the repose source path is the same from the provider URL
// and returns the *git.Repository object.
func verifyRepoSource(source, url string) (*git.Repository, error) {
func verifyRepoSource(source string, repoURL url.URL) (*git.Repository, error) {
repo, err := git.PlainOpen(source)
if err != nil {
return nil, errors.Wrap(err, "failed to open ignite repository")
Expand All @@ -417,10 +420,16 @@ func verifyRepoSource(source, url string) (*git.Repository, error) {
if err != nil {
return nil, errors.Wrap(err, "failed to open ignite repository")
}
for _, remoteURL := range remote.Config().URLs {
if strings.TrimSuffix(url, ".git") == strings.TrimSuffix(remoteURL, ".git") {
return repo, nil

for _, u := range remote.Config().URLs {
remoteURL, err := url.New(u)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse repo url %s", u)
}

if err := repoURL.Compare(remoteURL); err != nil {
return nil, errors.Wrapf(err, "repository folder %s does not match the repo URL %s", repoURL, remoteURL)
}
}
return nil, errors.Wrap(err, "repository folder does not match the repo URL")
return repo, nil
}
123 changes: 123 additions & 0 deletions ignite/internal/tools/gen-mig-diffs/pkg/url/url.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package url

import (
"fmt"
"net/url"
"regexp"
"strings"

"github.com/ignite/cli/v29/ignite/pkg/errors"
)

// URL represents a Git URL in any supported protocol.
type URL struct {
// Protocol is the protocol of the endpoint (e.g. ssh, https).
Protocol string
// Host is the host.
Host string
// Path is the repository path.
Path string
}

var (
isSchemeRegExp = regexp.MustCompile(`^[^:]+://`)
scpLikeUrlRegExp = regexp.MustCompile(`^(?:(?P<user>[^@]+)@)?(?P<host>[^:\s]+):(?:(?P<port>[0-9]{1,5}):)?(?P<path>[^\\].*)$`)
)

// New creates a new URL object.
func New(endpoint string) (URL, error) {
if e, ok := parseSCPLike(endpoint); ok {
return e, nil
}
return parseURL(endpoint)
}

func (u URL) Compare(cp URL) error {
switch {
case u.Host != cp.Host:
return errors.Errorf("host mismatch for %s != %s", u.Host, cp.Host)
case u.Path != cp.Path:
return errors.Errorf("path mismatch for %s != %s", u.Path, cp.Path)
default:
return nil
}
}

func (u URL) String() string {
if u.Protocol == "ssh" {
return fmt.Sprintf("git@%s:%s.git", u.Host, u.Path)
}
return fmt.Sprintf("%s://%s/%s.git", u.Protocol, u.Host, u.Path)
}

// parseURL returns an URL object from SCP git URL.
func parseSCPLike(endpoint string) (URL, bool) {
if matchesScheme(endpoint) || !matchesScpLike(endpoint) {
return URL{}, false
}

_, host, _, path := findScpLikeComponents(endpoint)

return URL{
Protocol: "ssh",
Host: host,
Path: strings.TrimSuffix(path, ".git"),
}, true
}

// parseURL returns an URL object from an endpoint.
func parseURL(endpoint string) (URL, error) {
if !matchesScheme(endpoint) || matchesScpLike(endpoint) {
return URL{}, errors.Errorf("invalid endpoint scheme: %s", endpoint)
}

u, err := url.Parse(endpoint)
if err != nil {
return URL{}, err
}

if !u.IsAbs() {
return URL{}, errors.Errorf("invalid endpoint URL: %s", endpoint)
}

return URL{
Protocol: u.Scheme,
Host: u.Hostname(),
Path: getPath(u),
}, nil
}

// matchesScheme returns true if the given string matches a URL-like format scheme.
func matchesScheme(url string) bool {
return isSchemeRegExp.MatchString(url)
}

// matchesScpLike returns true if the given string matches an SCP-like format scheme.
func matchesScpLike(url string) bool {
return scpLikeUrlRegExp.MatchString(url)
}

// findScpLikeComponents returns the user, host, port and path of the given SCP-like URL.
func findScpLikeComponents(url string) (user, host, port, path string) {
m := scpLikeUrlRegExp.FindStringSubmatch(url)
user = m[1]
host = m[2]
port = m[3]
path = m[4]
return m[1], m[2], m[3], m[4]
}

// getPath returns the path from an *url.URL.
func getPath(u *url.URL) string {
res := u.Path
if u.RawQuery != "" {
res += "?" + u.RawQuery
}
if u.Fragment != "" {
res += "#" + u.Fragment
}

res = strings.Trim(res, "/")
res = strings.TrimSuffix(res, ".git")
return strings.Split(res, ":")[0]
}
Loading

0 comments on commit fb5b081

Please sign in to comment.