From e4a01a315df4ba8cc14f2c72f3a735951215e0dd Mon Sep 17 00:00:00 2001
From: Compey <hi@devcomp.xyz>
Date: Sun, 27 Nov 2022 17:53:16 +0530
Subject: [PATCH] feat: untar progress bar & initial build mechanism

---
 go.mod           |  9 ++++--
 go.sum           | 25 ++++++++++++++--
 lib/core/core.go | 78 +++++++++++++++++++++++++++++++++++++++++++-----
 src/main.go      |  2 +-
 4 files changed, 101 insertions(+), 13 deletions(-)

diff --git a/go.mod b/go.mod
index 8fad0e4..e4c0fe5 100644
--- a/go.mod
+++ b/go.mod
@@ -6,12 +6,17 @@ require (
 	github.com/briandowns/spinner v1.19.0
 	github.com/cavaliergopher/grab/v3 v3.0.1
 	github.com/gookit/color v1.5.2
+	github.com/schollz/progressbar/v3 v3.12.1
 )
 
 require (
 	github.com/fatih/color v1.10.0 // indirect
 	github.com/mattn/go-colorable v0.1.8 // indirect
-	github.com/mattn/go-isatty v0.0.12 // indirect
+	github.com/mattn/go-isatty v0.0.16 // indirect
+	github.com/mattn/go-runewidth v0.0.14 // indirect
+	github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
+	github.com/rivo/uniseg v0.4.3 // indirect
 	github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
-	golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
+	golang.org/x/sys v0.2.0 // indirect
+	golang.org/x/term v0.2.0 // indirect
 )
diff --git a/go.sum b/go.sum
index d7686fb..3022182 100644
--- a/go.sum
+++ b/go.sum
@@ -10,16 +10,29 @@ github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
 github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
 github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
 github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
+github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
 github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
+github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
+github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
+github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/schollz/progressbar/v3 v3.12.1 h1:JAhtIrLWAn6/p7i82SrpSG3fgAwlAxi+Sy12r4AzBvQ=
+github.com/schollz/progressbar/v3 v3.12.1/go.mod h1:g7QSuwyGpqCjVQPFZXA31MSxtrhka9Y9LMdF+XT77/Y=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -29,8 +42,14 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
-golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
diff --git a/lib/core/core.go b/lib/core/core.go
index cf50bee..07d6c69 100644
--- a/lib/core/core.go
+++ b/lib/core/core.go
@@ -1,20 +1,22 @@
 package core
 
 import (
+	"bufio"
+	"encoding/json"
 	"fmt"
 	"io"
 	"net/http"
 	"os"
 	"os/exec"
+	"strconv"
 	"strings"
 	"time"
 
-	"encoding/json"
-
 	"github.com/CompeyDev/wsl-archlinux-manager/lib/checkers"
 	logger "github.com/CompeyDev/wsl-archlinux-manager/util"
 	"github.com/briandowns/spinner"
 	"github.com/cavaliergopher/grab/v3"
+	"github.com/schollz/progressbar/v3"
 )
 
 // TODO:
@@ -90,19 +92,81 @@ func Build() {
 		checkers.VerifySignature(mirror)
 	}
 
+	archiveName := fmt.Sprintf(`archlinux-bootstrap-%s-x86_64.tar.gz`, version)
+
+	untarArchive(archiveName, bar)
+
+	bar.Suffix = "  Building bootstrap package..."
+
+	bar.Start()
+
+	_d, buildErr := exec.Command("wsl.exe", "bash", "-c", "cd root.x86_64 && tar -zcvf arch_bootstrap_package.tar.gz .").CombinedOutput()
+
+	if buildErr != nil {
+		bar.Stop()
+		println(buildErr.Error())
+		println(string(_d))
+		logger.Error("Failed to build bootstrap package; fatal. Aborting installation...")
+	}
+	bar.Stop()
+	logger.Progress("Successfully built bootstrap package, proceeeding!")
+}
+
+func untarArchive(archiveName string, bar *spinner.Spinner) {
 	bar.Suffix = " Untarring archive..."
 	bar.Start()
 
-	stdoute, untarErr := exec.Command("wsl.exe", "bash", "-c", fmt.Sprintf(`tar -xzvf archlinux-bootstrap-%s-x86_64.tar.gz`, version)).CombinedOutput()
+	untarSizeCmd, sizeCmdErr := exec.Command("wsl.exe", "bash", "-c", fmt.Sprintf("tar -tzf %s | wc -l", archiveName)).CombinedOutput()
 
-	if untarErr != nil {
-		println(untarErr)
+	if sizeCmdErr != nil {
+		bar.Stop()
+		logger.Error("Failed to retrieve archive length; fatal. Refusing to continue.")
+	}
+
+	untarSizeArr := strings.Split(string(untarSizeCmd), "\n")
+	untarSizeStr := strings.Trim(untarSizeArr[len(untarSizeArr)-2], "\n\r ")
+	untarSize, convErr := strconv.ParseInt(untarSizeStr, 10, 64)
+
+	if convErr != nil {
+		bar.Stop()
+		logger.Error("An internal error occurred while attempting to untar the archive. Aborting.")
+	}
+
+	bar.Stop()
+
+	pb := progressbar.NewOptions(1000,
+		progressbar.OptionEnableColorCodes(true),
+		progressbar.OptionShowBytes(true),
+		progressbar.OptionSetPredictTime(true),
+		progressbar.OptionSetDescription("[yellow][1/3][reset] Untarring archive..."),
+		progressbar.OptionSetTheme(progressbar.Theme{
+			Saucer:        "=",
+			SaucerHead:    ">",
+			SaucerPadding: " ",
+			BarStart:      "[",
+			BarEnd:        "]",
+		}))
+
+	progressbar.DefaultBytes(untarSize)
+
+	untarCmd := exec.Command("wsl.exe", "bash", "-c", fmt.Sprintf("tar -xzvf %s", archiveName))
+
+	stdout, stdoutErr := untarCmd.StdoutPipe()
+	stderr, _ := untarCmd.StderrPipe()
+	_ = untarCmd.Start()
+
+	scanner := bufio.NewScanner(io.MultiReader(stdout, stderr))
+	scanner.Split(bufio.ScanWords)
+	for scanner.Scan() {
+		pb.Add64(1)
+	}
+	_ = untarCmd.Wait()
+
+	if stdoutErr != nil {
 		logger.Error("Failed to untar archive; this is a non-recoverable error. Quitting.")
 	}
-	println(stdoute)
 	bar.Stop()
 	logger.Info("Successfully untarred archive!")
-
 }
 
 func getMirror(country string) string {
diff --git a/src/main.go b/src/main.go
index fef0501..68f4158 100644
--- a/src/main.go
+++ b/src/main.go
@@ -18,7 +18,7 @@ import (
 
 func main() {
 	if runtime.GOOS == "windows" {
-		// checks()
+		checks()
 		core.Build()
 	} else {
 		fmt.Println("WSL is reserved for windows users only.")