11package pack
22
33import (
4- "archive/zip"
5- "bufio"
4+ "bytes"
65 "encoding/json"
76 "fmt"
8- "io"
97 "io/ioutil"
108 "os"
119 "path/filepath"
12- "strings"
1310 "time"
11+
12+ "golang.org/x/mod/modfile"
13+ "golang.org/x/mod/zip"
1414)
1515
1616// Module packs the module at the given path and version then
1717// outputs the result to the specified output directory
1818func Module (path string , version string , outputDirectory string ) error {
19- moduleName , err := getModuleName (path )
19+ moduleFile , err := getModuleFile (path , version )
2020 if err != nil {
21- return fmt .Errorf ("get module name : %w" , err )
21+ return fmt .Errorf ("get module file : %w" , err )
2222 }
2323
24- if err := createZipArchive (path , moduleName , version , outputDirectory ); err != nil {
24+ if err := createZipArchive (path , moduleFile , outputDirectory ); err != nil {
2525 return fmt .Errorf ("create zip archive: %w" , err )
2626 }
2727
28- if err := createInfoFile (version , outputDirectory ); err != nil {
28+ if err := createInfoFile (moduleFile , outputDirectory ); err != nil {
2929 return fmt .Errorf ("create info file: %w" , err )
3030 }
3131
32- if err := copyModuleFile (path , outputDirectory ); err != nil {
32+ if err := copyModuleFile (path , moduleFile , outputDirectory ); err != nil {
3333 return fmt .Errorf ("copy module file: %w" , err )
3434 }
3535
3636 return nil
3737}
3838
39- func getModuleName (path string ) (string , error ) {
40- moduleFilePath : = filepath .Join (path , "go.mod" )
41- file , err := os .Open (moduleFilePath )
39+ func getModuleFile (path string , version string ) (* modfile. File , error ) {
40+ path = filepath .Join (path , "go.mod" )
41+ file , err := os .Open (path )
4242 if err != nil {
43- return "" , fmt .Errorf ("unable to open module file: %w" , err )
43+ return nil , fmt .Errorf ("open module file: %w" , err )
4444 }
4545 defer file .Close ()
4646
47- moduleFileScanner := bufio .NewScanner (file )
48- moduleFileScanner .Scan ()
49-
50- moduleHeaderParts := strings .Split (moduleFileScanner .Text (), " " )
51- if len (moduleHeaderParts ) <= 1 {
52- return "" , fmt .Errorf ("parse module header: %w" , err )
53- }
54-
55- return moduleHeaderParts [1 ], nil
56- }
57-
58- func createZipArchive (path string , moduleName string , version string , outputDirectory string ) error {
59- filePathsToArchive , err := getFilePathsToArchive (path )
47+ moduleBytes , err := ioutil .ReadAll (file )
6048 if err != nil {
61- return fmt .Errorf ("get files to archive : %w" , err )
49+ return nil , fmt .Errorf ("read module file : %w" , err )
6250 }
6351
64- outputPath := filepath .Join (outputDirectory , version + ".zip" )
65- zipFile , err := os .Create (outputPath )
52+ moduleFile , err := modfile .Parse (path , moduleBytes , nil )
6653 if err != nil {
67- return fmt .Errorf ("create zip file: %w" , err )
54+ return nil , fmt .Errorf ("parse module file: %w" , err )
6855 }
69- defer zipFile .Close ()
70-
71- zipWriter := zip .NewWriter (zipFile )
72- defer zipWriter .Close ()
73-
74- for _ , filePath := range filePathsToArchive {
75- fileToZip , err := os .Open (filePath )
76- if err != nil {
77- return fmt .Errorf ("open file: %w" , err )
78- }
79-
80- zippedFilePath := getZipPath (path , filePath , moduleName , version )
81- zippedFileWriter , err := zipWriter .Create (zippedFilePath )
82- if err != nil {
83- return fmt .Errorf ("add file to zip archive: %w" , err )
84- }
85-
86- if _ , err := io .Copy (zippedFileWriter , fileToZip ); err != nil {
87- return fmt .Errorf ("copy file contents to zip archive: %w" , err )
88- }
8956
90- fileToZip .Close ()
57+ if moduleFile .Module == nil {
58+ return nil , fmt .Errorf ("parsing module returned nil module" )
9159 }
9260
93- return nil
94- }
95-
96- func getFilePathsToArchive (path string ) ([]string , error ) {
97- var files []string
98- err := filepath .Walk (path , func (currentFilePath string , fileInfo os.FileInfo , err error ) error {
99- if err != nil {
100- return fmt .Errorf ("walk path: %w" , err )
101- }
61+ moduleFile .Module .Mod .Version = version
10262
103- if fileInfo .IsDir () && fileInfo .Name () == ".git" {
104- return filepath .SkipDir
105- }
106-
107- if fileInfo .IsDir () {
108- return nil
109- }
63+ return moduleFile , nil
64+ }
11065
111- files = append (files , currentFilePath )
66+ func createZipArchive (path string , moduleFile * modfile.File , outputDirectory string ) error {
67+ outputPath := filepath .Join (outputDirectory , moduleFile .Module .Mod .Version + ".zip" )
11268
113- return nil
114- })
115- if err != nil {
116- return nil , err
69+ var zipContents bytes.Buffer
70+ if err := zip .CreateFromDir (& zipContents , moduleFile .Module .Mod , path ); err != nil {
71+ return fmt .Errorf ("create zip from dir: %w" , err )
11772 }
11873
119- return files , nil
120- }
74+ if err := ioutil .WriteFile (outputPath , zipContents .Bytes (), 0644 ); err != nil {
75+ return fmt .Errorf ("writing zip file: %w" , err )
76+ }
12177
122- func getZipPath (path string , currentFilePath string , moduleName string , version string ) string {
123- filePath := strings .TrimPrefix (currentFilePath , path )
124- return filepath .Join (fmt .Sprintf ("%s@%s" , moduleName , version ), filePath )
78+ return nil
12579}
12680
127- func createInfoFile (version string , outputDirectory string ) error {
128- infoFilePath := filepath .Join (outputDirectory , version + ".info" )
81+ func createInfoFile (moduleFile * modfile. File , outputDirectory string ) error {
82+ infoFilePath := filepath .Join (outputDirectory , moduleFile . Module . Mod . Version + ".info" )
12983 file , err := os .Create (infoFilePath )
13084 if err != nil {
13185 return fmt .Errorf ("create info file: %w" , err )
@@ -139,7 +93,7 @@ func createInfoFile(version string, outputDirectory string) error {
13993
14094 currentTime := getInfoFileFormattedTime (time .Now ())
14195 info := infoFile {
142- Version : version ,
96+ Version : moduleFile . Module . Mod . Version ,
14397 Time : currentTime ,
14498 }
14599
@@ -160,13 +114,13 @@ func getInfoFileFormattedTime(currentTime time.Time) string {
160114 return currentTime .Format (infoFileTimeFormat )
161115}
162116
163- func copyModuleFile (path string , outputDirectory string ) error {
117+ func copyModuleFile (path string , moduleFile * modfile. File , outputDirectory string ) error {
164118 if outputDirectory == "." {
165119 return nil
166120 }
167121
168122 sourcePath := filepath .Join (path , "go.mod" )
169- destinationPath := filepath .Join (outputDirectory , "go .mod" )
123+ destinationPath := filepath .Join (outputDirectory , moduleFile . Module . Mod . Version + " .mod" )
170124
171125 if sourcePath == destinationPath {
172126 return nil
0 commit comments