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

gop/env.Installed(); gop/ast.File.Pos() #1471

Merged
merged 3 commits into from
Oct 18, 2023
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
9 changes: 7 additions & 2 deletions ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ type FileType = int16
// are "free-floating" (see also issues #18593, #20744).
type File struct {
Doc *CommentGroup // associated documentation; or nil
Package token.Pos // position of "package" keyword
Package token.Pos // position of "package" keyword; or NoPos
Name *Ident // package name
Decls []Decl // top-level declarations; or nil

Expand All @@ -1145,7 +1145,12 @@ func (f *File) NoEntrypoint() bool {
}

// Pos returns position of first character belonging to the node.
func (f *File) Pos() token.Pos { return f.Package }
func (f *File) Pos() token.Pos {
if f.Package != token.NoPos {
return f.Package
}
return f.Name.NamePos
}

// End returns position of first character immediately after the node.
func (f *File) End() token.Pos {
Expand Down
1 change: 1 addition & 0 deletions env/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var (
buildDate string
)

// BuildDate returns build date of the `gop` command.
func BuildDate() string {
return buildDate
}
24 changes: 24 additions & 0 deletions env/gop_nonwindows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//go:build !windows
// +build !windows

/*
* Copyright (c) 2021 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package env

func isGopCmd(fname string) bool {
return fname == "gop"
}
2 changes: 2 additions & 0 deletions env/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var (
defaultGopRoot string
)

// GOPROOT returns the root of the Go+ tree. It uses the GOPROOT environment variable,
// if set at process start, or else the root used during the Go+ build.
func GOPROOT() string {
gopRoot, err := findGopRoot()
if err != nil {
Expand Down
20 changes: 10 additions & 10 deletions env/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package env

import (
"io/ioutil"
"os"
"path/filepath"
"testing"
Expand All @@ -39,12 +38,13 @@ func findGoModFile(dir string) (modfile string, noCacheFile bool, err error) {

// Common testing directory structure:
// testing_root/
// src/
// subdir/
// valid_goproot/
// go.mod
// go.sum
// cmd/gop/
//
// src/
// subdir/
// valid_goproot/
// go.mod
// go.sum
// cmd/gop/
func makeTestDir(t *testing.T) (root string, src string, gopRoot string) {
root, _ = filepath.EvalSymlinks(t.TempDir())
src = filepath.Join(root, "src")
Expand All @@ -57,12 +57,12 @@ func makeTestDir(t *testing.T) (root string, src string, gopRoot string) {
func makeValidGopRoot(root string) {
os.Mkdir(root, 0755)
os.MkdirAll(filepath.Join(root, "cmd/gop"), 0755)
ioutil.WriteFile(filepath.Join(root, "go.mod"), []byte(""), 0644)
ioutil.WriteFile(filepath.Join(root, "go.sum"), []byte(""), 0644)
os.WriteFile(filepath.Join(root, "go.mod"), []byte(""), 0644)
os.WriteFile(filepath.Join(root, "go.sum"), []byte(""), 0644)
}

func writeDummyFile(path string) {
ioutil.WriteFile(path, []byte(""), 0644)
os.WriteFile(path, []byte(""), 0644)
}

func cleanup() {
Expand Down
4 changes: 4 additions & 0 deletions env/sys_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ package env
const (
envHOME = "USERPROFILE"
)

func isGopCmd(fname string) bool {
return fname == "gop.exe" || fname == "gop"
}
41 changes: 39 additions & 2 deletions env/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
package env

import (
"bytes"
"os"
"os/exec"
"path/filepath"
"strings"
)

Expand All @@ -31,9 +35,42 @@ var (
)

func init() {
if buildVersion != "" && !strings.HasPrefix(buildVersion, "v"+MainVersion+".") {
panic("Invalid buildVersion: " + buildVersion)
initEnv()
}

func initEnv() {
if buildVersion == "" {
initEnvByGop()
return
}
if !strings.HasPrefix(buildVersion, "v"+MainVersion+".") {
panic("gop/env: [FATAL] Invalid buildVersion: " + buildVersion)
}
}

func initEnvByGop() {
if fname := filepath.Base(os.Args[0]); !isGopCmd(fname) {
if ret, err := gopEnv(); err == nil {
parts := strings.SplitN(strings.TrimRight(ret, "\n"), "\n", 3)
if len(parts) == 3 {
buildVersion, buildDate, defaultGopRoot = parts[0], parts[1], parts[2]
}
}
}
}

var gopEnv = func() (string, error) {
var b bytes.Buffer
cmd := exec.Command("gop", "env", "GOPVERSION", "BUILDDATE", "GOPROOT")
cmd.Stdout = &b
err := cmd.Run()
return b.String(), err
}

// Installed checks is `gop` installed or not.
// If returns false, it means `gop` is not installed or not in PATH.
func Installed() bool {
return buildVersion != ""
}

// Version returns the GoPlus tree's version string.
Expand Down
52 changes: 42 additions & 10 deletions env/version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,53 @@

package env

import "testing"
import (
"os"
"path/filepath"
"testing"
)

func TestVersion(t *testing.T) {
if Version() != "v"+MainVersion+".x" {
t.Fatal("TestVersion failed:", Version())
func TestPanic(t *testing.T) {
t.Run("initEnvPanic", func(t *testing.T) {
defer func() {
if e := recover(); e == nil {
t.Fatal("initEnvPanic: no panic?")
}
}()
buildVersion = "v1.2"
initEnv()
})
t.Run("GOPROOT panic", func(t *testing.T) {
defer func() {
if e := recover(); e == nil {
t.Fatal("GOPROOT: no panic?")
}
}()
defaultGopRoot = ""
os.Setenv(envGOPROOT, "")
GOPROOT()
})
}

func TestEnv(t *testing.T) {
gopEnv = func() (string, error) {
wd, _ := os.Getwd()
root := filepath.Dir(wd)
return "v1.0.0-beta1\n2023-10-18_17-45-50\n" + root + "\n", nil
}
buildVersion = ""
initEnv()
if !Installed() {
t.Fatal("not Installed")
}
buildVersion = "v1.0.0-beta1"
if Version() != buildVersion {
if Version() != "v1.0.0-beta1" {
t.Fatal("TestVersion failed:", Version())
}
buildVersion = ""
}

func TestBuild(t *testing.T) {
if BuildDate() != "" {
if Version() != "v"+MainVersion+".x" {
t.Fatal("TestVersion failed:", Version())
}
if BuildDate() != "2023-10-18_17-45-50" {
t.Fatal("BuildInfo failed:", BuildDate())
}
}
2 changes: 1 addition & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3709,7 +3709,7 @@ func (p *parser) parseFile() *ast.File {
} else {
noPkgDecl = true
pos = token.NoPos
ident = ast.NewIdent("main")
ident = &ast.Ident{NamePos: p.file.Pos(0), Name: "main"}
}

p.openScope()
Expand Down