forked from go-llvm/llgo
/
utils.go
100 lines (90 loc) · 2.28 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// Copyright 2013 The llgo Authors.
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"fmt"
"go/build"
"io"
"log"
"os"
"path/filepath"
"strings"
)
// goFilesPackage creates a package for building a collection of Go files.
//
// This function is based on the function of the same name in cmd/go.
func goFilesPackage(gofiles []string) (*build.Package, error) {
for _, f := range gofiles {
if !strings.HasSuffix(f, ".go") {
return nil, fmt.Errorf("named files must be .go files")
}
}
buildctx := *buildctx
buildctx.UseAllFiles = true
// Synthesize fake "directory" that only shows the named files,
// to make it look like this is a standard package or
// command directory. So that local imports resolve
// consistently, the files must all be in the same directory.
var dirent []os.FileInfo
var dir string
for _, file := range gofiles {
fi, err := os.Stat(file)
if err != nil {
return nil, err
}
if fi.IsDir() {
return nil, fmt.Errorf("%s is a directory, should be a Go file", file)
}
dir1, _ := filepath.Split(file)
if dir == "" {
dir = dir1
} else if dir != dir1 {
fmt.Errorf("named files must all be in one directory; have %s and %s", dir, dir1)
}
dirent = append(dirent, fi)
}
buildctx.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
if !filepath.IsAbs(dir) {
cwd, err := os.Getwd()
if err != nil {
return nil, err
}
dir = filepath.Join(cwd, dir)
}
return buildctx.ImportDir(dir, 0)
}
func moveFile(src, dst string) error {
if printcommands {
log.Printf("mv %s %s\n", src, dst)
}
if os.Rename(src, dst) != nil {
// rename may fail if the paths are on
// different filesystems.
fin, err := os.Open(src)
if err != nil {
return err
}
defer fin.Close()
fout, err := os.Create(dst)
if err != nil {
return err
}
defer fout.Close()
info, err := fin.Stat()
if err != nil {
return err
}
if err = fout.Chmod(info.Mode()); err != nil {
return err
}
if _, err = io.Copy(fout, fin); err != nil {
return err
}
return os.Remove(src)
}
return nil
}