Skip to content

Instantly share code, notes, and snippets.

@skyend
Last active November 14, 2023 13:08
Show Gist options
  • Save skyend/03491e0577f7dd417b73d2c8c3070cff to your computer and use it in GitHub Desktop.
Save skyend/03491e0577f7dd417b73d2c8c3070cff to your computer and use it in GitHub Desktop.
node_modules Recursive packer
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"sync"
)
type PackageJson struct {
Name string `json:"name"`
Version string `json:"version"`
}
type PackInfo struct {
PackageJson
RelativeDirPath string
}
func ReadDirRecursively(dir string, visitor func(dir string)) {
files, err := ioutil.ReadDir(dir)
if err != nil {
panic(err)
}
for _, file := range files {
relativePath := path.Join(dir, file.Name())
if file.IsDir() {
ReadDirRecursively(relativePath, visitor)
}
visitor(relativePath)
//println(relativePath, file.IsDir())
}
}
func main() {
fmt.Println("Hello")
packTargetBuffer := make(chan PackInfo, 10000)
failedPacks := []PackInfo{}
done := make(chan bool)
totalCount := 0
packedCount := 0
var wg sync.WaitGroup
go func() {
ReadDirRecursively("./node_modules", func(dir string) {
packagePath := path.Join(dir, "package.json")
fileBytes, err := ioutil.ReadFile(packagePath)
if err != nil {
// package.json 이 없으면 아무것도안함
return
}
packageJson := PackageJson{}
err = json.Unmarshal(fileBytes, &packageJson)
if err != nil {
panic(err)
}
packTargetBuffer <- PackInfo{
PackageJson: packageJson,
RelativeDirPath: dir,
}
totalCount++
//fmt.Println(packageJson.Name)
})
done <- true
}()
os.Mkdir("./packs/", os.ModePerm)
workerCount := 10
packCounter := make(chan int, workerCount)
waitGo := make(chan bool, workerCount)
for i := 0; i < workerCount; i++ {
go func() {
for {
packInfo, more := <-packTargetBuffer
if !more {
waitGo <- true
return
}
fmt.Println("Packing...", packInfo.Name, packInfo.Version)
cmd := exec.Command("npm", "pack", packInfo.RelativeDirPath, "--pack-destination", "./packs")
if err := cmd.Run(); err != nil {
_, err := cmd.CombinedOutput()
fmt.Println("Pack fail", err.Error())
wg.Add(1)
failedPacks = append(failedPacks, packInfo)
wg.Done()
} else {
fmt.Println("Pack done", packInfo.Name, packInfo.Version)
packCounter <- 1
}
}
}()
}
go func() {
// discounter
for {
packedCount += <-packCounter
fmt.Printf("Progress %d/%d \n", packedCount, totalCount)
}
}()
<-done
for i := 0; i < workerCount; i++ {
<-waitGo
}
fmt.Println("Done")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment