Skip to content

Commit

Permalink
feat: support output vendor archive in cli
Browse files Browse the repository at this point in the history
  • Loading branch information
kulti committed Nov 25, 2024
1 parent 6a112cd commit 1ec8bbd
Show file tree
Hide file tree
Showing 216 changed files with 17,797 additions and 31 deletions.
1 change: 1 addition & 0 deletions api/rockamalg.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ message AmalgRequest {

message AmalgResponse {
bytes lua = 1;
bytes vendor = 2;
}
35 changes: 22 additions & 13 deletions internal/api/rockamalgrpc/rockamalg.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

74 changes: 61 additions & 13 deletions internal/archive/zip.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,27 @@ import (

var errZipInvalidFilePath = errors.New("invalid file path in zip")

func ZipDir(path string) ([]byte, error) {
func ZipDirToBytes(path string) ([]byte, error) {
buf := new(bytes.Buffer)
zw := zip.NewWriter(buf)
err := zipDir(path, buf)
return buf.Bytes(), err
}

func ZipDirToFile(path, zipFilePath string) error {
file, err := os.Create(zipFilePath)
if err != nil {
return fmt.Errorf("creates archive file: %w", err)
}
defer file.Close()
return zipDir(path, file)
}

func zipDir(path string, w io.Writer) error {
zw := zip.NewWriter(w)
defer zw.Close()

fsys := os.DirFS(path)
err := fs.WalkDir(fsys, ".", func(path string, entry fs.DirEntry, err error) error {
return fs.WalkDir(fsys, ".", func(path string, entry fs.DirEntry, err error) error {
if err != nil {
return err
}
Expand All @@ -43,15 +58,6 @@ func ZipDir(path string) ([]byte, error) {
}
return nil
})
if err != nil {
return nil, fmt.Errorf("walk dir: %w", err)
}

if err := zw.Close(); err != nil {
return nil, fmt.Errorf("close zip: %w", err)
}

return buf.Bytes(), nil
}

func UnzipBytesToDir(data []byte, path string) error {
Expand All @@ -62,6 +68,48 @@ func UnzipBytesToDir(data []byte, path string) error {
return unzipToDir(archive, path)
}

func UnzipFileToDir(zipFile, path string) error {
archive, err := zip.OpenReader(zipFile)
if err != nil {
return fmt.Errorf("create zip reader: %w", err)
}
defer archive.Close()
return unzipToDir(&archive.Reader, path)
}

func UnzipFileToFilesMap(zipFile string) (map[string][]byte, error) {
archive, err := zip.OpenReader(zipFile)
if err != nil {
return nil, fmt.Errorf("create zip reader: %w", err)
}
defer archive.Close()
return unzipToFilesMap(&archive.Reader)
}

func unzipToFilesMap(archive *zip.Reader) (map[string][]byte, error) {
files := make(map[string][]byte, len(archive.File))
for _, f := range archive.File {
if f.FileInfo().IsDir() {
continue
}

fileInArchive, err := f.Open()
if err != nil {
return nil, fmt.Errorf("open archive file: %w", err)
}

file, err := io.ReadAll(fileInArchive)
if err != nil {
return nil, fmt.Errorf("read archive file: %w", err)
}

fileInArchive.Close()
files[f.Name] = file
}

return files, nil
}

func unzipToDir(archive *zip.Reader, path string) error {
for _, f := range archive.File {
if f.FileInfo().IsDir() {
Expand All @@ -87,7 +135,7 @@ func unzipToDir(archive *zip.Reader, path string) error {
return fmt.Errorf("open archive file: %w", err)
}

//#nosec G110 -- this server for internal usage only.
//#nosec G110 -- this server for internal usage only and tests.
if _, err := io.Copy(dstFile, fileInArchive); err != nil {
return fmt.Errorf("copy: %w", err)
}
Expand Down
12 changes: 12 additions & 0 deletions internal/rockamalg/rockamalg.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"sync"
"text/template"

"github.com/enapter/rockamalg/internal/archive"
"github.com/enapter/rockamalg/internal/rockamalg/analyzer"
)

Expand All @@ -29,6 +30,7 @@ type AmalgParams struct {
Rockspec string
Lua string
Output string
Vendor string
Isolate bool
DisableDebug bool
AllowDevDeps bool
Expand Down Expand Up @@ -128,6 +130,12 @@ func (a *amalg) Do(ctx context.Context) error {
if err := a.wrapWithMsg(a.installDependencies, "Installing dependencies")(ctx); err != nil {
return fmt.Errorf("install dependencies: %w", err)
}

if a.p.Vendor != "" {
if err := a.wrapWithMsg(a.buildVendorArchive, "Building vendor archive")(ctx); err != nil {
return fmt.Errorf("build vendor archive: %w", err)
}
}
}

if err := a.wrapWithMsg(a.calculateRequires, "Calculating requires")(ctx); err != nil {
Expand Down Expand Up @@ -240,6 +248,10 @@ func (a *amalg) installDependencies(ctx context.Context) error {
return nil
}

func (a *amalg) buildVendorArchive(_ context.Context) error {
return archive.ZipDirToFile(a.tree, a.p.Vendor)
}

func (a *amalg) calculateRequires(ctx context.Context) error {
var err error
if a.p.Isolate {
Expand Down
9 changes: 9 additions & 0 deletions internal/rockamalgcli/cmd_amalg.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type cmdAmalg struct {
deps string
rockspec string
output string
vendor string
lua string
isolate bool
disableDebug bool
Expand Down Expand Up @@ -54,6 +55,13 @@ See the tutorial https://developers.enapter.com/docs/tutorial/lua-complex/introd
Destination: &cmd.output,
Required: true,
},
&cli.StringFlag{
Name: "vendor",
Aliases: []string{"v"},
Usage: "Vendor zip archive file name",
Destination: &cmd.vendor,
Required: true,
},
&cli.BoolFlag{
Name: "isolate",
Aliases: []string{"i"},
Expand Down Expand Up @@ -94,6 +102,7 @@ See the tutorial https://developers.enapter.com/docs/tutorial/lua-complex/introd
Rockspec: cmd.rockspec,
Lua: cmd.lua,
Output: cmd.output,
Vendor: cmd.vendor,
Writer: cliCtx.App.Writer,
Isolate: cmd.isolate,
DisableDebug: cmd.disableDebug,
Expand Down
7 changes: 4 additions & 3 deletions internal/rockamalgcli/testdata/helps/rockamalg amalg
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ USAGE:

DESCRIPTION:
The lua should be a single Lua file or directory with main.lua and other Lua files.

The dependencies file should be in the Luarocks format.

See the tutorial https://developers.enapter.com/docs/tutorial/lua-complex/introduction to learn more.

OPTIONS:
--deps value, -d value Use dependencies file
--rockspec value, -r value Use rockspec file for dependencies
--output value, -o value Output Lua file name
--vendor value, -v value Vendor zip archive file name
--isolate, -i Enable isolate mode (default: false)
--disable-debug Disable debug mode (default: false)
--allow-dev-dependencies Allow to use dev dependencies (default: false)
--rocks-server value, -s value Use custom rocks server
--help, -h show help (default: false)

Loading

0 comments on commit 1ec8bbd

Please sign in to comment.