Skip to content

Commit

Permalink
2.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Icaruk committed Mar 30, 2023
1 parent afb56b6 commit 29ef470
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 73 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ CLI tool written in Go to review and update your NPM dependencies, easy and fast
![](https://i.imgur.com/8AUJFVb.png)


# Features

- Update each package one by one
- Check version update before updating it: patch, minor or major
- Review what's new on each package before updating it


# Usage

Expand Down
17 changes: 0 additions & 17 deletions package-lock.json

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "up-npm",
"version": "2.1.1",
"version": "2.2.0",
"author": "Icaruk",
"scripts": {
"postinstall": "node ./scripts/setup.js"
Expand Down
195 changes: 141 additions & 54 deletions pkg/updater/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"runtime"
"strconv"
"strings"
"sync"
"time"

"github.com/AlecAivazis/survey/v2"
Expand Down Expand Up @@ -205,7 +206,7 @@ func promptUpdateDependency(options updatePackageOptions, dependency, currentVer
return response, err
}

func promptWriteJson(options writeJsonOptions) string {
func promptWriteJson(options writeJsonOptions) (string, error) {
response := ""
prompt := &survey.Select{
Message: "Update package.json?",
Expand All @@ -215,9 +216,9 @@ func promptWriteJson(options writeJsonOptions) string {
options.no,
},
}
survey.AskOne(prompt, &response)
err := survey.AskOne(prompt, &response)

return response
return response, err
}

func getVersionType(currentVersion, latestVersion string) string {
Expand Down Expand Up @@ -306,16 +307,32 @@ func getCleanVersion(version string) (string, string) {
}

func getRepositoryUrl(url string) string {
re := regexp.MustCompile(`^(git\+)(.*)(.git)$`)
// https://regex101.com/r/AEVsGf/1
re := regexp.MustCompile(`^(git\+)(.*)`)
matches := re.FindStringSubmatch(url)
return matches[2]

if matches == nil {
return ""
}

repoUrl := matches[2]
repoUrl = strings.TrimSuffix(repoUrl, ".git")

return repoUrl
}

const concurrencyLimit int = 10

func readDependencies(dependencyList map[string]string, targetMap map[string]VersionComparisonItem, isDev bool, bar *progressbar.ProgressBar) {

if !isDev {
isDev = false
}
var wg sync.WaitGroup
semaphoreChan := make(chan struct{}, concurrencyLimit)
resultsChan := make(chan string, len(dependencyList))
doneChan := make(chan struct{})

defer func() {
close(semaphoreChan)
}()

for dependency, currentVersion := range dependencyList {

Expand All @@ -327,54 +344,84 @@ func readDependencies(dependencyList map[string]string, targetMap map[string]Ver
continue
}

// Perform get request to npm registry
resp, err := fetchNpmRegistry(dependency)
if err != nil {
fmt.Println("Failed to fetch", dependency, " from npm registry, skipping...")
continue
}
defer resp.Body.Close()

// Get response data
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)

distTags := result["dist-tags"].(map[string]interface{})
homepage := result["homepage"].(string)
repository := result["repository"].(map[string]interface{})
repositoryUrl := getRepositoryUrl(repository["url"].(string))

// Get latest version from distTags
var latestVersion string
for key := range distTags {
if key == "latest" {
latestVersion = distTags[key].(string)
wg.Add(1)

go func(dependency string, currentVersion string) {
defer func() {
wg.Done()
<-semaphoreChan
}()
semaphoreChan <- struct{}{}

// Perform get request to npm registry
resp, err := fetchNpmRegistry(dependency)
if err != nil {
fmt.Println("Failed to fetch", dependency, " from npm registry, skipping...")
resultsChan <- "" // Enviar un resultado vacío para que se tenga en cuenta en la cuenta de resultados
return
}
}
defer resp.Body.Close()

// Get version type (major, minor, patch)
versionType := getVersionType(cleanCurrentVersion, latestVersion)

// Save data
if versionType != "" {
targetMap[dependency] = VersionComparisonItem{
current: cleanCurrentVersion,
latest: latestVersion,
versionType: versionType,
shouldUpdate: false,
homepage: homepage,
repositoryUrl: repositoryUrl,
versionPrefix: versionPrefix,
isDev: isDev,
// Get response data
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)

distTags := result["dist-tags"].(map[string]interface{})

var homepage string
if result["homepage"] != nil {
homepage = result["homepage"].(string)
}
}

if bar != nil {
bar.Add(1)
}
var repository map[string]interface{}
if result["repository"] != nil {
repository = result["repository"].(map[string]interface{})
}

var repositoryUrl string
if repository["url"] != nil {
repositoryUrl = getRepositoryUrl(repository["url"].(string))
}

// Get latest version from distTags
var latestVersion string
for key := range distTags {
if key == "latest" {
latestVersion = distTags[key].(string)
}
}

// Get version type (major, minor, patch)
versionType := getVersionType(cleanCurrentVersion, latestVersion)

// Save data
if versionType != "" {
targetMap[dependency] = VersionComparisonItem{
current: cleanCurrentVersion,
latest: latestVersion,
versionType: versionType,
shouldUpdate: false,
homepage: homepage,
repositoryUrl: repositoryUrl,
versionPrefix: versionPrefix,
isDev: isDev,
}
}

resultsChan <- ""

if bar != nil {
bar.Add(1)
}

}(dependency, currentVersion)

}

// Wait for all goroutines to complete
wg.Wait()
close(doneChan)

}

func Init(updateDev bool) {
Expand All @@ -393,7 +440,7 @@ func Init(updateDev bool) {
var packageJsonMap PackageJSON
err = json.Unmarshal(jsonFile, &packageJsonMap)
if err != nil {
fmt.Println(aurora.Red("Error reading package.json"), "the file seems corrupt. Error:")
fmt.Println(aurora.Red("Error reading package.json"), "invalid JSON or corrupt file. Error:")
fmt.Println(err)
fmt.Println()
return
Expand Down Expand Up @@ -424,8 +471,10 @@ func Init(updateDev bool) {
// Count version types
totalCount, majorCount, minorCount, patchCount := countVersionTypes(versionComparison)
if totalCount == 0 {
fmt.Println()
fmt.Println()
fmt.Println(aurora.Green("No outdated dependencies!"))
fmt.Println("")
fmt.Println()
return
}

Expand All @@ -436,6 +485,7 @@ func Init(updateDev bool) {
fmt.Println("")

// Print summary line (1 major, 1 minor, 1 patch)
fmt.Println("Total dependencies:", aurora.Blue(totalCount))
printSummary(totalCount, majorCount, minorCount, patchCount)
fmt.Println()

Expand Down Expand Up @@ -471,11 +521,16 @@ func Init(updateDev bool) {
var url string

if value.repositoryUrl != "" {
url = value.repositoryUrl + "/releases"
url = value.repositoryUrl + "/releases" + "#:~:text=" + value.current
} else {
url = value.homepage
}

if url == "" {
fmt.Println(aurora.Yellow("No repository or homepage URL found"))
break
}

fmt.Println("Opening...")
fmt.Println()
Openbrowser(url)
Expand Down Expand Up @@ -508,14 +563,40 @@ func Init(updateDev bool) {

// ------------------------------------------

// Check how many updates are on versionComparison with value.shouldUpdate = true
var shouldUpdateCount int
for _, value := range versionComparison {
if value.shouldUpdate {
shouldUpdateCount++
}
}

if shouldUpdateCount == 0 {
fmt.Println(aurora.Yellow("No packages have been selected to update"))
return
}

fmt.Println(
aurora.Green("There are"),
aurora.Green(shouldUpdateCount),
aurora.Green("package(s) selected to be updated"),
)
fmt.Println()

// Prompt to write package.json
writeJsonOptions := writeJsonOptions{
yes: "Yes",
yes_backup: "Yes, but backup before update",
no: "No",
}

response := promptWriteJson(writeJsonOptions)
response, err := promptWriteJson(writeJsonOptions)

if err != nil {
if err == terminal.InterruptErr {
log.Fatal("interrupted")
}
}

if response == writeJsonOptions.no {
fmt.Println("Cancelled update process")
Expand Down Expand Up @@ -552,7 +633,13 @@ func Init(updateDev bool) {
}

fmt.Println()
fmt.Println(aurora.Green("Updated package.json"))
fmt.Println(
"✅ package.json has been updated with",
aurora.Sprintf(aurora.Green("%d updated packages"), shouldUpdateCount),
)
fmt.Println()

fmt.Println("Run 'npm install' to install dependencies")
fmt.Println()

}
2 changes: 1 addition & 1 deletion scripts/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const scriptsPath = path.join(__dirname, "../scripts");
const binPath = path.join(__dirname, "..");

const appName = "up-npm";
const version = "2.1.1";
const version = "2.2.0";

let distFilename = "";
let isWindows = false;
Expand Down
Loading

0 comments on commit 29ef470

Please sign in to comment.