From 222e4c43dad770b2ba5dbcf7de55d24c98abc3e4 Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Wed, 9 Oct 2024 12:36:22 -0700 Subject: [PATCH 01/16] started working on windows native version --- .gitignore | 3 ++- Makefile | 5 +++++ README.md | 22 +++++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6b7ce1b..405becf 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -flist \ No newline at end of file +flist +flist.exe \ No newline at end of file diff --git a/Makefile b/Makefile index 1efe5e7..a41e31c 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,11 @@ build: v -o flist . sudo ./flist install +build-win: + v fmt -w flist.v + v -o flist . + ./flist.exe install + rebuild: sudo rm flist sudo flist uninstall diff --git a/README.md b/README.md index f16a56a..63ad8be 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ - [Linux](#linux) - [macOS](#macos) - [Windows](#windows) + - [WSL](#wsl) + - [Native Windows](#native-windows) - [Troubleshooting](#troubleshooting) - [Development](#development) - [Contributing](#contributing) @@ -99,7 +101,25 @@ flist [arguments] ### Windows -For now, we recommend to use WSL and follow the Linux steps. +#### WSL + +You can use WSL with Ubuntu to deploy the Flist CLI on Windows. + +#### Native Windows + +When using the make commands, add `-win` to the commands: `make build-win`, `make rebuild-win`, `make delete-win`. + +- Run make for Windows on Powershell Admin: +``` +git clone https://git.ourworld.tf/tfgrid/flist_cli_v +cd flist_cli_v +make build-win +``` +- Run in Powershell Admin the following lines then restart the shell +``` +$newPath = 'C:\Program Files\flist' +setx PATH "$($env:PATH);$newPath" +``` ## Troubleshooting From ca543c10b7cc44641584add562001e767f3046e7 Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Wed, 9 Oct 2024 15:26:18 -0700 Subject: [PATCH 02/16] started work on install windows --- .gitignore | 3 ++- flist.v | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 405becf..0ef9f17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ flist -flist.exe \ No newline at end of file +flist.exe +test/ \ No newline at end of file diff --git a/flist.v b/flist.v index 66076e8..d81f92d 100644 --- a/flist.v +++ b/flist.v @@ -23,6 +23,60 @@ struct Response { payload Payload } +fn add_path_windows() { + // Define the new directory path to add + new_path := r'C:\Program Files\flist' + + // Get the current PATH environment variable + current_path := os.getenv('PATH') + + // Check if the new_path is already in the current PATH + if current_path.contains(new_path) { + println('The directory is already in the PATH.') + return + } + + // Construct the new PATH by appending the new_path + new_env_path := '${current_path};${new_path}' + + // Prepare the command to set the new PATH + cmd := 'setx PATH "${new_env_path}"' + + // Execute the command to update the PATH + exit_code := os.system(cmd.replace('"$', '${new_env_path}"')) + + if exit_code == 0 { + println('PATH updated successfully.') + } else { + println('Failed to update the PATH. Please try running the script as an administrator.') + } +} + +fn remove_path_windows() { + // Define the directory path to remove + path_to_remove := r'C:\Program Files\flist' + + // Get the current PATH environment variable + mut current_path := os.getenv('PATH') + + // Remove the specified path from current PATH + paths := current_path.split(';') + updated_paths := paths.filter(it != path_to_remove) // Keep only paths that are not the one we want to remove + new_env_path := updated_paths.join(';') // Join the remaining paths back into a single string + + // Prepare the command to set the new PATH + cmd := 'setx PATH "${new_env_path}"' + + // Execute the command to update the PATH + exit_code := os.system(cmd.replace('"$', '${new_env_path}"')) + + if exit_code == 0 { + println('PATH updated successfully.') + } else { + println('Failed to update the PATH. Please try running the script as an administrator.') + } +} + fn error_message(msg string) { println(term.red('\nError: ') + msg) println(term.yellow("Run 'flist help' for usage information.\n")) @@ -68,6 +122,9 @@ fn install() { os.mkdir_all(os.dir(binary_location)) or { panic(err) } os.cp(current_exe, binary_location) or { panic(err) } os.chmod(binary_location, 0o755) or { panic(err) } + if os.user_os() == 'windows' { + add_path_windows() + } success_message('Flist CLI has been installed to ' + binary_location) info_message("You can now use it by running 'flist help'") } else { @@ -84,6 +141,9 @@ fn uninstall() { } else { info_message('Flist CLI is not installed at ' + binary_location) } + // if os.user_os() == 'windows' { + // remove_path_windows() + // } } fn login() { From 25d61bc6a2d19ef6c6c09d3d2f1222826dcdf4f6 Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Wed, 9 Oct 2024 16:00:49 -0700 Subject: [PATCH 03/16] set makefile for windows, macos, linux --- Makefile | 22 ++++++++++++++++------ flist.v | 36 ++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index a41e31c..32a5b8b 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,6 @@ build: v -o flist . sudo ./flist install -build-win: - v fmt -w flist.v - v -o flist . - ./flist.exe install - rebuild: sudo rm flist sudo flist uninstall @@ -17,4 +12,19 @@ rebuild: delete: sudo rm flist - sudo flist uninstall \ No newline at end of file + sudo flist uninstall + +build-win: + v fmt -w flist.v + v -o flist . + ./flist.exe install + +rebuild-win: + ./flist.exe uninstall + v fmt -w flist.v + v -o flist . + ./flist.exe install + +delete-win: + ./flist.exe uninstall + diff --git a/flist.v b/flist.v index d81f92d..2210e1f 100644 --- a/flist.v +++ b/flist.v @@ -57,12 +57,16 @@ fn remove_path_windows() { path_to_remove := r'C:\Program Files\flist' // Get the current PATH environment variable - mut current_path := os.getenv('PATH') + current_path := os.getenv('PATH') - // Remove the specified path from current PATH - paths := current_path.split(';') - updated_paths := paths.filter(it != path_to_remove) // Keep only paths that are not the one we want to remove - new_env_path := updated_paths.join(';') // Join the remaining paths back into a single string + // Check if the path_to_remove is in the current PATH + if !current_path.contains(path_to_remove) { + println('The directory is not in the PATH.') + return + } + + // Remove specified directory from the PATH + new_env_path := current_path.split(';').filter(it != path_to_remove).join(';') // Prepare the command to set the new PATH cmd := 'setx PATH "${new_env_path}"' @@ -135,15 +139,31 @@ fn install() { fn uninstall() { info_message('Uninstalling Flist CLI...') + if os.exists(binary_location) { + // Remove the binary file os.rm(binary_location) or { panic(err) } success_message('Flist CLI has been removed from ' + binary_location) + + // Get the directory of the binary + parent_dir := os.dir(binary_location) + + // Check if the parent directory is empty + if os.is_dir_empty(parent_dir) { + // Remove the parent directory + os.rmdir(parent_dir) or { panic(err) } + success_message('The directory ' + parent_dir + ' has been removed as it is empty.') + } else { + info_message('The directory ' + parent_dir + ' is not empty, so it was not removed.') + } } else { info_message('Flist CLI is not installed at ' + binary_location) } - // if os.user_os() == 'windows' { - // remove_path_windows() - // } + + // Uncomment the following block if you want to remove from PATH for Windows. + // if os.user_os() == 'windows' { + // remove_path_windows() + // } } fn login() { From 4ea5bf3c7b3394c15b912d311e1e9f5426ae5442 Mon Sep 17 00:00:00 2001 From: mik-tf Date: Wed, 9 Oct 2024 19:48:55 -0400 Subject: [PATCH 04/16] added shortcut if windows --- flist.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/flist.v b/flist.v index 2210e1f..524afda 100644 --- a/flist.v +++ b/flist.v @@ -5,7 +5,7 @@ import json import x.json2 const token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') -const binary_location = if os.user_os() == 'windows' { +const binary_location = $if windows { 'C:\\Program Files\\flist\\flist.exe' } else { '/usr/local/bin/flist' @@ -126,7 +126,7 @@ fn install() { os.mkdir_all(os.dir(binary_location)) or { panic(err) } os.cp(current_exe, binary_location) or { panic(err) } os.chmod(binary_location, 0o755) or { panic(err) } - if os.user_os() == 'windows' { + $if windows { add_path_windows() } success_message('Flist CLI has been installed to ' + binary_location) From 2652b3583490f00e185c7cee3bab0b30daab0c8d Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Wed, 9 Oct 2024 16:55:18 -0700 Subject: [PATCH 05/16] fixed help for windows --- flist.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flist.v b/flist.v index 524afda..4362aec 100644 --- a/flist.v +++ b/flist.v @@ -7,7 +7,7 @@ import x.json2 const token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') const binary_location = $if windows { 'C:\\Program Files\\flist\\flist.exe' -} else { +} $else { '/usr/local/bin/flist' } From f6f52c46f3f355c0709acf99cece364535d91dfc Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Thu, 10 Oct 2024 05:15:33 -0700 Subject: [PATCH 06/16] updated make for windows, simplified globally, set cyan for color instead of blue --- Makefile | 5 +---- flist.v | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 32a5b8b..130875c 100644 --- a/Makefile +++ b/Makefile @@ -4,14 +4,12 @@ build: sudo ./flist install rebuild: - sudo rm flist sudo flist uninstall v fmt -w flist.v v -o flist . sudo ./flist install delete: - sudo rm flist sudo flist uninstall build-win: @@ -26,5 +24,4 @@ rebuild-win: ./flist.exe install delete-win: - ./flist.exe uninstall - + ./flist.exe uninstall \ No newline at end of file diff --git a/flist.v b/flist.v index 4362aec..a887571 100644 --- a/flist.v +++ b/flist.v @@ -91,7 +91,7 @@ fn success_message(msg string) { } fn info_message(msg string) { - println(term.blue('\n' + msg + '\n')) + println(term.cyan('\n' + msg + '\n')) } fn create_box(content []string, padding int) string { From 3eb53a4b3b33cf0fd1d138f241b9858b5df0ec7f Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Thu, 10 Oct 2024 05:56:21 -0700 Subject: [PATCH 07/16] windows version working function now are ls ls url login logout rename delete, todo: push --- flist.v | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/flist.v b/flist.v index a887571..1cec0f5 100644 --- a/flist.v +++ b/flist.v @@ -5,6 +5,7 @@ import json import x.json2 const token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') +const token_dir = os.join_path(os.home_dir(), '.config') const binary_location = $if windows { 'C:\\Program Files\\flist\\flist.exe' } $else { @@ -105,17 +106,17 @@ fn create_box(content []string, padding int) string { max_width += padding * 2 separator := '━'.repeat(max_width + 2) // +2 for left and right borders - mut box_content := term.blue('┏${separator}┓') + '\n' + mut box_content := term.cyan('┏${separator}┓') + '\n' for line in content { clean_line := term.strip_ansi(line) padding_left := ' '.repeat(padding) padding_right := ' '.repeat(max_width - clean_line.len) - box_content += term.blue('┃') + padding_left + line + padding_right + term.blue('┃') + + box_content += term.cyan('┃') + padding_left + line + padding_right + term.cyan('┃') + '\n' } - box_content += term.blue('┗${separator}┛') + box_content += term.cyan('┗${separator}┛') return box_content } @@ -170,6 +171,9 @@ fn login() { mut token_exists := os.exists(token_file) if !token_exists { + $if windows { + os.mkdir_all(token_dir) or { panic(err) } + } tfhub_token := os.input('Please enter your tfhub token: ') os.write_file(token_file, tfhub_token) or { panic(err) } success_message('Token saved in ' + token_file) @@ -177,7 +181,7 @@ fn login() { info_message('Your Flist Hub token is already saved.') } - result := os.system('sudo docker login') + result := $if windows { os.system('docker login') } $else { os.system('sudo docker login') } if result == 0 { info_message('\nYou are already logged in to Docker.') @@ -194,7 +198,7 @@ fn logout() { info_message('Your Flist Hub Token was already not present.') } - exit_code := os.system('sudo docker logout') + exit_code := $if windows { os.system('docker logout') } $else { os.system('sudo docker logout') } if exit_code != 0 { error_message('Failed to log out from Docker Hub.') } @@ -490,17 +494,17 @@ fn help() { println('This tool turns Dockerfiles and Docker images directly into Flists on the TF Flist Hub, passing by the Docker Hub.\n') println(term.bold('Available commands:')) - println(term.blue(' install ') + '- Install the Flist CLI') - println(term.blue(' uninstall ') + '- Uninstall the Flist CLI') - println(term.blue(' login ') + '- Log in to Docker Hub and save the Flist Hub token') - println(term.blue(' logout ') + '- Log out of Docker Hub and remove the Flist Hub token') - println(term.blue(' push ') + + println(term.cyan(' install ') + '- Install the Flist CLI') + println(term.cyan(' uninstall ') + '- Uninstall the Flist CLI') + println(term.cyan(' login ') + '- Log in to Docker Hub and save the Flist Hub token') + println(term.cyan(' logout ') + '- Log out of Docker Hub and remove the Flist Hub token') + println(term.cyan(' push ') + '- Build and push a Docker image to Docker Hub, then convert and push it as an Flist to Flist Hub') - println(term.blue(' delete ') + '- Delete an Flist from Flist Hub') - println(term.blue(' rename ') + '- Rename an Flist in Flist Hub') - println(term.blue(' ls ') + '- List all Flists of the current user') - println(term.blue(' ls url ') + '- List all Flists of the current user with full URLs') - println(term.blue(' help ') + '- Display this help message\n') + println(term.cyan(' delete ') + '- Delete an Flist from Flist Hub') + println(term.cyan(' rename ') + '- Rename an Flist in Flist Hub') + println(term.cyan(' ls ') + '- List all Flists of the current user') + println(term.cyan(' ls url ') + '- List all Flists of the current user with full URLs') + println(term.cyan(' help ') + '- Display this help message\n') println(term.bold('Usage:')) println(term.yellow(' sudo ./flist install')) println(term.yellow(' sudo flist uninstall')) From 6f4c146ec08a25706d1fc464ff83496c2e7d324f Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Thu, 10 Oct 2024 05:59:46 -0700 Subject: [PATCH 08/16] set help fn with windows specific --- flist.v | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/flist.v b/flist.v index 1cec0f5..c5669cb 100644 --- a/flist.v +++ b/flist.v @@ -494,8 +494,10 @@ fn help() { println('This tool turns Dockerfiles and Docker images directly into Flists on the TF Flist Hub, passing by the Docker Hub.\n') println(term.bold('Available commands:')) - println(term.cyan(' install ') + '- Install the Flist CLI') - println(term.cyan(' uninstall ') + '- Uninstall the Flist CLI') + $if !windows { + println(term.cyan(' install ') + '- Install the Flist CLI') + println(term.cyan(' uninstall ') + '- Uninstall the Flist CLI') + } println(term.cyan(' login ') + '- Log in to Docker Hub and save the Flist Hub token') println(term.cyan(' logout ') + '- Log out of Docker Hub and remove the Flist Hub token') println(term.cyan(' push ') + @@ -506,8 +508,10 @@ fn help() { println(term.cyan(' ls url ') + '- List all Flists of the current user with full URLs') println(term.cyan(' help ') + '- Display this help message\n') println(term.bold('Usage:')) - println(term.yellow(' sudo ./flist install')) - println(term.yellow(' sudo flist uninstall')) + $if !windows { + println(term.yellow(' sudo ./flist install')) + println(term.yellow(' sudo flist uninstall')) + } println(term.yellow(' flist login')) println(term.yellow(' flist logout')) println(term.yellow(' flist push :')) From 9d9b92c14d4e803bd7d4ac78f01f702f34a80e7a Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Thu, 10 Oct 2024 06:06:23 -0700 Subject: [PATCH 09/16] set docker cmd for windows or not --- flist.v | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/flist.v b/flist.v index c5669cb..72f8c3e 100644 --- a/flist.v +++ b/flist.v @@ -11,6 +11,11 @@ const binary_location = $if windows { } $else { '/usr/local/bin/flist' } +const docker_cmd = $if windows { + 'docker' +} $else { + 'sudo docker' +} struct FlistItem { name string @@ -181,7 +186,7 @@ fn login() { info_message('Your Flist Hub token is already saved.') } - result := $if windows { os.system('docker login') } $else { os.system('sudo docker login') } + result := os.system('${docker_cmd} login') if result == 0 { info_message('\nYou are already logged in to Docker.') @@ -198,7 +203,7 @@ fn logout() { info_message('Your Flist Hub Token was already not present.') } - exit_code := $if windows { os.system('docker logout') } $else { os.system('sudo docker logout') } + exit_code := os.system('${docker_cmd} logout') if exit_code != 0 { error_message('Failed to log out from Docker Hub.') } @@ -222,7 +227,7 @@ fn get_docker_credential() !string { fn get_docker_credential_auto() !string { // First, try to get the Docker username using the system info command - system_info_result := os.execute("sudo docker system info | grep 'Username' | cut -d ' ' -f 3") + system_info_result := os.execute("${docker_cmd} system info | grep 'Username' | cut -d ' ' -f 3") if system_info_result.exit_code == 0 && system_info_result.output.trim_space() != '' { return system_info_result.output.trim_space() } @@ -282,13 +287,13 @@ fn push(tag string) { } info_message('Starting Docker build') - if os.system('sudo docker buildx build -t ${full_tag} .') != 0 { + if os.system('${docker_cmd} buildx build -t ${full_tag} .') != 0 { error_message('Docker build failed') exit(1) } info_message('Finished local Docker build, now pushing to Docker Hub') - if os.system('sudo docker push ${full_tag}') != 0 { + if os.system('${docker_cmd} push ${full_tag}') != 0 { error_message('Docker push failed') exit(1) } From a39c06233924c29c3617f96a97e4435bb8905e35 Mon Sep 17 00:00:00 2001 From: Mik-TF Date: Thu, 10 Oct 2024 06:29:22 -0700 Subject: [PATCH 10/16] added os specific info for help --- flist.v | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/flist.v b/flist.v index 72f8c3e..5c80d18 100644 --- a/flist.v +++ b/flist.v @@ -16,6 +16,13 @@ const docker_cmd = $if windows { } $else { 'sudo docker' } +const info_msg = $if windows { + 'Note: Make sure to use an admin PowerShell. Docker Desktop must be running to use the push function.\n' +} $else $if linux { + 'Note: Docker Engine must be running to use the push function.\n' +} $else $if macos { + 'Note: Docker desktop must be running to use the push function.\n' +} struct FlistItem { name string @@ -136,7 +143,7 @@ fn install() { add_path_windows() } success_message('Flist CLI has been installed to ' + binary_location) - info_message("You can now use it by running 'flist help'") + info_message("Run 'flist help' to see all commands.") } else { error_message('Cannot find the executable file') exit(1) @@ -498,6 +505,7 @@ fn help() { println(create_box([welcome_msg], 2)) println('This tool turns Dockerfiles and Docker images directly into Flists on the TF Flist Hub, passing by the Docker Hub.\n') + println(term.cyan(info_msg)) println(term.bold('Available commands:')) $if !windows { println(term.cyan(' install ') + '- Install the Flist CLI') From 6d0781cdc4fa9b33e42b2e4e0a02011dab9b6e1d Mon Sep 17 00:00:00 2001 From: mik-tf Date: Thu, 10 Oct 2024 09:57:15 -0400 Subject: [PATCH 11/16] fixed mac specific error --- flist.v | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/flist.v b/flist.v index 5c80d18..7cc0173 100644 --- a/flist.v +++ b/flist.v @@ -5,23 +5,27 @@ import json import x.json2 const token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') + const token_dir = os.join_path(os.home_dir(), '.config') + const binary_location = $if windows { 'C:\\Program Files\\flist\\flist.exe' } $else { '/usr/local/bin/flist' } + const docker_cmd = $if windows { 'docker' } $else { 'sudo docker' } + const info_msg = $if windows { 'Note: Make sure to use an admin PowerShell. Docker Desktop must be running to use the push function.\n' } $else $if linux { 'Note: Docker Engine must be running to use the push function.\n' } $else $if macos { - 'Note: Docker desktop must be running to use the push function.\n' + 'Note: Docker Desktop must be running to use the push function.\n' } struct FlistItem { @@ -157,18 +161,6 @@ fn uninstall() { // Remove the binary file os.rm(binary_location) or { panic(err) } success_message('Flist CLI has been removed from ' + binary_location) - - // Get the directory of the binary - parent_dir := os.dir(binary_location) - - // Check if the parent directory is empty - if os.is_dir_empty(parent_dir) { - // Remove the parent directory - os.rmdir(parent_dir) or { panic(err) } - success_message('The directory ' + parent_dir + ' has been removed as it is empty.') - } else { - info_message('The directory ' + parent_dir + ' is not empty, so it was not removed.') - } } else { info_message('Flist CLI is not installed at ' + binary_location) } @@ -521,9 +513,12 @@ fn help() { println(term.cyan(' ls url ') + '- List all Flists of the current user with full URLs') println(term.cyan(' help ') + '- Display this help message\n') println(term.bold('Usage:')) - $if !windows { + $if linux { println(term.yellow(' sudo ./flist install')) println(term.yellow(' sudo flist uninstall')) + } $else $if macos { + println(term.yellow(' sudo ./flist install')) + println(term.yellow(' flist uninstall')) } println(term.yellow(' flist login')) println(term.yellow(' flist logout')) From b7f793c8d15892673138c33e65d864d0fa0b4ca2 Mon Sep 17 00:00:00 2001 From: mik-tf Date: Thu, 10 Oct 2024 10:42:44 -0400 Subject: [PATCH 12/16] finalized readme for win mac linux --- README.md | 94 +++++++++++++++++++++++++------------------------------ 1 file changed, 42 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 63ad8be..ab99d23 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,10 @@ - [Building and Installing](#building-and-installing) - [Rebuild and Uninstall](#rebuild-and-uninstall) - [Usage](#usage) -- [Commands](#commands) - [OS-Specific Instructions](#os-specific-instructions) - [Linux](#linux) - [macOS](#macos) - [Windows](#windows) - - [WSL](#wsl) - - [Native Windows](#native-windows) - [Troubleshooting](#troubleshooting) - [Development](#development) - [Contributing](#contributing) @@ -31,34 +28,52 @@ Flist CLI is a tool that turns Dockerfiles and Docker images directly into Flist ### Prerequisites - [V programming language](https://vlang.io/) (latest version) installed on your system -- Docker installed and running +- Docker Engine installed and running (Linux) +- Docker Desktop installed and running (MacOS+Windows) - Docker Hub account - TF Hub account and token ### Building and Installing -Clone this repository, build the project, and install the CLI: -``` -git clone https://git.ourworld.tf/tfgrid/flist_cli_v -cd flist_cli_v -make build -``` +- To clone this repository, build the project, and install the CLI: + - MacOS and Linux + ``` + git clone https://git.ourworld.tf/tfgrid/flist_cli_v + cd flist_cli_v + make build + ``` + - Windows + ``` + git clone https://git.ourworld.tf/tfgrid/flist_cli_v + cd flist_cli_v + make build-win + ``` -This will build the `flist` executable and install it to the appropriate system location. +This will build the executable and install it to the appropriate system location. ### Rebuild and Uninstall You can use the following Makefile commands: - To rebuild and reinstall: - ``` - make rebuild - ``` + - MacOS and Linux + ``` + make rebuild + ``` + - Windows + ``` + make rebuild-win + ``` - To uninstall and remove the binary: - ``` - make delete - ``` + - MacOS and Linux + ``` + make delete + ``` + - Windows + ``` + make delete-win + ``` ## Usage @@ -68,24 +83,13 @@ After installation, you can use the `flist` command followed by various subcomma flist [arguments] ``` -## Commands - -- `install`: Install the Flist CLI -- `uninstall`: Uninstall the Flist CLI -- `login`: Log in to Docker Hub and save the Flist Hub token -- `logout`: Log out of Docker Hub and remove the Flist Hub token -- `push :`: Build and push a Docker image, then convert and push it as an flist -- `delete `: Delete an flist from Flist Hub -- `rename `: Rename an flist in Flist Hub -- `ls`: List all flists of the current user -- `ls url`: List all flists of the current user with full URLs -- `help`: Display help information +Run `flist` or `flist help` to see all available commands for your specific OS. ## OS-Specific Instructions ### Linux -1. Ensure Docker is installed and the Docker daemon is running. +1. Ensure Docker Engine is installed and running. 2. The `flist` executable will be installed to: ``` /usr/local/bin/flist @@ -101,39 +105,25 @@ flist [arguments] ### Windows -#### WSL - -You can use WSL with Ubuntu to deploy the Flist CLI on Windows. - -#### Native Windows - -When using the make commands, add `-win` to the commands: `make build-win`, `make rebuild-win`, `make delete-win`. - -- Run make for Windows on Powershell Admin: -``` -git clone https://git.ourworld.tf/tfgrid/flist_cli_v -cd flist_cli_v -make build-win -``` -- Run in Powershell Admin the following lines then restart the shell -``` -$newPath = 'C:\Program Files\flist' -setx PATH "$($env:PATH);$newPath" -``` +1. Ensure Docker Desktop is installed and running. +2. Run the program and installer in an admin PowerShell. +3. The `flist.exe` executable will be installed to: + ``` + C:\\Program Files\\flist\\flist.exe + ``` ## Troubleshooting - If you encounter permission issues, ensure you're running the command with appropriate privileges (e.g., as administrator on Windows or with `sudo` on Unix-like systems). -- Make sure Docker is running before using Flist CLI commands. - If you face issues with Docker commands, try logging out and logging back in to refresh your Docker credentials. -- If you encounter compilation errors, ensure you have the latest version of V installed. +- If you encounter compilation errors, ensure you have the latest version of V installed. To update v, run `v up`. ## Development To modify the Flist CLI: 1. Make your changes to the `flist.v` file. -2. Rebuild the project using `make rebuild` +2. Rebuild the project using using the appropriate Make command. 3. Test your changes thoroughly across different operating systems if possible. ## Contributing From 7a5449c7183cc7eb5ef26353673cdc1eb530a075 Mon Sep 17 00:00:00 2001 From: mik-tf Date: Fri, 11 Oct 2024 00:01:42 -0400 Subject: [PATCH 13/16] testing macos --- flist.v | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/flist.v b/flist.v index 7cc0173..644c5a8 100644 --- a/flist.v +++ b/flist.v @@ -5,8 +5,8 @@ import json import x.json2 const token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') - -const token_dir = os.join_path(os.home_dir(), '.config') +const docker_username_file = os.join_path(os.home_dir(), '.config', 'dockerusername') +const config_dir = os.join_path(os.home_dir(), '.config') const binary_location = $if windows { 'C:\\Program Files\\flist\\flist.exe' @@ -176,7 +176,7 @@ fn login() { if !token_exists { $if windows { - os.mkdir_all(token_dir) or { panic(err) } + os.mkdir_all(config_dir) or { panic(err) } } tfhub_token := os.input('Please enter your tfhub token: ') os.write_file(token_file, tfhub_token) or { panic(err) } @@ -185,7 +185,20 @@ fn login() { info_message('Your Flist Hub token is already saved.') } - result := os.system('${docker_cmd} login') + mut result := 0 + + $if macos { + mut dockername_exists := os.exists(docker_username_file) + + if !dockername_exists { + docker_username := os.input('Please enter your Docker username: ') + os.write_file(docker_username_file, docker_username) or { panic(err) } + success_message('Docker username saved in ' + docker_username_file) + result = os.system('${docker_cmd} login -u ${docker_username}') + } + } $else { + result = os.system('${docker_cmd} login') + } if result == 0 { info_message('\nYou are already logged in to Docker.') @@ -202,6 +215,13 @@ fn logout() { info_message('Your Flist Hub Token was already not present.') } + if os.exists(docker_username_file) { + os.rm(docker_username_file) or { panic(err) } + success_message('Your Docker username has been removed from the config folder.') + } else { + info_message('Your Docker username was already not present in the config folder.') + } + exit_code := os.system('${docker_cmd} logout') if exit_code != 0 { error_message('Failed to log out from Docker Hub.') @@ -271,9 +291,17 @@ fn get_docker_credential_auto() !string { } fn push(tag string) { - docker_user := get_docker_credential() or { - error_message('Failed to get Docker username: ${err}') - exit(1) + mut docker_user := '' + $if macos { + docker_user = os.read_file(docker_username_file) or { + error_message("No Docker username found. Please run 'flist login' first.") + exit(1) + } + } $else { + docker_user = get_docker_credential() or { + error_message('Failed to get Docker username: ${err}') + exit(1) + } } info_message('Docker username: ${docker_user}') From e7d572f50ec5c965f58e549f7953e1a1b9331da8 Mon Sep 17 00:00:00 2001 From: mik-tf Date: Fri, 11 Oct 2024 00:21:14 -0400 Subject: [PATCH 14/16] fixed macos version --- flist.v | 1 + 1 file changed, 1 insertion(+) diff --git a/flist.v b/flist.v index 644c5a8..31b1010 100644 --- a/flist.v +++ b/flist.v @@ -194,6 +194,7 @@ fn login() { docker_username := os.input('Please enter your Docker username: ') os.write_file(docker_username_file, docker_username) or { panic(err) } success_message('Docker username saved in ' + docker_username_file) + info_message('Enter your Docker password.') result = os.system('${docker_cmd} login -u ${docker_username}') } } $else { From 7304271e22537077739c094aa68e73ea47ce27a1 Mon Sep 17 00:00:00 2001 From: mik-tf Date: Fri, 11 Oct 2024 00:37:37 -0400 Subject: [PATCH 15/16] macos v flist fixes --- flist.v | 146 ++++++++++++++------------------------------------------ 1 file changed, 35 insertions(+), 111 deletions(-) diff --git a/flist.v b/flist.v index 31b1010..e1d81fa 100644 --- a/flist.v +++ b/flist.v @@ -2,7 +2,6 @@ import os import net.http import term import json -import x.json2 const token_file = os.join_path(os.home_dir(), '.config', 'tfhubtoken') const docker_username_file = os.join_path(os.home_dir(), '.config', 'dockerusername') @@ -173,32 +172,25 @@ fn uninstall() { fn login() { mut token_exists := os.exists(token_file) - + os.mkdir_all(config_dir) or { panic(err) } if !token_exists { - $if windows { - os.mkdir_all(config_dir) or { panic(err) } - } tfhub_token := os.input('Please enter your tfhub token: ') os.write_file(token_file, tfhub_token) or { panic(err) } - success_message('Token saved in ' + token_file) + success_message('TF Hub token saved in ' + token_file) } else { - info_message('Your Flist Hub token is already saved.') + info_message('Your TF Hub token is already saved.') } mut result := 0 - $if macos { - mut dockername_exists := os.exists(docker_username_file) + mut dockername_exists := os.exists(docker_username_file) - if !dockername_exists { - docker_username := os.input('Please enter your Docker username: ') - os.write_file(docker_username_file, docker_username) or { panic(err) } - success_message('Docker username saved in ' + docker_username_file) - info_message('Enter your Docker password.') - result = os.system('${docker_cmd} login -u ${docker_username}') - } - } $else { - result = os.system('${docker_cmd} login') + if !dockername_exists { + docker_username := os.input('Please enter your Docker username: ') + os.write_file(docker_username_file, docker_username) or { panic(err) } + success_message('Docker username saved in ' + docker_username_file) + info_message('Enter your Docker password.') + result = os.system('${docker_cmd} login -u ${docker_username}') } if result == 0 { @@ -211,9 +203,9 @@ fn login() { fn logout() { if os.exists(token_file) { os.rm(token_file) or { panic(err) } - success_message('Your Flist Hub Token has been removed') + success_message('Your TF Hub token has been removed') } else { - info_message('Your Flist Hub Token was already not present.') + info_message('Your TF Hub token was already not present.') } if os.exists(docker_username_file) { @@ -228,81 +220,13 @@ fn logout() { error_message('Failed to log out from Docker Hub.') } - success_message('You are now logged out of Docker Hub and your Flist Hub token has been removed.') -} - -fn get_docker_credential() !string { - // Try to get the Docker credential automatically - credential := get_docker_credential_auto() or { - // If automatic retrieval fails, prompt the user for input - println(term.yellow("\nCouldn't find your Docker username automatically.")) - username := os.input('Please enter your Docker username and press ENTER: ') - if username.trim_space() == '' { - return error('No Docker username provided') - } - return username.trim_space() - } - return credential -} - -fn get_docker_credential_auto() !string { - // First, try to get the Docker username using the system info command - system_info_result := os.execute("${docker_cmd} system info | grep 'Username' | cut -d ' ' -f 3") - if system_info_result.exit_code == 0 && system_info_result.output.trim_space() != '' { - return system_info_result.output.trim_space() - } - - // If the above method fails, proceed with the current method - // Read the Docker config file - config_path := os.join_path(os.home_dir(), '.docker', 'config.json') - config_content := os.read_file(config_path) or { - return error('Failed to read Docker config file: ${err}') - } - - // Parse the JSON content - config := json2.raw_decode(config_content) or { - return error('Failed to parse Docker config: ${err}') - } - - // Extract the credsStore value - creds_store := config.as_map()['credsStore'] or { - return error('credsStore not found in Docker config') - }.str() - - // Execute the docker-credential command - cred_helper := 'docker-credential-${creds_store}' - cred_output := os.execute('${cred_helper} list') - if cred_output.exit_code != 0 { - return error('Failed to execute ${cred_helper}: ${cred_output.output}') - } - - // Parse the credential list - cred_list := json2.raw_decode(cred_output.output) or { - return error('Failed to parse credential list: ${err}') - } - - // Find the first docker.io entry - for key, value in cred_list.as_map() { - if key.contains('docker.io') { - return value.str() - } - } - - return error('No docker.io credential found') + success_message('You are now logged out of Docker Hub and your TF Hub token has been removed.') } fn push(tag string) { - mut docker_user := '' - $if macos { - docker_user = os.read_file(docker_username_file) or { - error_message("No Docker username found. Please run 'flist login' first.") - exit(1) - } - } $else { - docker_user = get_docker_credential() or { - error_message('Failed to get Docker username: ${err}') - exit(1) - } + docker_user := os.read_file(docker_username_file) or { + error_message("No Docker username found. Please run 'flist login' first.") + exit(1) } info_message('Docker username: ${docker_user}') @@ -310,7 +234,7 @@ fn push(tag string) { full_tag := '${docker_user}/${tag}' tfhub_token := os.read_file(token_file) or { - error_message("No token found. Please run 'flist login' first.") + error_message("No TF Hub token found. Please run 'flist login' first.") exit(1) } @@ -353,7 +277,7 @@ fn push(tag string) { if response.status_code == 200 { hub_user := get_hub_username(tfhub_token) or { - error_message('Failed to get hub username') + error_message('Failed to get TF Hub username') exit(1) } @@ -371,9 +295,9 @@ fn push(tag string) { '', 'You can access your Flist using the URL above.', 'To manage your Flists, use the following commands:', - term.yellow(' flist ls ') + '- List all your Flists', - term.yellow(' flist delete') + '- Delete an Flist', - term.yellow(' flist rename') + '- Rename an Flist', + term.yellow(' flist ls ') + ' - List all your Flists', + term.yellow(' flist delete') + ' - Delete an Flist', + term.yellow(' flist rename') + ' - Rename an Flist', ] println(create_box(success_content, 2)) @@ -387,7 +311,7 @@ fn push(tag string) { fn delete(flist_name string) { tfhub_token := os.read_file(token_file) or { - error_message("No token found. Please run 'flist login' first.") + error_message("No TF Hub token found. Please run 'flist login' first.") exit(1) } @@ -413,7 +337,7 @@ fn delete(flist_name string) { fn rename(flist_name string, new_flist_name string) { tfhub_token := os.read_file(token_file) or { - error_message("No token found. Please run 'flist login' first.") + error_message("No TF Hub token found. Please run 'flist login' first.") exit(1) } @@ -474,7 +398,7 @@ fn get_hub_username(tfhub_token string) ?string { fn ls(show_url bool) { tfhub_token := os.read_file(token_file) or { - error_message("No token found. Please run 'flist login' first.") + error_message("No TF Hub token found. Please run 'flist login' first.") exit(1) } @@ -529,18 +453,18 @@ fn help() { println(term.cyan(info_msg)) println(term.bold('Available commands:')) $if !windows { - println(term.cyan(' install ') + '- Install the Flist CLI') - println(term.cyan(' uninstall ') + '- Uninstall the Flist CLI') + println(term.cyan(' install ') + ' - Install the Flist CLI') + println(term.cyan(' uninstall') + ' - Uninstall the Flist CLI') } - println(term.cyan(' login ') + '- Log in to Docker Hub and save the Flist Hub token') - println(term.cyan(' logout ') + '- Log out of Docker Hub and remove the Flist Hub token') - println(term.cyan(' push ') + - '- Build and push a Docker image to Docker Hub, then convert and push it as an Flist to Flist Hub') - println(term.cyan(' delete ') + '- Delete an Flist from Flist Hub') - println(term.cyan(' rename ') + '- Rename an Flist in Flist Hub') - println(term.cyan(' ls ') + '- List all Flists of the current user') - println(term.cyan(' ls url ') + '- List all Flists of the current user with full URLs') - println(term.cyan(' help ') + '- Display this help message\n') + println(term.cyan(' login ') + ' - Log in to Docker Hub and save the Flist Hub token') + println(term.cyan(' logout ') + ' - Log out of Docker Hub and remove the Flist Hub token') + println(term.cyan(' push ') + + ' - Build and push a Docker image to Docker Hub, then convert and push it as an Flist to Flist Hub') + println(term.cyan(' delete ') + ' - Delete an Flist from Flist Hub') + println(term.cyan(' rename ') + ' - Rename an Flist in Flist Hub') + println(term.cyan(' ls ') + ' - List all Flists of the current user') + println(term.cyan(' ls url ') + ' - List all Flists of the current user with full URLs') + println(term.cyan(' help ') + ' - Display this help message\n') println(term.bold('Usage:')) $if linux { println(term.yellow(' sudo ./flist install')) From 1d97660e8e96c419ded4a0b172374a5e7a2de9df Mon Sep 17 00:00:00 2001 From: mik-tf Date: Fri, 11 Oct 2024 00:42:04 -0400 Subject: [PATCH 16/16] fixed typo in msg --- flist.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flist.v b/flist.v index e1d81fa..5ffe45c 100644 --- a/flist.v +++ b/flist.v @@ -174,7 +174,7 @@ fn login() { mut token_exists := os.exists(token_file) os.mkdir_all(config_dir) or { panic(err) } if !token_exists { - tfhub_token := os.input('Please enter your tfhub token: ') + tfhub_token := os.input('Please enter your TF Hub token: ') os.write_file(token_file, tfhub_token) or { panic(err) } success_message('TF Hub token saved in ' + token_file) } else {