You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2023/06/02 07:39:10 UTC
[camel-k] branch main updated: chore(deps): revert vfs-gen removal
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push:
new 4a74b39be chore(deps): revert vfs-gen removal
4a74b39be is described below
commit 4a74b39be50c2fabe08e48f36c38574119d632f2
Author: Gaelle Fournier <ga...@gmail.com>
AuthorDate: Thu Jun 1 15:15:32 2023 +0200
chore(deps): revert vfs-gen removal
Ref #4326
---
cmd/manager/main.go | 1 +
cmd/util/vfs-gen/main.go | 259 +++++++++++++++++++++++++++++++++++
cmd/util/vfs-gen/multifs/multidir.go | 171 +++++++++++++++++++++++
go.mod | 2 +
go.sum | 4 +
pkg/resources/resources_support.go | 4 +
6 files changed, 441 insertions(+)
diff --git a/cmd/manager/main.go b/cmd/manager/main.go
new file mode 120000
index 000000000..8413b53c5
--- /dev/null
+++ b/cmd/manager/main.go
@@ -0,0 +1 @@
+../kamel/main.go
\ No newline at end of file
diff --git a/cmd/util/vfs-gen/main.go b/cmd/util/vfs-gen/main.go
new file mode 100644
index 000000000..79d6f8593
--- /dev/null
+++ b/cmd/util/vfs-gen/main.go
@@ -0,0 +1,259 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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 main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "net/http"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/apache/camel-k/v2/pkg/util"
+
+ "github.com/apache/camel-k/v2/cmd/util/vfs-gen/multifs"
+ "github.com/apache/camel-k/v2/pkg/base"
+ "github.com/shurcooL/httpfs/filter"
+ "github.com/shurcooL/vfsgen"
+)
+
+func main() {
+ var rootDir string
+ var destDir string
+
+ wd, err := os.Getwd()
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ flag.StringVar(&rootDir, "root", base.GoModDirectory, "The absolute path from were the directories can be found (camel-k module directory by default)")
+ flag.StringVar(&destDir, "dest", wd, "The destination directory of the generated file (working directory by default)")
+ flag.Parse()
+
+ if len(flag.Args()) < 1 {
+ println("usage: vfs-gen [-root <absolute root parent path>] [-dest <directory>] directory1 [directory2 ... ...]")
+ os.Exit(1)
+ }
+
+ err = checkDir(rootDir)
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ dirNames := flag.Args()
+ for _, dirName := range dirNames {
+ absDir := filepath.Join(rootDir, dirName)
+ err := checkDir(absDir)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ }
+
+ exclusions := calcExclusions(rootDir, dirNames)
+
+ //
+ // Destination file for the generated resources
+ //
+ resourceFile := path.Join(destDir, "resources.go")
+
+ mfs, err := multifs.New(rootDir, dirNames, exclusions)
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ var fs http.FileSystem = modTimeFS{
+ fs: mfs,
+ }
+
+ //
+ // Filter un-interesting files
+ //
+ fs = filter.Skip(fs, filter.FilesWithExtensions(".go"))
+ fs = filter.Skip(fs, func(path string, fi os.FileInfo) bool {
+ return strings.HasSuffix(path, ".gen.yaml") || strings.HasSuffix(path, ".gen.json")
+ })
+ fs = filter.Skip(fs, NamedFilesFilter("kustomization.yaml"))
+ fs = filter.Skip(fs, NamedFilesFilter("Makefile"))
+ fs = filter.Skip(fs, NamedFilesFilter("auto-generated.txt"))
+ fs = filter.Skip(fs, BigFilesFilter(1048576)) // 1M
+ fs = filter.Skip(fs, func(path string, fi os.FileInfo) bool {
+ for _, ex := range exclusions {
+ if strings.HasPrefix(path, ex) {
+ return true
+ }
+ }
+ return false
+ })
+
+ //
+ // Generate the assets
+ //
+ err = vfsgen.Generate(fs, vfsgen.Options{
+ Filename: resourceFile,
+ PackageName: filepath.Base(destDir),
+ })
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ //
+ // Post-process the final resource file
+ //
+ header := `/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+*/
+
+`
+ content, err := util.ReadFile(resourceFile)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ var finalContent []byte
+ finalContent = append(finalContent, []byte(header)...)
+ finalContent = append(finalContent, content...)
+ if err := os.WriteFile(resourceFile, finalContent, 0o600); err != nil {
+ log.Fatalln(err)
+ }
+}
+
+func NamedFilesFilter(names ...string) func(path string, fi os.FileInfo) bool {
+ return func(path string, fi os.FileInfo) bool {
+ if fi.IsDir() {
+ return false
+ }
+
+ for _, name := range names {
+ if name == filepath.Base(path) {
+ return true
+ }
+ }
+
+ return false
+ }
+}
+
+//
+// If file is bigger than maximum size (in bytes) then exclude.
+//
+func BigFilesFilter(size int) func(path string, fi os.FileInfo) bool {
+ return func(path string, fi os.FileInfo) bool {
+ if fi.IsDir() {
+ return false
+ }
+
+ if fi.Size() > int64(size) {
+ log.Printf("Warning: File %s is skipped due to being %d bytes (greater than maximum %d bytes)", path, fi.Size(), size)
+ return true
+ }
+
+ return false
+ }
+}
+
+func calcExclusions(root string, dirNames []string) []string {
+ var exclusions []string
+
+ for _, name := range dirNames {
+ dirName := filepath.Join(root, name)
+ if err := filepath.Walk(dirName, func(resPath string, info os.FileInfo, err error) error {
+ if info.IsDir() {
+ ignoreFileName := path.Join(resPath, ".vfsignore")
+ _, err := os.Stat(ignoreFileName)
+ if err == nil {
+ rel, err := filepath.Rel(dirName, resPath)
+ if err != nil {
+ log.Fatalln(err)
+ }
+ if !strings.HasPrefix(rel, "/") {
+ rel = "/" + rel
+ }
+ exclusions = append(exclusions, rel)
+ } else if !os.IsNotExist(err) {
+ log.Fatalln(err)
+ }
+ }
+ return nil
+ }); err != nil {
+ log.Fatalln(err)
+ }
+ }
+
+ return exclusions
+}
+
+func checkDir(dirName string) error {
+ dir, err := os.Stat(dirName)
+ if err != nil {
+ return err
+ }
+ if !dir.IsDir() {
+ return fmt.Errorf("path %s is not a directory", dirName)
+ }
+
+ return nil
+}
+
+// modTimeFS wraps http.FileSystem to set mod time to 0 for all files.
+type modTimeFS struct {
+ fs http.FileSystem
+}
+
+func (fs modTimeFS) Open(name string) (http.File, error) {
+ f, err := fs.fs.Open(name)
+ if err != nil {
+ return nil, err
+ }
+ return modTimeFile{f}, nil
+}
+
+type modTimeFile struct {
+ http.File
+}
+
+func (f modTimeFile) Stat() (os.FileInfo, error) {
+ fi, err := f.File.Stat()
+ if err != nil {
+ return nil, err
+ }
+ return modTimeFileInfo{fi}, nil
+}
+
+type modTimeFileInfo struct {
+ os.FileInfo
+}
+
+func (modTimeFileInfo) ModTime() time.Time {
+ return time.Time{}
+}
diff --git a/cmd/util/vfs-gen/multifs/multidir.go b/cmd/util/vfs-gen/multifs/multidir.go
new file mode 100644
index 000000000..7a7f62309
--- /dev/null
+++ b/cmd/util/vfs-gen/multifs/multidir.go
@@ -0,0 +1,171 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You 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.
+*/
+
+/*
+Based on the union fs function available at
+https://github.com/shurcooL/httpfs/blob/master/union/union.go
+(Licenced under MIT)
+*/
+
+package multifs
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+
+ "github.com/shurcooL/httpfs/vfsutil"
+)
+
+func New(rootDir string, dirNames []string, exclude []string) (http.FileSystem, error) {
+ m := &multiFS{
+ rootDir: rootDir,
+ exclude: exclude,
+ mfs: make(map[string]http.FileSystem),
+ root: &dirInfo{
+ name: "/",
+ },
+ }
+ for _, dirName := range dirNames {
+ err := m.bind(dirName)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return m, nil
+}
+
+type multiFS struct {
+ rootDir string
+ exclude []string
+ mfs map[string]http.FileSystem
+ root *dirInfo
+}
+
+func (m *multiFS) bind(dirName string) error {
+ absDir := filepath.Join(m.rootDir, dirName)
+
+ hfs := http.Dir(absDir)
+ m.mfs["/"+dirName] = hfs
+
+ //
+ // The 1-level down paths are needed since the
+ // remainder are covered by the http filesystems
+ //
+ fileInfos, err := vfsutil.ReadDir(hfs, "/")
+ if err != nil {
+ return err
+ }
+
+ for _, nfo := range fileInfos {
+ path := "/" + nfo.Name()
+
+ if m.excluded(path) {
+ continue // skip
+ }
+
+ if nfo.IsDir() {
+ m.root.entries = append(m.root.entries, &dirInfo{
+ name: path,
+ })
+ } else {
+ m.root.entries = append(m.root.entries, nfo)
+ }
+ }
+
+ return nil
+}
+
+func (m *multiFS) excluded(path string) bool {
+ for _, ex := range m.exclude {
+ if strings.HasPrefix(path, ex) {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (m *multiFS) Open(path string) (http.File, error) {
+ if path == "/" {
+ return &dir{
+ dirInfo: m.root,
+ }, nil
+ }
+
+ for _, fs := range m.mfs {
+ f, err := fs.Open(path)
+ if err != nil {
+ continue
+ }
+
+ return f, nil
+ }
+
+ return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist}
+}
+
+// dirInfo is a static definition of a directory.
+type dirInfo struct {
+ name string
+ entries []os.FileInfo
+}
+
+func (d *dirInfo) Read([]byte) (int, error) {
+ return 0, fmt.Errorf("cannot Read from directory %s", d.name)
+}
+func (d *dirInfo) Close() error { return nil }
+func (d *dirInfo) Stat() (os.FileInfo, error) { return d, nil }
+
+func (d *dirInfo) Name() string { return d.name }
+func (d *dirInfo) Size() int64 { return 0 }
+func (d *dirInfo) Mode() os.FileMode { return 0o755 | os.ModeDir }
+func (d *dirInfo) ModTime() time.Time { return time.Time{} } // Actual mod time is not computed because it's expensive and rarely needed.
+func (d *dirInfo) IsDir() bool { return true }
+func (d *dirInfo) Sys() interface{} { return nil }
+
+// dir is an opened dir instance.
+type dir struct {
+ *dirInfo
+ pos int // Position within entries for Seek and Readdir.
+}
+
+func (d *dir) Seek(offset int64, whence int) (int64, error) {
+ if offset == 0 && whence == io.SeekStart {
+ d.pos = 0
+ return 0, nil
+ }
+ return 0, fmt.Errorf("unsupported Seek in directory %s", d.dirInfo.name)
+}
+
+func (d *dir) Readdir(count int) ([]os.FileInfo, error) {
+ if d.pos >= len(d.dirInfo.entries) && count > 0 {
+ return nil, io.EOF
+ }
+ if count <= 0 || count > len(d.dirInfo.entries)-d.pos {
+ count = len(d.dirInfo.entries) - d.pos
+ }
+ e := d.dirInfo.entries[d.pos : d.pos+count]
+ d.pos += count
+
+ return e, nil
+}
diff --git a/go.mod b/go.mod
index b871dd193..99eb45a35 100644
--- a/go.mod
+++ b/go.mod
@@ -30,6 +30,8 @@ require (
github.com/redhat-developer/service-binding-operator v1.3.4
github.com/rs/xid v1.5.0
github.com/scylladb/go-set v1.0.2
+ github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749
+ github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd
github.com/sirupsen/logrus v1.9.2
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
diff --git a/go.sum b/go.sum
index 883aa0ffd..3fbb9d949 100644
--- a/go.sum
+++ b/go.sum
@@ -630,7 +630,11 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
github.com/scylladb/go-set v1.0.2 h1:SkvlMCKhP0wyyct6j+0IHJkBkSZL+TDzZ4E7f7BCcRE=
github.com/scylladb/go-set v1.0.2/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
+github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
+github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
diff --git a/pkg/resources/resources_support.go b/pkg/resources/resources_support.go
index b16595889..2dc27637b 100644
--- a/pkg/resources/resources_support.go
+++ b/pkg/resources/resources_support.go
@@ -31,7 +31,11 @@ import (
"github.com/apache/camel-k/v2/pkg/util"
)
+//
// ResourceAsString returns the named resource content as string.
+// Warning : do not remove the go:generate line as it is used to update the resources file in case of CRD changes.
+//
+//go:generate go run ../../cmd/util/vfs-gen resources config
func ResourceAsString(name string) (string, error) {
data, err := Resource(name)
return string(data), err