From f289f3b62f64be235c472fe438ac5a4aefc067f7 Mon Sep 17 00:00:00 2001
From: Roberto Sora <r.sora@arduino.cc>
Date: Fri, 19 Apr 2019 18:45:14 +0200
Subject: [PATCH 1/2] replace PathEscaping with encoding in base64 for
 downloaded index filenames in order to be compatible on windows FS

---
 v2/pkgs/indexes.go | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/v2/pkgs/indexes.go b/v2/pkgs/indexes.go
index ff0d9dcff..96f30c17f 100644
--- a/v2/pkgs/indexes.go
+++ b/v2/pkgs/indexes.go
@@ -2,6 +2,7 @@ package pkgs
 
 import (
 	"context"
+	b64 "encoding/base64"
 	"encoding/json"
 	"io/ioutil"
 	"net/url"
@@ -31,7 +32,7 @@ func (c *Indexes) Add(ctx context.Context, payload *indexes.IndexPayload) (*inde
 	}
 
 	// Download tmp file
-	filename := url.PathEscape(payload.URL)
+	filename := b64.StdEncoding.EncodeToString([]byte(url.PathEscape(payload.URL)))
 	path := filepath.Join(c.Folder, filename+".tmp")
 	d, err := downloader.Download(path, indexURL.String())
 	if err != nil {
@@ -53,7 +54,7 @@ func (c *Indexes) Add(ctx context.Context, payload *indexes.IndexPayload) (*inde
 
 // Get reads the index file from the Indexes Folder, unmarshaling it
 func (c *Indexes) Get(ctx context.Context, uri string) (index Index, err error) {
-	filename := url.PathEscape(uri)
+	filename := b64.StdEncoding.EncodeToString([]byte(url.PathEscape(uri)))
 	path := filepath.Join(c.Folder, filename)
 	data, err := ioutil.ReadFile(path)
 	if err != nil {
@@ -74,6 +75,7 @@ func (c *Indexes) List(context.Context) ([]string, error) {
 	_ = os.MkdirAll(c.Folder, 0755)
 	// Read files
 	files, err := ioutil.ReadDir(c.Folder)
+
 	if err != nil {
 		return nil, err
 	}
@@ -81,10 +83,12 @@ func (c *Indexes) List(context.Context) ([]string, error) {
 	res := []string{}
 	for _, file := range files {
 		// Select only files that begin with http
-		if !strings.HasPrefix(file.Name(), "http") {
+		decodedFileName, _ := b64.URLEncoding.DecodeString(file.Name())
+		fileName:=string(decodedFileName)
+		if !strings.HasPrefix(fileName, "http") {
 			continue
 		}
-		path, err := url.PathUnescape(file.Name())
+		path, err := url.PathUnescape(fileName)
 		if err != nil {
 			c.Log.Warn(err)
 		}
@@ -96,7 +100,7 @@ func (c *Indexes) List(context.Context) ([]string, error) {
 
 // Remove deletes the index file from the Indexes Folder
 func (c *Indexes) Remove(ctx context.Context, payload *indexes.IndexPayload) (*indexes.Operation, error) {
-	filename := url.PathEscape(payload.URL)
+	filename := b64.StdEncoding.EncodeToString([]byte(url.PathEscape(payload.URL)))
 	err := os.RemoveAll(filepath.Join(c.Folder, filename))
 	if err != nil {
 		return nil, err

From 9f5f93d8a7ce8e946f05de959474bf7cb19a1900 Mon Sep 17 00:00:00 2001
From: Roberto Sora <r.sora@arduino.cc>
Date: Fri, 19 Apr 2019 18:45:56 +0200
Subject: [PATCH 2/2] add tool entry with version in installed.json

---
 v2/pkgs/tools.go | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/v2/pkgs/tools.go b/v2/pkgs/tools.go
index 777007943..0418db044 100644
--- a/v2/pkgs/tools.go
+++ b/v2/pkgs/tools.go
@@ -212,10 +212,9 @@ func (c *Tools) Remove(ctx context.Context, payload *tools.ToolPayload) (*tools.
 
 func rename(base string) extract.Renamer {
 	return func(path string) string {
-		parts := strings.Split(path, string(filepath.Separator))
-		path = strings.Join(parts[1:], string(filepath.Separator))
+		parts := strings.Split(filepath.ToSlash(path), "/")
+		path = strings.Join(parts[1:], "/")
 		path = filepath.Join(base, path)
-
 		return path
 	}
 }
@@ -258,8 +257,9 @@ func writeInstalled(folder, path string) error {
 
 	parts := strings.Split(path, string(filepath.Separator))
 	tool := parts[len(parts)-2]
-
+	toolWithVersion := fmt.Sprint(tool, "-", parts[len(parts)-1])
 	installed[tool] = filepath.Join(folder, path)
+	installed[toolWithVersion] = filepath.Join(folder, path)
 
 	data, err = json.Marshal(installed)
 	if err != nil {