-
Notifications
You must be signed in to change notification settings - Fork 1
CLI Skeleton Preview #68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
WarrickT
wants to merge
11
commits into
main
Choose a base branch
from
oliver_warrick_cli_skeleton
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
ae74bfd
set up kong and got initial file structure and "mist help" working
olliekm 1346eaa
added job status command
olliekm c2a0448
Added some logic and files for login and auth.
olliekm 5b14b8b
Added initial logic for submitting job
olliekm 349c106
added user input to auth login
olliekm 1e761de
Added config and cancel jobs
WarrickT 932d8e8
Added config unit tests
WarrickT 66c3e22
Some unit testing done
WarrickT d1a34f9
Added job_status unit test + Made invalid response consistent with jo…
olliekm 950ee60
Added job status test and job submit test (Not completely done)
WarrickT a285320
Finished testing for submit, cancel, and list
WarrickT File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package cmd | ||
|
||
type AuthCmd struct { | ||
Login LoginCmd `cmd:"" help:"Log in to your account"` | ||
// Logout LogoutCmd `cmd:"" help:"Log out of your account"` | ||
// Status AuthStatusCmd `cmd:"" help:"Check your authentication status" default:1` | ||
} | ||
|
||
func (a *AuthCmd) Run() error { | ||
// Possible fallback if no subcommand is provided | ||
// fmt.Println("(auth root) – try 'mist auth login|logout|status' or mist help") | ||
return nil | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will need to chat about how auth is implemented There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package cmd | ||
|
||
import ( | ||
"bufio" | ||
"errors" | ||
"fmt" | ||
"os" | ||
"strings" | ||
) | ||
|
||
// TODO: What credentials are we taking? | ||
type LoginCmd struct { | ||
} | ||
|
||
func verifyUser(username, password string) error { | ||
// Placeholder for actual authentication logic | ||
if username == "admin" && password == "password" { | ||
return nil | ||
} | ||
return errors.New("invalid credentials") | ||
} | ||
|
||
// TODO: Figure out how to handle password input without exposing it in the terminal historyn (go get golang.org/x/term) | ||
// TODO: Where are we storing auth token? Are we getting JWT? | ||
|
||
func (l *LoginCmd) Run() error { | ||
// mist auth login | ||
|
||
fmt.Print("Username: ") | ||
|
||
reader := bufio.NewReader(os.Stdin) | ||
username, _ := reader.ReadString('\n') | ||
username = strings.TrimSpace(strings.ToLower(username)) | ||
|
||
fmt.Print("Password: ") | ||
password, _ := reader.ReadString('\n') | ||
password = strings.TrimSpace(strings.ToLower(password)) | ||
err := verifyUser(username, password) | ||
if err != nil { | ||
fmt.Println("Error during authentication:", err) | ||
} | ||
|
||
fmt.Println("Logging in with username:", username) | ||
|
||
return nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package cmd | ||
|
||
import "fmt" | ||
|
||
|
||
// Config flags | ||
type ConfigCmd struct{ | ||
DefaultCluster string `help:"Set the default compute cluster." optional: ""` | ||
Show bool `help:"Show current configuration."` | ||
|
||
} | ||
|
||
func (h *ConfigCmd) Run() error { | ||
// Some dummy config; Call API or something | ||
defaultConfig := map[string]string{ | ||
"defaultCluster": "AMD-cluster-1", | ||
"region": "us-east", | ||
} | ||
|
||
if h.Show && h.DefaultCluster!= "" { | ||
fmt.Printf("Cannot use --show and --default-cluster together") | ||
return nil | ||
} | ||
|
||
if h.DefaultCluster != "" { | ||
// This is not actually set. | ||
fmt.Printf("Setting default cluster to: %s\n", h.DefaultCluster) | ||
return nil | ||
} | ||
|
||
if h.Show { | ||
fmt.Println("Current configuration: ") | ||
for key, value := range defaultConfig { | ||
fmt.Printf(" %s: %s \n", key, value) | ||
} | ||
return nil | ||
} | ||
|
||
fmt.Println("No config action specified. Use --help for options.") | ||
|
||
return nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package cmd | ||
|
||
import ( | ||
"testing" | ||
// "fmt" | ||
// "bytes" | ||
) | ||
|
||
// No Flag config | ||
func TestConfigNoFlags(t *testing.T){ | ||
cmd := &ConfigCmd{} | ||
output := CaptureOutput(func(){ | ||
_ = cmd.Run() | ||
}) | ||
if want := "No config action specified. Use --help for options."; !contains(output, want){ | ||
t.Errorf("expected output to contain %q, got %q", want, output) | ||
} | ||
} | ||
|
||
// Set Default Cluster to tt-gpu-cluster-1 | ||
func TestConfigDefaultCluster(t *testing.T){ | ||
cmd := &ConfigCmd{DefaultCluster: "tt-gpu-cluster-1"} // Create config object | ||
|
||
output := CaptureOutput(func(){ | ||
_ = cmd.Run() | ||
}) | ||
|
||
// fmt.Printf("Captured the output: %s\n", output) | ||
|
||
if want := "Setting default cluster to: tt-gpu-cluster-1"; !contains(output, want) { | ||
t.Errorf("expected output to contain %q, got %q", want, output) | ||
} | ||
} | ||
|
||
// Show Config | ||
func TestConfigCmd_Show(t *testing.T){ | ||
cmd := &ConfigCmd{Show: true} | ||
output := CaptureOutput(func(){ | ||
_ = cmd.Run() | ||
}) | ||
|
||
if want := "Current configuration:"; !contains(output, want){ | ||
t.Errorf("expected output to contain %q, got %q", want, output) | ||
} | ||
} | ||
|
||
// Show Error message if both flags are sent | ||
func TestConfigBothFlagError(t *testing.T){ | ||
cmd := &ConfigCmd{DefaultCluster: "tt-gpu-cluster-1", Show: true} | ||
output := CaptureOutput(func(){ | ||
_ = cmd.Run() | ||
}) | ||
|
||
if want := "Cannot use --show and --default-cluster together"; !contains(output, want){ | ||
t.Errorf("Expected the error message of \"%s\", got %q", want, output) | ||
} | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cmd | ||
|
||
import "fmt" | ||
|
||
type HelpCmd struct{} | ||
|
||
func (h *HelpCmd) Run() error { | ||
fmt.Println("MIST CLI Help") | ||
fmt.Println("Usage: mist [command] [options]") | ||
fmt.Println("Commands:") | ||
fmt.Println(" auth Authentication commands") | ||
fmt.Println(" job Job management commands") | ||
fmt.Println(" config Configuration commands") | ||
fmt.Println(" help Show help information") | ||
return nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package cmd | ||
|
||
type JobCmd struct { | ||
Submit JobSubmitCmd `cmd:"" help:"Submit a new job"` | ||
Cancel JobCancelCmd `cmd:"" help:"Cancel an existing job"` | ||
// Delete JobDeleteCmd `cmd: "" help: "Delete an existing job"` | ||
Status JobStatusCmd `cmd:"" help:"Check the status of a job"` | ||
// Cancel CancelCmd `cmd:"" help:"Cancel a running job"` | ||
List ListCmd `cmd:"" help:"List all jobs" default:1` | ||
} | ||
|
||
func (j *JobCmd) Run() error { | ||
// Possible fallback if no subcommand is providFAre yed | ||
// fmt.Println("(job root) – try 'mist job submit|status|list|cancel' or mist help") | ||
return nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package cmd | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
"strings" | ||
"time" | ||
) | ||
|
||
|
||
type JobCancelCmd struct { | ||
ID string `arg:"" help:"ID of job you want to cancel"` | ||
} | ||
|
||
func (c *JobCancelCmd) Run() error { | ||
// Same Mock data from job list. | ||
jobs := []Job{ | ||
{ | ||
ID: "ID:1", | ||
Name: "docker_container_name_1", | ||
Status: "Running", | ||
GPUType: "AMD", | ||
CreatedAt: time.Now(), | ||
}, | ||
{ | ||
ID: "ID:2", | ||
Name: "docker_container_name_2", | ||
Status: "Enqueued", | ||
GPUType: "TT", | ||
CreatedAt: time.Now().Add(-time.Hour * 24), | ||
}, | ||
{ | ||
ID: "ID:3", | ||
Name: "docker_container_name_3", | ||
Status: "Running", | ||
GPUType: "TT", | ||
CreatedAt: time.Now().Add(-time.Hour * 24), | ||
}, | ||
} | ||
|
||
// Check if job exists | ||
if !jobExists(jobs, c.ID) { | ||
fmt.Printf("%s does not exist in your jobs.\n", c.ID) | ||
fmt.Printf("Use the command \"job list\" for your list of jobs.") | ||
return nil | ||
} | ||
|
||
|
||
fmt.Printf("Are you sure you want to cancel %s? (y/n): \n", c.ID) | ||
|
||
reader := bufio.NewReader(os.Stdin) | ||
input, _ := reader.ReadString('\n') | ||
input = strings.TrimSpace(strings.ToLower(input)) | ||
|
||
if input == "y" || input == "yes"{ | ||
fmt.Println("Confirmed, proceeding job cancellation....") | ||
|
||
// Confirmed job cancellation logic | ||
|
||
fmt.Println("Cancelling job with ID:", c.ID) | ||
fmt.Printf("Job cancelled successfully with ID: %s\n", c.ID) | ||
return nil | ||
} else if input == "n" || input == "no"{ | ||
fmt.Println("Cancelled.") | ||
return nil | ||
} else{ | ||
fmt.Println("Invalid response.") | ||
return nil | ||
} | ||
|
||
return nil | ||
|
||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package cmd | ||
|
||
import ( | ||
"testing" | ||
"fmt" | ||
) | ||
|
||
|
||
// Added job, with no compute type added | ||
func TestJobCancelJobDoesNotExist(t *testing.T){ | ||
// This job should not exist in the dummy | ||
cmd := &JobCancelCmd{ID: "job_12345"} | ||
output := CaptureOutput(func(){ | ||
_ = cmd.Run() | ||
}) | ||
if want := "job_12345 does not exist in your jobs.\nUse the command \"job list\" for your list of jobs."; !contains(output, want){ | ||
t.Errorf("expected output to contain %q, got %q", want, output) | ||
} | ||
} | ||
|
||
// Added job, with compute type | ||
func TestJobCancelValid(t *testing.T){ | ||
// This job should not exist in the dummy | ||
cmd := &JobCancelCmd{ID: "ID:1"} | ||
output := CaptureOutput(func(){ | ||
_ = cmd.Run() | ||
}) | ||
if want := "Are you sure you want to cancel ID:1? (y/n):"; !contains(output, want){ | ||
t.Errorf("expected output to contain %q, got %q", want, output) | ||
} | ||
} | ||
|
||
|
||
func TestJobCancelProceed(t *testing.T){ | ||
cmd := &JobCancelCmd{ID: "ID:1"} | ||
// Lowkey, we should refactor this into a | ||
output := CaptureOutput(func(){ | ||
MockInput("y\n", func() { | ||
_ = cmd.Run() | ||
}) | ||
}) | ||
if !contains(output, "Confirmed, proceeding job cancellation...."){ | ||
t.Errorf("expected 'Confirmed, proceeding job cancellation....' but got:\n%s", output) | ||
} | ||
// fmt.Printf("Got the output %s\n", output) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"text/tabwriter" | ||
"time" | ||
) | ||
|
||
type ListCmd struct { | ||
All bool `help:"List all jobs, including completed and failed ones." short:"a"` | ||
} | ||
|
||
type Job struct { | ||
ID string | ||
Name string | ||
Status string | ||
GPUType string | ||
CreatedAt time.Time | ||
} | ||
|
||
func (l *ListCmd) Run() error { | ||
// Mock data - pull from API in real implementation | ||
jobs := []Job{ | ||
{ | ||
ID: "ID:1", | ||
Name: "docker_container_name_1", | ||
Status: "Running", | ||
GPUType: "AMD", | ||
CreatedAt: time.Now(), | ||
}, | ||
{ | ||
ID: "ID:2", | ||
Name: "docker_container_name_2", | ||
Status: "Enqueued", | ||
GPUType: "TT", | ||
CreatedAt: time.Now().Add(-time.Hour * 24), | ||
}, | ||
{ | ||
ID: "ID:3", | ||
Name: "docker_container_name_3", | ||
Status: "Running", | ||
GPUType: "TT", | ||
CreatedAt: time.Now().Add(-time.Hour * 24), | ||
}, | ||
} | ||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) | ||
fmt.Fprintln(w, "Job ID\tName\tStatus\tGPU Type\tCreated At") | ||
fmt.Fprintln(w, "--------------------------------------------------------------") | ||
|
||
for _, job := range jobs { | ||
// Maybe filter based on running? | ||
fmt.Fprintf( | ||
w, | ||
"%s\t%s\t%s\t%s\t%s\n", | ||
job.ID, | ||
job.Name, | ||
job.Status, | ||
job.GPUType, | ||
job.CreatedAt.Format(time.RFC1123), | ||
) | ||
} | ||
|
||
w.Flush() | ||
|
||
return nil | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These files need to be removed and gitignored