Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support using local directory as template #162

Merged
merged 8 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions cmd/commands/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,17 +71,10 @@ var NewCmd = &cobra.Command{
})

// Clone repo
tmpDir, err := options.NewOpts.CloneRepo()
tmpDir, err := options.NewOpts.GetSource()
if err != nil {
return errors.NewWakuErrorf("could not clone git repo: %s", err)
return errors.ToWakuError(err)
}
cleanup.Schedule(func() error {
log.Debugf("removing tmp dir: %s\n", tmpDir)
if err := os.RemoveAll(tmpDir); err != nil {
return errors.NewWakuErrorf("failed to cleanup tmp dir: %v", err)
}
return nil
})

// Resolve dir
rootDir := tmpDir
Expand Down Expand Up @@ -248,12 +241,18 @@ func init() {

func AddNewCmdFlags(cmd *cobra.Command) {
cmd.Flags().VarP(&options.NewOpts.Repo, "repo", "r", "source repository to template from")
cmd.Flags().VarP(&options.NewOpts.Source, "source", "s", "source repository to template from")
cmd.Flags().VarP(&options.NewOpts.Branch, "branch", "b", "branch to clone from")
cmd.Flags().VarP(&options.NewOpts.Directory, "directory", "D", "directory where config is located")
cmd.Flags().VarP(&options.NewOpts.Name, "name", "n", "name of the project")
cmd.Flags().VarP(&options.NewOpts.License, "license", "l", "license to use for the project")
cmd.Flags().VarP(&options.NewOpts.Style, "style", "S", "which style to use")
cmd.Flags().BoolVarP(&options.NewOpts.NoGit, "no-git", "G", options.NewOpts.NoGit, "whether to not initialize git")

if err := cmd.Flags().MarkDeprecated("repo", "Please use --source instead."); err != nil {
panic(err)
}
cmd.MarkFlagsMutuallyExclusive("source", "repo")
}

func WriteFiles(tmpRoot, projectRoot string, paths []string, licenseText string, tmpl map[string]any, licenseTmpl map[string]string) error {
Expand Down
47 changes: 44 additions & 3 deletions cmd/options/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"errors"
"os"

"github.com/caffeine-addictt/waku/cmd/cleanup"
e "github.com/caffeine-addictt/waku/internal/errors"
"github.com/caffeine-addictt/waku/internal/git"
"github.com/caffeine-addictt/waku/internal/log"
"github.com/caffeine-addictt/waku/internal/types"
Expand All @@ -16,6 +18,7 @@ const defaultRepo = "https://github.com/caffeine-addictt/waku.git"
// The options for the new command
var NewOpts = NewOptions{
Repo: *types.NewValueGuard("", cmdOpt, types.REPO),
Source: *types.NewValueGuard("", cmdOpt, types.REPO),
Branch: *types.NewValueGuard("", cmdOpt, types.BRANCH),
Directory: *types.NewValueGuard("", cmdOpt, types.PATH),
Name: *types.NewValueGuard("", cmdOpt, types.STRING),
Expand All @@ -29,6 +32,10 @@ type NewOptions struct {
// Should be this repository by default
Repo types.ValueGuard[string]

// The repository Url or local path to use
// Should be this repository by default
Source types.ValueGuard[string]

// The branch to use
Branch types.ValueGuard[string]

Expand All @@ -54,9 +61,14 @@ func cmdOpt(v string) (string, error) {

// TO be invoked before a command is ran
func (o *NewOptions) Validate() error {
switch o.Repo.Value() {
// Since both flags are mutually exclusive
if err := o.Source.Set(o.Source.Value() + o.Repo.Value()); err != nil {
return err
}

switch o.Source.Value() {
case "":
if err := o.Repo.Set(defaultRepo); err != nil {
if err := o.Source.Set(defaultRepo); err != nil {
return err
}
if err := o.Directory.Set("template"); err != nil {
Expand All @@ -83,6 +95,35 @@ func (o *NewOptions) Validate() error {
return nil
}

// GetSource returns the source directory path
// that is either cloned with Git or is local.
//
// If it is a Git cloned path, it will be cleaned
func (o *NewOptions) GetSource() (string, error) {
switch git.CheckUrl(o.Source.Value()) {
case git.GitUrlType:
s, err := o.CloneRepo()
if err != nil {
return s, e.NewWakuErrorf("could not clone repo: %v", err)
}

cleanup.Schedule(func() error {
log.Debugf("removing tmp dir: %s\n", s)
if err := os.RemoveAll(s); err != nil {
return e.NewWakuErrorf("failed to cleanup tmp dir: %v", err)
}
return nil
})

return s, err

case git.PathUrlType:
return o.Source.Value(), nil
}

return "", e.NewWakuErrorf("invalid source URL or path: %s", o.Source.Value())
}

// To clone the repository
func (o *NewOptions) CloneRepo() (string, error) {
log.Debugln("creating tmp dir")
Expand All @@ -97,7 +138,7 @@ func (o *NewOptions) CloneRepo() (string, error) {
opts := git.CloneOptions{
Depth: 1,
Branch: o.Branch.Value(),
Url: utils.EscapeTermString(o.Repo.Value()),
Url: utils.EscapeTermString(o.Source.Value()),
ClonePath: utils.EscapeTermString(tmpDirPath),
}

Expand Down
65 changes: 65 additions & 0 deletions internal/git/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package git

import (
"net/url"
"os"

"github.com/caffeine-addictt/waku/internal/log"
)

type UrlType string

const (
GitUrlType UrlType = "git"
PathUrlType UrlType = "path"
BadUrlType UrlType = "bad"
)

var validSchemas [4]string = [4]string{"http", "https", "git", "ssh"}

// CheckUrl checks if a given string s is
// a valid git or path url
func CheckUrl(s string) UrlType {
if IsGitUrl(s) {
return GitUrlType
}

if IsPathUrl(s) {
return PathUrlType
}

return BadUrlType
}

// IsPathUrl checks if a given string s is
// a valid fs path
func IsPathUrl(s string) bool {
log.Debugf("checking if %s is a valid path\n", s)
_, err := os.Stat(s)
v := !os.IsNotExist(err)

if !v {
log.Debugf("%s is not a valid path", s)
}

return v
}

// IsGitUrl checks if a given string s is
// a valid Git url
func IsGitUrl(s string) bool {
log.Debugf("checking if %s is a valid git url\n", s)
parsedUrl, err := url.Parse(s)
if err != nil {
log.Debugf("%s is not a valid url\n", s)
return false
}

for _, schema := range validSchemas {
if parsedUrl.Scheme == schema {
return true
}
}

return false
}
14 changes: 13 additions & 1 deletion internal/license/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/caffeine-addictt/waku/cmd/options"
"github.com/caffeine-addictt/waku/internal/log"
"github.com/caffeine-addictt/waku/pkg/version"
"github.com/goccy/go-json"
)

Expand All @@ -19,14 +20,25 @@ const (
// need to hit the endpoint once per session.
var Licenses *[]License

func GetLicenseFetchUrl() string {
var url string
if options.NewOpts.Branch.Value() != "" {
url = fmt.Sprintf(BASE_URL, options.NewOpts.Branch.Value())
} else {
url = fmt.Sprintf(BASE_URL, "v"+version.Version)
}
url += LICENSE_LIST
return url
}

// GetLicenses returns the list of licenses from the GitHub API
// or returns the cached list if it exists.
func GetLicenses() (*[]License, error) {
if Licenses != nil {
return Licenses, nil
}

url := fmt.Sprintf(BASE_URL, options.NewOpts.Branch.Value()) + LICENSE_LIST
url := GetLicenseFetchUrl()
log.Infof("Fetching licenses from %s...\n", url)
req, err := http.NewRequest(http.MethodGet, url, http.NoBody)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/license/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type License struct {
}

func (license *License) GetLicenseText() (string, error) {
req, err := http.NewRequest(http.MethodGet, BASE_URL+license.Filename, http.NoBody)
req, err := http.NewRequest(http.MethodGet, GetLicenseFetchUrl()+license.Filename, http.NoBody)
if err != nil {
return "", err
}
Expand Down
11 changes: 6 additions & 5 deletions internal/types/cli.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package types

// The <typeStirng> for CLI options
// The <typeString> for CLI options
const (
PATH string = "<path>"
REPO string = "<repo>"
BRANCH string = "<branch>"
STRING string = "<string>"
PATH string = "<path>"
REPO string = "<repo>"
BRANCH string = "<branch>"
STRING string = "<string>"
REPO_OR_PATH = "<repo|path>"
)
2 changes: 1 addition & 1 deletion pkg/version/version.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package version

// The current app version
const Version = "0.6.0"
const Version = "0.7.0"
2 changes: 1 addition & 1 deletion www/docs/blog/posts/2024-10-08-waku-v0.6.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Waku has a Discord server. [Join us!](https://discord.gg/NcRFkVTcaw)
## Download

You can [install](../../install.md) or upgrade Waku with your favorite package manager,
or see the full release notes [here](https://github.com/caffeine-addictt/waku/releases/tag/v0.6.0).
or see the full release notes [here](https://github.com/caffeine-addictt/waku/releases/tag/v0.7.0).

## Helping out

Expand Down
4 changes: 2 additions & 2 deletions www/docs/configuration/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ for better editor support.
https://waku.ngjx.org/static/schema.json
```

Or you can pin a specific version like `v0.6.0`:
Or you can pin a specific version like `v0.7.0`:

```text
https://raw.githubusercontent.com/caffeine-addictt/waku/v0.6.0/www/docs/static/schema.json
https://raw.githubusercontent.com/caffeine-addictt/waku/v0.7.0/www/docs/static/schema.json
```

Simply add the `$schema` property to your `configuration` file:
Expand Down
13 changes: 13 additions & 0 deletions www/docs/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

This page lists all deprecation notices in Waku.

Active deprecations will be removed in the next major version,
please update your code accordingly.

## Active notices

### waku new `--repo` flag

> since v0.7

This flag was deprecated in favor of the `--source` flag which works
like `--repo` but it also accepts local directory paths. Switching
to `--source` is __NOT BREAKING__.

## Removed in v0

Nothing so far. :partying_face:
10 changes: 5 additions & 5 deletions www/docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,17 @@ All artifacts are checksummed, and the checksum file is signed with [cosign][].
and `checksums.txt.sig` files from the [releases][] page.

```sh
curl -O 'https://github.com/caffeine-addictt/waku/releases/download/v0.6.0/checksums.txt'
curl -O 'https://github.com/caffeine-addictt/waku/releases/download/v0.7.0/checksums.txt'
```

1. Verify checksums signature:

```bash
cosign verify-blob \
--certificate-identity 'https://github.com/caffeine-addictt/waku/.github/workflows/release.yml@refs/tags/v0.6.0' \
--certificate-identity 'https://github.com/caffeine-addictt/waku/.github/workflows/release.yml@refs/tags/v0.7.0' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
--cert 'https://github.com/caffeine-addictt/waku/releases/download/v0.6.0/checksums.txt.pem' \
--signature 'https://github.com/caffeine-addictt/waku/releases/download/v0.6.0/checksums.txt.sig' \
--cert 'https://github.com/caffeine-addictt/waku/releases/download/v0.7.0/checksums.txt.pem' \
--signature 'https://github.com/caffeine-addictt/waku/releases/download/v0.7.0/checksums.txt.sig' \
./checksums.txt
```

Expand All @@ -130,7 +130,7 @@ Verify the signature:

```sh
cosign verify \
--certificate-identity 'https://github.com/caffeine-addictt/waku/.github/workflows/release.yml@refs/tags/v0.6.0' \
--certificate-identity 'https://github.com/caffeine-addictt/waku/.github/workflows/release.yml@refs/tags/v0.7.0' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
caffeinec/waku
```
Expand Down
Loading