-
Notifications
You must be signed in to change notification settings - Fork 375
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: implement gno mod init
command
#955
Changes from 9 commits
48e6cc8
c806201
d429246
a80d4a2
ac64106
fd9cf8d
1dd6df8
6e94287
1f5bc54
b189d2a
bc12c9f
e093de6
a1c51c1
5c9af0e
58f6ffa
791996d
fa7fc5a
4286d3d
7807a32
b95edba
efc2e5b
c1ef18b
b61b60d
371eaef
fde1acd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
package gnomod | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
|
@@ -163,6 +165,65 @@ func GnoToGoMod(f File) (*File, error) { | |
return &f, nil | ||
} | ||
|
||
func CreateGnoModFile(rootDir, modPath string) error { | ||
if !filepath.IsAbs(rootDir) { | ||
return fmt.Errorf("dir %q is not absolute", rootDir) | ||
} | ||
|
||
modFilePath := filepath.Join(rootDir, "gno.mod") | ||
if _, err := os.Stat(modFilePath); err == nil { | ||
return errors.New("gno.mod file already exists") | ||
} | ||
|
||
if modPath == "" { | ||
// Check .gno files for package name | ||
// and use it as modPath | ||
files, err := ioutil.ReadDir(rootDir) | ||
if err != nil { | ||
fmt.Errorf("read dir %q: %w", rootDir, err) | ||
} | ||
|
||
var pkgName gnolang.Name | ||
for _, file := range files { | ||
if file.IsDir() || !strings.HasSuffix(file.Name(), ".gno") || strings.HasSuffix(file.Name(), "_filetest.gno") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should create helpers for this in another PR. Also discussed with @tbruyelle in another PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay. Will open PR for that soon. |
||
continue | ||
} | ||
|
||
fpath := filepath.Join(rootDir, file.Name()) | ||
bz, err := os.ReadFile(fpath) | ||
if err != nil { | ||
return fmt.Errorf("read file %q: %w", fpath, err) | ||
} | ||
|
||
pn := gnolang.PackageNameFromFileBody(file.Name(), string(bz)) | ||
if strings.HasSuffix(string(pkgName), "_test") { | ||
pkgName = pkgName[:len(pkgName)-len("_test")] | ||
} | ||
if pkgName == "" { | ||
pkgName = pn | ||
} | ||
if pkgName != pn { | ||
return fmt.Errorf("package name mismatch: [%q] and [%q]", pkgName, pn) | ||
} | ||
} | ||
if pkgName == "" { | ||
return errors.New("cannot determine package name") | ||
} | ||
modPath = string(pkgName) | ||
Comment on lines
+209
to
+212
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this situation when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch. Should be fixed by: fa7fc5a |
||
} | ||
|
||
modFile := &File{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not create a helper for this initialization? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah. I agree there is a helper needed for |
||
Module: &modfile.Module{ | ||
Mod: module.Version{ | ||
Path: modPath, | ||
}, | ||
}, | ||
} | ||
modFile.WriteToPath(filepath.Join(rootDir, "gno.mod")) | ||
|
||
return nil | ||
} | ||
|
||
func isReplaced(mod module.Version, repl []*modfile.Replace) (module.Version, bool) { | ||
for _, r := range repl { | ||
hasNoVersion := r.Old.Path == mod.Path && r.Old.Version == "" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package gnomod | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/gnolang/gno/tm2/pkg/testutils" | ||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestCreateGnoModFile(t *testing.T) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you paralellize this test with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done efc2e5b |
||
for _, tc := range []struct { | ||
desc string | ||
in []struct{ filename, content string } | ||
inModPath string | ||
out string | ||
errShouldContain string | ||
}{ | ||
{ | ||
desc: "empty directory", | ||
inModPath: "gno.land/p/demo/foo", | ||
out: "module gno.land/p/demo/foo\n", | ||
}, | ||
{ | ||
desc: "empty directory (without modPath)", | ||
errShouldContain: "cannot determine package name", | ||
}, | ||
{ | ||
desc: "valid package", | ||
in: []struct{ filename, content string }{ | ||
{ | ||
"foo.gno", | ||
`package foo`, | ||
}, | ||
}, | ||
inModPath: "gno.land/p/demo/foo", | ||
out: "module gno.land/p/demo/foo\n", | ||
}, | ||
{ | ||
desc: "valid package (without modPath)", | ||
in: []struct{ filename, content string }{ | ||
{ | ||
"foo.gno", | ||
`package foo`, | ||
}, | ||
}, | ||
out: "module foo\n", | ||
}, | ||
{ | ||
desc: "ambigious package names", | ||
in: []struct{ filename, content string }{ | ||
{ | ||
"foo.gno", | ||
`package foo`, | ||
}, | ||
{ | ||
"bar.gno", | ||
`package bar`, | ||
}, | ||
}, | ||
inModPath: "gno.land/p/demo/foo", | ||
out: "module gno.land/p/demo/foo\n", | ||
}, | ||
{ | ||
desc: "ambigious package names (without modPath)", | ||
in: []struct{ filename, content string }{ | ||
{ | ||
"foo.gno", | ||
`package foo`, | ||
}, | ||
{ | ||
"bar.gno", | ||
`package bar`, | ||
}, | ||
}, | ||
errShouldContain: "package name mismatch:", | ||
}, | ||
{ | ||
desc: "valid package with gno.mod file", | ||
in: []struct{ filename, content string }{ | ||
{ | ||
"foo.gno", | ||
`package foo`, | ||
}, | ||
{ | ||
"gno.mod", | ||
`module gno.land/p/demo/foo`, | ||
}, | ||
}, | ||
inModPath: "gno.land/p/demo/foo", | ||
errShouldContain: "gno.mod file already exists", | ||
}, | ||
{ | ||
desc: "valid package with gno.mod file (without modPath)", | ||
in: []struct{ filename, content string }{ | ||
{ | ||
"foo.gno", | ||
`package foo`, | ||
}, | ||
{ | ||
"gno.mod", | ||
`module gno.land/p/demo/foo`, | ||
}, | ||
}, | ||
errShouldContain: "gno.mod file already exists", | ||
}, | ||
} { | ||
t.Run(tc.desc, func(t *testing.T) { | ||
// Create test dir | ||
dirPath, cleanUpFn := testutils.NewTestCaseDir(t) | ||
require.NotNil(t, dirPath) | ||
defer cleanUpFn() | ||
|
||
// Create files | ||
for _, f := range tc.in { | ||
err := os.WriteFile(filepath.Join(dirPath, f.filename), []byte(f.content), 0o644) | ||
require.NoError(t, err) | ||
} | ||
|
||
err := CreateGnoModFile(dirPath, tc.inModPath) | ||
if tc.errShouldContain != "" { | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), tc.errShouldContain) | ||
return | ||
} | ||
assert.NoError(t, err) | ||
|
||
// Verify gno.mod file | ||
bz, err := os.ReadFile(filepath.Join(dirPath, "gno.mod")) | ||
assert.NoError(t, err) | ||
assert.Equal(t, string(bz), tc.out) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The second param for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: you can use
commands.NewEmptyConfig()
, as with other commands that don't have a config fileThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: 791996d