Reuse -y to mean accept defaults for init command for #288 (#437)

* Reuse -y to mean accept defaults for init command

* Change cli.promptCustom to accept a ForcePrompt value and delegate prompting responsiblity to it

* Add prompt for different license selection

* Remove extra spaces in category in promptCustom and promptList

* Fix bug that always returned MIT

* Add LGPL3 to array of licenses

* Change to not prompt at all for package name

* Change to not prompt for author if acquired from vcs and moved before prompting for version

* Reduce excess indenting

* Create tools.writeContents to contain file writting functionality and use it to write the nimble file

* Create package src directory and add it to the nimble file

* Write an initial source file

* Create directory and files needed for testing

* Add package created message and change priority of nimble file creation

* Rearrange args for promptCustom and add another promptCustom function that doesn't accept ForcePrompt

* Add package type prompt, remove writeContents proc, rename initial test file, provide alternate initial file contents based on type, and other minor improvements
This commit is contained in:
antizealot1337 2017-12-21 18:11:02 -05:00 • committed by Dominik Picheta
commit 4cc1d44bdd
4 changed files with 185 additions and 52 deletions

View file

@ -693,73 +693,168 @@ proc dump(options: Options) =
proc init(options: Options) = proc init(options: Options) =
var nimbleFile: string = "" var nimbleFile: string = ""
display("Info:", if options.forcePrompts != forcePromptYes:
"In order to initialise a new Nimble package, I will need to ask you\n" & display("Info:",
"some questions. Default values are shown in square brackets, press\n" & "In order to initialise a new Nimble package, I will need to ask you\n" &
"enter to use them.", priority = HighPriority) "some questions. Default values are shown in square brackets, press\n" &
"enter to use them.", priority = HighPriority)
# Ask for package name. # Ask for package name.
if options.action.projName != "": let pkgName =
let pkgName = options.action.projName if options.action.projName != "":
nimbleFile = pkgName.changeFileExt("nimble") options.action.projName
else: else:
var pkgName = os.getCurrentDir().splitPath.tail.toValidPackageName() os.getCurrentDir().splitPath.tail.toValidPackageName()
pkgName = promptCustom("Package name?", pkgName)
nimbleFile = pkgName.changeFileExt("nimble")
nimbleFile = pkgName.changeFileExt("nimble")
validatePackageName(nimbleFile.changeFileExt("")) validatePackageName(nimbleFile.changeFileExt(""))
if existsFile(os.getCurrentDir() / nimbleFile): if existsFile(os.getCurrentDir() / nimbleFile):
raise newException(NimbleError, "Nimble file already exists.") raise newException(NimbleError, "Nimble file already exists.")
# Ask for package version. display("Using", "$# for new package name" % [pkgName.escape()],
let pkgVersion = promptCustom("Initial version of package?", "0.1.0") priority = HighPriority)
validateVersion(pkgVersion)
# Ask for package author # Ask for package author
var defaultAuthor = "Anonymous" proc getAuthor(): string =
if findExe("git") != "": if findExe("git") != "":
let (name, exitCode) = doCmdEx("git config --global user.name") let (name, exitCode) = doCmdEx("git config --global user.name")
if exitCode == QuitSuccess and name.len > 0: if exitCode == QuitSuccess and name.len > 0:
defaultAuthor = name.strip() result = name.strip()
elif defaultAuthor == "Anonymous" and findExe("hg") != "": display("Using", "$# for new package author" % [result.escape()],
let (name, exitCode) = doCmdEx("hg config ui.username") priority = HighPriority)
if exitCode == QuitSuccess and name.len > 0: elif findExe("hg") != "":
defaultAuthor = name.strip() let (name, exitCode) = doCmdEx("hg config ui.username")
let pkgAuthor = promptCustom("Your name?", defaultAuthor) if exitCode == QuitSuccess and name.len > 0:
result = name.strip()
display("Using", "$# for new package author" % [result.escape()],
priority = HighPriority)
else:
result = promptCustom(options, "Your name?", "Anonymous")
let pkgAuthor = getAuthor()
# Declare the src/ directory
let pkgSrcDir = "src"
display("Using", "$# for new package source directory" % [pkgSrcDir.escape()],
priority = HighPriority)
# Determine the type of package
let pkgType = promptList(options, "Package type?", [
"lib",
"bin",
])
# Ask for package version.
let pkgVersion = promptCustom(options, "Initial version of package?", "0.1.0")
validateVersion(pkgVersion)
# Ask for description # Ask for description
let pkgDesc = promptCustom("Package description?", "") let pkgDesc = promptCustom(options, "Package description?",
"A new awesome nimble package")
# Ask for license # Ask for license
# TODO: Provide selection of licenses, or select random default license. let pkgLicense = options.promptList("Package License?", [
let pkgLicense = promptCustom("Package license?", "MIT") "MIT",
"BSD2",
"GPLv3",
"LGPLv3",
"Apache2",
])
# Ask for Nim dependency # Ask for Nim dependency
let nimDepDef = getNimrodVersion() let nimDepDef = getNimrodVersion()
let pkgNimDep = promptCustom("Lowest supported Nim version?", $nimDepDef) let pkgNimDep = promptCustom(options, "Lowest supported Nim version?",
$nimDepDef)
validateVersion(pkgNimDep) validateVersion(pkgNimDep)
var outFile: File let pkgTestDir = "tests"
if open(f = outFile, filename = nimbleFile, mode = fmWrite):
outFile.writeLine """# Package # Create source directory
os.createDir(pkgSrcDir)
display("Success:", "Source directory created successfully", Success,
MediumPriority)
# Create initial source file
cd pkgSrcDir:
let pkgFile = pkgName.changeFileExt("nim")
try:
if pkgType == "bin":
pkgFile.writeFile "# Hello Nim!\necho \"Hello, World!\"\n"
else:
pkgFile.writeFile """# $#
# Copyright $#
# $#
""" % [pkgName, pkgAuthor, pkgDesc]
display("Success:", "Created initial source file successfully", Success,
MediumPriority)
except:
raise newException(NimbleError, "Unable to open file " & pkgFile &
" for writing: " & osErrorMsg(osLastError()))
# Create test directory
os.createDir(pkgTestDir)
display("Success:", "Test directory created successfully", Success,
MediumPriority)
cd pkgTestDir:
try:
"test1.nims".writeFile("""switch("path", "$$projectDir/../$#")""" %
[pkgSrcDir])
display("Success:", "Test config file created successfully", Success,
MediumPriority)
except:
raise newException(NimbleError, "Unable to open file " & "test1.nims" &
" for writing: " & osErrorMsg(osLastError()))
try:
"test1.nim".writeFile("doAssert(1 + 1 == 2)\n")
display("Success:", "Test file created successfully", Success,
MediumPriority)
except:
raise newException(NimbleError, "Unable to open file " & "test1.nim" &
" for writing: " & osErrorMsg(osLastError()))
# Write the nimble file
try:
if pkgType == "lib":
nimbleFile.writeFile """# Package
version = $# version = $#
author = $# author = $#
description = $# description = $#
license = $# license = $#
srcDir = $#
# Dependencies # Dependencies
requires "nim >= $#" requires "nim >= $#"
""" % [pkgVersion.escape(), pkgAuthor.escape(), pkgDesc.escape(), """ % [pkgVersion.escape(), pkgAuthor.escape(), pkgDesc.escape(),
pkgLicense.escape(), pkgNimDep] pkgLicense.escape(), pkgSrcDir.escape(), pkgNimDep]
close(outFile) else:
else: nimbleFile.writeFile """# Package
raise newException(NimbleError, "Unable to open file " & nimbleFile &
version = $#
author = $#
description = $#
license = $#
srcDir = $#
bin = @[$#]
# Dependencies
requires "nim >= $#"
""" % [pkgVersion.escape(), pkgAuthor.escape(), pkgDesc.escape(),
pkgLicense.escape(), pkgSrcDir.escape(), pkgName.escape(), pkgNimDep]
except:
raise newException(NimbleError, "Unable to open file " & "test1.nim" &
" for writing: " & osErrorMsg(osLastError())) " for writing: " & osErrorMsg(osLastError()))
display("Success:", "Nimble file created successfully", Success, HighPriority) display("Success:", "Nimble file created successfully", Success,
MediumPriority)
display("Success:", "Package $# created successfully" % [pkgName], Success,
HighPriority)
proc uninstall(options: Options) = proc uninstall(options: Options) =
if options.action.packages.len == 0: if options.action.packages.len == 0:

View file

@ -146,19 +146,43 @@ proc prompt*(forcePrompts: ForcePrompt, question: string): bool =
else: else:
return false return false
proc promptCustom*(question, default: string): string = proc promptCustom*(forcePrompts: ForcePrompt, question, default: string): string =
if default == "": case forcePrompts:
display("Prompt:", question, Warning, HighPriority) of forcePromptYes:
displayCategory("Answer:", Warning, HighPriority) display("Prompt:", question & " -> [forced " & default & "]", Warning,
let user = stdin.readLine() HighPriority)
if user.len == 0: return promptCustom(question, default) return default
else: return user
else: else:
display("Prompt:", question & " [" & default & "]", Warning, HighPriority) if default == "":
display("Prompt:", question, Warning, HighPriority)
displayCategory("Answer:", Warning, HighPriority)
let user = stdin.readLine()
if user.len == 0: return promptCustom(forcePrompts, question, default)
else: return user
else:
display("Prompt:", question & " [" & default & "]", Warning, HighPriority)
displayCategory("Answer:", Warning, HighPriority)
let user = stdin.readLine()
if user == "": return default
else: return user
proc promptCustom*(question, default: string): string =
return promptCustom(dontForcePrompt, question, default)
proc promptList*(forcePrompts: ForcePrompt, question: string, args: openarray[string]): string =
case forcePrompts:
of forcePromptYes:
result = args[0]
display("Prompt:", question & " -> [forced " & result & "]", Warning,
HighPriority)
else:
display("Prompt:", question & " [" & join(args, "/") & "]", Warning, HighPriority)
displayCategory("Answer:", Warning, HighPriority) displayCategory("Answer:", Warning, HighPriority)
let user = stdin.readLine() result = stdin.readLine()
if user == "": return default for arg in args:
else: return user if arg.cmpIgnoreCase(result) == 0:
return arg
return promptList(forcePrompts, question, args)
proc setVerbosity*(level: Priority) = proc setVerbosity*(level: Priority) =
globalCLI.level = level globalCLI.level = level

View file

@ -194,6 +194,20 @@ proc prompt*(options: Options, question: string): bool =
## forcePrompts has a value different than dontForcePrompt. ## forcePrompts has a value different than dontForcePrompt.
return prompt(options.forcePrompts, question) return prompt(options.forcePrompts, question)
proc promptCustom*(options: Options, question, default: string): string =
## Asks an interactive question and returns the result.
##
## The proc will return "default" without asking the user if the global
## forcePrompts is forcePromptYes.
return promptCustom(options.forcePrompts, question, default)
proc promptList*(options: Options, question: string, args: openarray[string]): string =
## Asks an interactive question and returns the result.
##
## The proc will return one of the provided args. If not prompting the first
## options is selected.
return promptList(options.forcePrompts, question, args)
proc renameBabelToNimble(options: Options) {.deprecated.} = proc renameBabelToNimble(options: Options) {.deprecated.} =
let babelDir = getHomeDir() / ".babel" let babelDir = getHomeDir() / ".babel"
let nimbleDir = getHomeDir() / ".nimble" let nimbleDir = getHomeDir() / ".nimble"