diff --git a/functions/__yay_serve.fish b/functions/__yay_serve.fish new file mode 100644 index 0000000..3579fb1 --- /dev/null +++ b/functions/__yay_serve.fish @@ -0,0 +1,32 @@ +function __yay_serve + set -l opts h/help 'p/port=' 'd/directory=' + argparse $opts -- $argv; or return + + if set -q _flag_help + echo "Usage: yay serve [OPTIONS]" + echo "Start a file server to serve files from a directory" + echo "" + echo "Options:" + echo " -p, --port PORT Port to serve on (default: 8080)" + echo " -d, --directory DIR Directory to serve (default: current directory)" + echo " -h, --help Show this help message" + return + end + + set -l port 8080 + if test -n "$_flag_port" + set port $_flag_port + end + + set -l directory "." + if test -n "$_flag_directory" + set directory $_flag_directory + end + + __yay_green "««« STARTING FILE SERVER »»»" + __yay_yellow "Port: $port" + __yay_yellow "Directory: $directory" + + # Run the Go file server + yay-serve -p $port -d "$directory" +end diff --git a/functions/yay.fish b/functions/yay.fish index aa4babe..abec7ed 100644 --- a/functions/yay.fish +++ b/functions/yay.fish @@ -22,6 +22,8 @@ function yay_function __yay_tar $argv[2..-1]; or exit $status case untar __yay_untar $argv[2..-1]; or exit $status + case serve + __yay_serve $argv[2..-1]; or exit $status case '*' __yay_red "Unknown subcommand: $argv[1]" exit 1 @@ -31,4 +33,4 @@ end # For direct fish shell usage function yay yay_function $argv -end \ No newline at end of file +end diff --git a/pkgs/default.nix b/pkgs/default.nix index 4e123a1..c37e94f 100644 --- a/pkgs/default.nix +++ b/pkgs/default.nix @@ -14,6 +14,14 @@ let cp ${../share/fish/completions}/yay.fish $out/share/fish/vendor_completions.d/ ''; + # Build the Go file server + yay-serve = pkgs.buildGoModule { + pname = "yay-serve"; + version = "1.0.0"; + src = ../share/serve; + vendorHash = null; + }; + # Create main yay binary that correctly passes args to fish yayBin = pkgs.writeShellScriptBin "yay" '' FUNCTIONS_DIR=$(dirname $(dirname $0))/share/fish/functions @@ -42,6 +50,7 @@ pkgs.symlinkJoin { yayBin fishFunctions fishCompletions + yay-serve ]; buildInputs = [ pkgs.makeWrapper ]; @@ -59,6 +68,7 @@ pkgs.symlinkJoin { pkgs.bzip2 pkgs.bzip3 pkgs.zstd + yay-serve ] } ''; diff --git a/share/fish/completions/yay.fish b/share/fish/completions/yay.fish index df28414..fff58fc 100644 --- a/share/fish/completions/yay.fish +++ b/share/fish/completions/yay.fish @@ -7,7 +7,7 @@ function __ensure_yay_functions (dirname (dirname (status -f)))/functions \ /run/current-system/sw/share/yay.nix/functions \ $__fish_config_dir/functions - + for dir in $possible_paths if test -f "$dir/__yay_get_flake_path.fish" source "$dir/__yay_get_flake_path.fish" @@ -84,11 +84,11 @@ end # Flake input handling function __yay_list_flake_inputs set -l flake_path (__yay_get_flake_path $argv[1]); or return - + if not test -f "$flake_path/flake.lock" return 1 end - + # Extract input names from the flake.lock file using jq jq -r '.nodes.root.inputs | keys[]' "$flake_path/flake.lock" 2>/dev/null end @@ -96,23 +96,23 @@ end function __yay_get_flake_inputs # Ensure required functions are available __ensure_yay_functions - + # Skip if the required function isn't available if not type -q __yay_get_flake_path return 1 end - + set -l cmd (commandline -poc) set -l path "" - + # Check for --path or -p option for i in (seq 1 (count $cmd)) - if test "$cmd[$i]" = "--path" -o "$cmd[$i]" = "-p"; and test (count $cmd) -ge (math $i + 1) + if test "$cmd[$i]" = --path -o "$cmd[$i]" = -p; and test (count $cmd) -ge (math $i + 1) set path $cmd[(math $i + 1)] break end end - + __yay_list_flake_inputs $path end @@ -155,12 +155,13 @@ end complete -c yay -f # Complete the top-level subcommands -complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar" -a rebuild -d "Rebuild the NixOS configuration" -complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar" -a update -d "Update flake inputs" -complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar" -a garbage -d "Clean up the Nix store" -complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar" -a try -d "Create a shell with the specified package(s)" -complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar" -a tar -d "Create compressed tar archives" -complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar" -a untar -d "Extract tar archives" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a garbage -d "Clean up the Nix store" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a rebuild -d "Rebuild the NixOS configuration" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a serve -d "Start a file server" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a tar -d "Create compressed tar archives" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a try -d "Create a shell with the specified package(s)" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a untar -d "Extract tar archives" +complete -c yay -n "not __yay_seen_subcommand_from rebuild update garbage try tar untar serve" -a update -d "Update flake inputs" ###################### # REBUILD SUBCOMMAND # @@ -191,6 +192,15 @@ complete -c yay -n "__yay_seen_subcommand_from update; and not __yay_seen_option # Options for 'garbage' complete -c yay -n "__yay_seen_subcommand_from garbage" -s h -l help -d "Show help message" +###################### +# SERVE SUBCOMMAND # +###################### + +# Options for 'serve' +complete -c yay -n "__yay_seen_subcommand_from serve" -s p -l port -r -d "Port to serve on (default: 8080)" +complete -c yay -n "__yay_seen_subcommand_from serve" -s d -l directory -r -a "(__fish_complete_directories)" -d "Directory to serve (default: current directory)" +complete -c yay -n "__yay_seen_subcommand_from serve" -s h -l help -d "Show help message" + ###################### # TRY SUBCOMMAND # ###################### @@ -204,7 +214,7 @@ function __yay_try_no_dash_dash_yet and not contains -- -- (commandline -poc) and not string match -r -- '^-' (commandline -ct) end -complete -c yay -n "__yay_try_no_dash_dash_yet" -a "(__yay_list_packages)" -d "Nix package" +complete -c yay -n __yay_try_no_dash_dash_yet -a "(__yay_list_packages)" -d "Nix package" # Double dash separator completion for try function __yay_try_can_add_dash_dash @@ -212,7 +222,7 @@ function __yay_try_can_add_dash_dash and not contains -- -- (commandline -poc) and test (count (commandline -poc)) -gt 2 end -complete -c yay -n "__yay_try_can_add_dash_dash" -a "--" -d "Separator for command to run" +complete -c yay -n __yay_try_can_add_dash_dash -a -- -d "Separator for command to run" # Command completion after -- function __yay_try_after_dash_dash @@ -220,7 +230,7 @@ function __yay_try_after_dash_dash contains -- -- $tokens and __yay_seen_subcommand_from try end -complete -c yay -n "__yay_try_after_dash_dash" -a "(__fish_complete_command)" -d "Command to run" +complete -c yay -n __yay_try_after_dash_dash -a "(__fish_complete_command)" -d "Command to run" ###################### # TAR SUBCOMMAND # diff --git a/share/serve/go.mod b/share/serve/go.mod new file mode 100644 index 0000000..22a8125 --- /dev/null +++ b/share/serve/go.mod @@ -0,0 +1,3 @@ +module yay-serve + +go 1.21 \ No newline at end of file diff --git a/share/serve/main.go b/share/serve/main.go new file mode 100644 index 0000000..7c8e38d --- /dev/null +++ b/share/serve/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "bufio" + "context" + "flag" + "fmt" + "net/http" + "os" + "strconv" + "strings" + "time" +) + +func main() { + var port int + var directory string + + // Define command-line flags + flag.IntVar(&port, "port", 8080, "Port to serve on") + flag.IntVar(&port, "p", 8080, "Port to serve on (shorthand)") + flag.StringVar(&directory, "directory", ".", "Directory to serve") + flag.StringVar(&directory, "d", ".", "Directory to serve (shorthand)") + + flag.Parse() + + // Check if the directory exists + _, err := os.Stat(directory) + if os.IsNotExist(err) { + fmt.Printf("Directory '%s' not found.\n", directory) + os.Exit(1) + } + + // Create a file server handler to serve the directory's contents + fileServer := http.FileServer(http.Dir(directory)) + + // Create a new HTTP server and handle requests + mux := http.NewServeMux() + mux.Handle("/", fileServer) + + server := &http.Server{ + Addr: ":" + strconv.Itoa(port), + Handler: mux, + } + + // Start the server in a goroutine + go func() { + fmt.Printf("Server started at http://localhost:%d\n", port) + fmt.Printf("Serving directory: %s\n", directory) + fmt.Printf("\nTo exit, enter 'x' and press Enter\n") + + if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + fmt.Printf("Error starting server: %s\n", err) + os.Exit(1) + } + }() + + // Wait for user input to exit + scanner := bufio.NewScanner(os.Stdin) + for { + if scanner.Scan() { + input := strings.TrimSpace(scanner.Text()) + if strings.ToLower(input) == "x" { + fmt.Println("Shutting down server...") + + // Create a context with timeout for graceful shutdown + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := server.Shutdown(ctx); err != nil { + fmt.Printf("Server shutdown error: %s\n", err) + } else { + fmt.Println("Server stopped gracefully") + } + break + } + } + } +} \ No newline at end of file