11package command
22
33import (
4- "archive/tar"
5- "compress/gzip"
64 "context"
7- "encoding/base64"
85 "encoding/json"
96 "errors"
107 "fmt"
@@ -13,10 +10,10 @@ import (
1310 "os"
1411 "path/filepath"
1512
13+ "github.com/harness/harness-cli/cmd/artifact/command/utils"
1614 "github.com/harness/harness-cli/cmd/cmdutils"
1715 "github.com/harness/harness-cli/config"
1816 pkgclient "github.com/harness/harness-cli/internal/api/ar_pkg"
19- "github.com/harness/harness-cli/module/ar/migrate/types/npm"
2017 "github.com/harness/harness-cli/util/common/auth"
2118 p "github.com/harness/harness-cli/util/common/progress"
2219
@@ -72,15 +69,29 @@ func NewPushNpmCmd(f *cmdutils.Factory) *cobra.Command {
7269
7370 // Extract package.json from tarball
7471 progress .Step ("Extracting package.json from tarball" )
75- pkgJSONBytes , err := extractPackageJSONFromTarball (packageFilePath )
72+ file , err := os .Open (packageFilePath )
73+ if err != nil {
74+ progress .Error ("Failed to open tarball" )
75+ return fmt .Errorf ("failed to open tarball: %w" , err )
76+ }
77+ defer file .Close ()
78+
79+ pkgJSONBytes , err := utils .ExtractPackageJSONFromTarball (file )
7680 if err != nil {
7781 progress .Error ("Failed to extract package.json from tarball" )
7882 return fmt .Errorf ("failed to extract package.json from tarball: %w" , err )
7983 }
8084
8185 // Build NPM upload payload
86+ file , err = os .Open (packageFilePath )
87+ if err != nil {
88+ progress .Error ("Failed to open tarball" )
89+ return fmt .Errorf ("failed to open tarball: %w" , err )
90+ }
91+ defer file .Close ()
92+
8293 progress .Step ("Building NPM upload payload" )
83- upload , pkgName , version , err := buildNpmUploadFromPackageJSON (pkgJSONBytes , packageFilePath )
94+ upload , pkgName , version , err := utils . BuildNpmUploadFromPackageJSON (pkgJSONBytes , file )
8495 if err != nil {
8596 progress .Error ("Failed to build NPM upload body" )
8697 return fmt .Errorf ("failed to build NPM upload body: %w" , err )
@@ -156,144 +167,3 @@ func NewPushNpmCmd(f *cmdutils.Factory) *cobra.Command {
156167
157168 return cmd
158169}
159-
160- func extractPackageJSONFromTarball (path string ) ([]byte , error ) {
161- file , err := os .Open (path )
162- if err != nil {
163- return nil , fmt .Errorf ("failed to open tarball: %w" , err )
164- }
165- defer file .Close ()
166-
167- gzReader , err := gzip .NewReader (file )
168- if err != nil {
169- return nil , fmt .Errorf ("failed to create gzip reader: %w" , err )
170- }
171- defer gzReader .Close ()
172-
173- tarReader := tar .NewReader (gzReader )
174-
175- for {
176- header , err := tarReader .Next ()
177- if err == io .EOF {
178- break
179- }
180- if err != nil {
181- return nil , fmt .Errorf ("failed to read tar header: %w" , err )
182- }
183-
184- if header .FileInfo ().IsDir () {
185- continue
186- }
187-
188- base := filepath .Base (header .Name )
189- if base == "package.json" {
190- data , err := io .ReadAll (tarReader )
191- if err != nil {
192- return nil , fmt .Errorf ("failed to read package.json from tarball: %w" , err )
193- }
194- return data , nil
195- }
196- }
197-
198- return nil , fmt .Errorf ("package.json not found in tarball" )
199- }
200-
201- // minimalPackageJSON represents the subset of fields from package.json we care about.
202- type minimalPackageJSON struct {
203- Name string `json:"name"`
204- Version string `json:"version"`
205- Description string `json:"description"`
206- Homepage string `json:"homepage"`
207- Keywords []string `json:"keywords"`
208- Repository interface {} `json:"repository"`
209- Author interface {} `json:"author"`
210- License interface {} `json:"license"`
211- Dependencies map [string ]string `json:"dependencies"`
212- DevDependencies map [string ]string `json:"devDependencies"`
213- PeerDependencies map [string ]string `json:"peerDependencies"`
214- OptionalDependencies map [string ]string `json:"optionalDependencies"`
215- Bin interface {} `json:"bin"`
216- }
217-
218- func buildNpmUploadFromPackageJSON (pkgJSON []byte , tarballPath string ) (* npm.PackageUpload , string , string , error ) {
219- var pkg minimalPackageJSON
220- if err := json .Unmarshal (pkgJSON , & pkg ); err != nil {
221- return nil , "" , "" , fmt .Errorf ("failed to parse package.json: %w" , err )
222- }
223-
224- if pkg .Name == "" || pkg .Version == "" {
225- return nil , "" , "" , fmt .Errorf ("package.json must contain 'name' and 'version'" )
226- }
227-
228- versionObj := & npm.PackageMetadataVersion {
229- ID : pkg .Name + "@" + pkg .Version ,
230- Name : pkg .Name ,
231- Version : pkg .Version ,
232- Description : pkg .Description ,
233- Author : pkg .Author ,
234- Homepage : pkg .Homepage ,
235- License : pkg .License ,
236- Repository : pkg .Repository ,
237- Keywords : pkg .Keywords ,
238- Dependencies : pkg .Dependencies ,
239- BundleDependencies : nil ,
240- DevDependencies : pkg .DevDependencies ,
241- PeerDependencies : pkg .PeerDependencies ,
242- Bin : pkg .Bin ,
243- OptionalDependencies : pkg .OptionalDependencies ,
244- Readme : "" ,
245- Dist : npm.PackageDistribution {},
246- Maintainers : nil ,
247- }
248-
249- metadata := npm.PackageMetadata {
250- ID : pkg .Name ,
251- Name : pkg .Name ,
252- Description : pkg .Description ,
253- DistTags : map [string ]string {
254- "latest" : pkg .Version ,
255- },
256- Versions : map [string ]* npm.PackageMetadataVersion {
257- pkg .Version : versionObj ,
258- },
259- Readme : "" ,
260- Maintainers : nil ,
261- Time : nil ,
262- Homepage : pkg .Homepage ,
263- Keywords : pkg .Keywords ,
264- Repository : pkg .Repository ,
265- Author : pkg .Author ,
266- ReadmeFilename : "" ,
267- Users : nil ,
268- License : pkg .License ,
269- }
270-
271- // Read tarball and base64 encode it into _attachments
272- file , err := os .Open (tarballPath )
273- if err != nil {
274- return nil , "" , "" , fmt .Errorf ("failed to open tarball for attachment: %w" , err )
275- }
276- defer file .Close ()
277-
278- data , err := io .ReadAll (file )
279- if err != nil {
280- return nil , "" , "" , fmt .Errorf ("failed to read tarball for attachment: %w" , err )
281- }
282-
283- b64Data := base64 .StdEncoding .EncodeToString (data )
284-
285- tarballName := filepath .Base (tarballPath )
286-
287- upload := & npm.PackageUpload {
288- PackageMetadata : metadata ,
289- Attachments : map [string ]* npm.PackageAttachment {
290- tarballName : {
291- ContentType : "application/octet-stream" ,
292- Data : b64Data ,
293- Length : len (data ),
294- },
295- },
296- }
297-
298- return upload , pkg .Name , pkg .Version , nil
299- }
0 commit comments