|
root / src / util / prompt.reef
prompt.reef Reef 188 lines 5.5 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/******************************************************************************
               __               ____                __
              / /   ___  ____ _/ __/_____________ _/ /__
             / /   / _ \/ __ `/ /_/ ___/ ___/ __ `/ / _ \
            / /___/  __/ /_/ / __(__  ) /__/ /_/ / /  __/
           /_____/\___/\__,_/_/ /____/\___/\__,_/_/\___/

   (C)opyright 2025, Leafscale, LLC -  https://www.leafscale.com

   Project: Zygaena
  Filename: prompt.reef
   Authors: Chris Tusa <chris.tusa@leafscale.com>
   License: <see LICENSE file included with this source code>
Description: User prompt utilities for Coral

******************************************************************************/

module util.prompt

import io.console
import core.option as opt
import core.str
import core.convert
import util.color
import types

export
    fn has_yes_flag(opts: types.GlobalOptions): bool
    fn confirm(message: string, opts: types.GlobalOptions): bool
    fn confirm_packages(action: string, packages: [string], count: int, opts: types.GlobalOptions): bool
    fn confirm_install(to_install: [string], install_count: int, to_upgrade: [string], upgrade_count: int, opts: types.GlobalOptions): bool
    fn confirm_remove(to_remove: [string], count: int, dependents: [string], dep_count: int, opts: types.GlobalOptions): bool
    fn confirm_build_plan(packages: [string], versions: [string], count: int, target: string, opts: types.GlobalOptions): bool
end export

// Check if -y or --yes flag is present
fn has_yes_flag(opts: types.GlobalOptions): bool
    return opts.yes
end has_yes_flag

// Ask for confirmation, returns true if user confirms
fn confirm(message: string, opts: types.GlobalOptions): bool
    // Skip if -y flag
    if has_yes_flag(opts)
        return true
    end if

    print(message + " [Y/n] ")
    let response = opt.unwrap_or(console.readLine(), "")
    let r = str.trim_ws(response)

    // Empty or Y/y means yes
    if str.length(r) == 0
        return true
    end if
    if r == "Y" or r == "y" or r == "yes" or r == "Yes" or r == "YES"
        return true
    end if

    return false
end confirm

// Display list of packages and ask for confirmation
fn confirm_packages(action: string, packages: [string], count: int, opts: types.GlobalOptions): bool
    if count == 0
        return false
    end if

    println("")
    println(color.bold("Packages to " + action + ":"))
    println("")

    // Display packages in columns
    mut i = 0
    while i < count
        println("  " + packages[i])
        i = i + 1
    end while

    println("")
    println(color.dim("Total: " + convert.to_string(count) + " package(s)"))
    println("")

    return confirm("Proceed?", opts)
end confirm_packages

// Display package info and ask for install confirmation
fn confirm_install(to_install: [string], install_count: int,
                   to_upgrade: [string], upgrade_count: int,
                   opts: types.GlobalOptions): bool
    if install_count == 0 and upgrade_count == 0
        return false
    end if

    println("")

    if install_count > 0
        println(color.bold("New packages to install:"))
        mut i = 0
        while i < install_count
            println("  " + color.green("+") + " " + to_install[i])
            i = i + 1
        end while
        println("")
    end if

    if upgrade_count > 0
        println(color.bold("Packages to upgrade:"))
        mut i = 0
        while i < upgrade_count
            println("  " + color.cyan("^") + " " + to_upgrade[i])
            i = i + 1
        end while
        println("")
    end if

    let total = install_count + upgrade_count
    println(color.dim("Total: " + convert.to_string(total) + " package(s)"))
    println("")

    return confirm("Proceed with installation?", opts)
end confirm_install

// Display packages to remove and ask for confirmation
fn confirm_remove(to_remove: [string], count: int,
                  dependents: [string], dep_count: int,
                  opts: types.GlobalOptions): bool
    if count == 0
        return false
    end if

    println("")
    println(color.bold("Packages to remove:"))

    mut i = 0
    while i < count
        println("  " + color.red("-") + " " + to_remove[i])
        i = i + 1
    end while

    if dep_count > 0
        println("")
        println(color.yellow("The following packages depend on these and will also be removed:"))
        i = 0
        while i < dep_count
            println("  " + color.yellow("-") + " " + dependents[i])
            i = i + 1
        end while
    end if

    println("")
    let total = count + dep_count
    println(color.dim("Total: " + convert.to_string(total) + " package(s)"))
    println("")

    return confirm("Proceed with removal?", opts)
end confirm_remove

// Display build plan and ask for confirmation
fn confirm_build_plan(packages: [string], versions: [string], count: int, target: string, opts: types.GlobalOptions): bool
    if count == 0
        return true
    end if

    println("")
    println(color.bold("Build plan for '" + target + "':"))
    println("")
    println("Packages to build from source:")

    mut i = 0
    while i < count
        mut line = "  " + color.green("+") + " " + packages[i]
        if str.length(versions[i]) > 0
            line = line + " " + color.dim(versions[i])
        end if
        println(line)
        i = i + 1
    end while

    println("")
    println(color.dim("Total: " + convert.to_string(count) + " package(s) to build"))
    println("")

    return confirm("Proceed with build?", opts)
end confirm_build_plan

end module