From 4cc1d44bdd9dbcd988681a6e98fa8168f1af1055 Mon Sep 17 00:00:00 2001 From: antizealot1337 Date: Thu, 21 Dec 2017 18:11:02 -0500 Subject: [PATCH] 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 --- src/nimble.nim | 167 ++++++++++++++++++++++++++++++-------- src/nimblepkg/cli.nim | 46 ++++++++--- src/nimblepkg/options.nim | 16 +++- src/nimblepkg/tools.nim | 8 +- 4 files changed, 185 insertions(+), 52 deletions(-) diff --git a/src/nimble.nim b/src/nimble.nim index da7e12e..2c52d5c 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -693,73 +693,168 @@ proc dump(options: Options) = proc init(options: Options) = var nimbleFile: string = "" - display("Info:", - "In order to initialise a new Nimble package, I will need to ask you\n" & - "some questions. Default values are shown in square brackets, press\n" & - "enter to use them.", priority = HighPriority) + if options.forcePrompts != forcePromptYes: + display("Info:", + "In order to initialise a new Nimble package, I will need to ask you\n" & + "some questions. Default values are shown in square brackets, press\n" & + "enter to use them.", priority = HighPriority) # Ask for package name. - if options.action.projName != "": - let pkgName = options.action.projName - nimbleFile = pkgName.changeFileExt("nimble") - else: - var pkgName = os.getCurrentDir().splitPath.tail.toValidPackageName() - pkgName = promptCustom("Package name?", pkgName) - nimbleFile = pkgName.changeFileExt("nimble") + let pkgName = + if options.action.projName != "": + options.action.projName + else: + os.getCurrentDir().splitPath.tail.toValidPackageName() + nimbleFile = pkgName.changeFileExt("nimble") validatePackageName(nimbleFile.changeFileExt("")) if existsFile(os.getCurrentDir() / nimbleFile): raise newException(NimbleError, "Nimble file already exists.") - # Ask for package version. - let pkgVersion = promptCustom("Initial version of package?", "0.1.0") - validateVersion(pkgVersion) + display("Using", "$# for new package name" % [pkgName.escape()], + priority = HighPriority) # Ask for package author - var defaultAuthor = "Anonymous" - if findExe("git") != "": - let (name, exitCode) = doCmdEx("git config --global user.name") - if exitCode == QuitSuccess and name.len > 0: - defaultAuthor = name.strip() - elif defaultAuthor == "Anonymous" and findExe("hg") != "": - let (name, exitCode) = doCmdEx("hg config ui.username") - if exitCode == QuitSuccess and name.len > 0: - defaultAuthor = name.strip() - let pkgAuthor = promptCustom("Your name?", defaultAuthor) + proc getAuthor(): string = + if findExe("git") != "": + let (name, exitCode) = doCmdEx("git config --global user.name") + if exitCode == QuitSuccess and name.len > 0: + result = name.strip() + display("Using", "$# for new package author" % [result.escape()], + priority = HighPriority) + elif findExe("hg") != "": + let (name, exitCode) = doCmdEx("hg config ui.username") + 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 - let pkgDesc = promptCustom("Package description?", "") + let pkgDesc = promptCustom(options, "Package description?", + "A new awesome nimble package") # Ask for license - # TODO: Provide selection of licenses, or select random default license. - let pkgLicense = promptCustom("Package license?", "MIT") + let pkgLicense = options.promptList("Package License?", [ + "MIT", + "BSD2", + "GPLv3", + "LGPLv3", + "Apache2", + ]) # Ask for Nim dependency let nimDepDef = getNimrodVersion() - let pkgNimDep = promptCustom("Lowest supported Nim version?", $nimDepDef) + let pkgNimDep = promptCustom(options, "Lowest supported Nim version?", + $nimDepDef) validateVersion(pkgNimDep) - var outFile: File - if open(f = outFile, filename = nimbleFile, mode = fmWrite): - outFile.writeLine """# Package + let pkgTestDir = "tests" + + # 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 = $# author = $# description = $# license = $# +srcDir = $# # Dependencies requires "nim >= $#" """ % [pkgVersion.escape(), pkgAuthor.escape(), pkgDesc.escape(), - pkgLicense.escape(), pkgNimDep] - close(outFile) - else: - raise newException(NimbleError, "Unable to open file " & nimbleFile & + pkgLicense.escape(), pkgSrcDir.escape(), pkgNimDep] + else: + nimbleFile.writeFile """# Package + +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())) - 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) = if options.action.packages.len == 0: diff --git a/src/nimblepkg/cli.nim b/src/nimblepkg/cli.nim index 0bd16cc..a232940 100644 --- a/src/nimblepkg/cli.nim +++ b/src/nimblepkg/cli.nim @@ -146,19 +146,43 @@ proc prompt*(forcePrompts: ForcePrompt, question: string): bool = else: return false -proc promptCustom*(question, default: string): string = - if default == "": - display("Prompt:", question, Warning, HighPriority) - displayCategory("Answer:", Warning, HighPriority) - let user = stdin.readLine() - if user.len == 0: return promptCustom(question, default) - else: return user +proc promptCustom*(forcePrompts: ForcePrompt, question, default: string): string = + case forcePrompts: + of forcePromptYes: + display("Prompt:", question & " -> [forced " & default & "]", Warning, + HighPriority) + return default 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) - let user = stdin.readLine() - if user == "": return default - else: return user + result = stdin.readLine() + for arg in args: + if arg.cmpIgnoreCase(result) == 0: + return arg + return promptList(forcePrompts, question, args) proc setVerbosity*(level: Priority) = globalCLI.level = level diff --git a/src/nimblepkg/options.nim b/src/nimblepkg/options.nim index 3b2c465..4af9f0c 100644 --- a/src/nimblepkg/options.nim +++ b/src/nimblepkg/options.nim @@ -194,6 +194,20 @@ proc prompt*(options: Options, question: string): bool = ## forcePrompts has a value different than dontForcePrompt. 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.} = let babelDir = getHomeDir() / ".babel" let nimbleDir = getHomeDir() / ".nimble" @@ -384,4 +398,4 @@ proc briefClone*(options: Options): Options = newOptions.config = options.config newOptions.nimbleData = options.nimbleData newOptions.pkgInfoCache = options.pkgInfoCache - return newOptions \ No newline at end of file + return newOptions diff --git a/src/nimblepkg/tools.nim b/src/nimblepkg/tools.nim index 00e518c..7ed5501 100644 --- a/src/nimblepkg/tools.nim +++ b/src/nimblepkg/tools.nim @@ -80,10 +80,10 @@ proc changeRoot*(origRoot, newRoot, path: string): string = ## path: /home/dom/bar/blah/2/foo.txt ## Return value -> /home/test/bar/blah/2/foo.txt - ## The additional check of `path.samePaths(origRoot)` is necessary to prevent - ## a regression, where by ending the `srcDir` defintion in a nimble file in a + ## The additional check of `path.samePaths(origRoot)` is necessary to prevent + ## a regression, where by ending the `srcDir` defintion in a nimble file in a ## trailing separator would cause the `path.startsWith(origRoot)` evaluation to - ## fail because of the value of `origRoot` would be longer than `path` due to + ## fail because of the value of `origRoot` would be longer than `path` due to ## the trailing separator. This would cause this method to throw during package ## installation. if path.startsWith(origRoot) or path.samePaths(origRoot): @@ -157,4 +157,4 @@ proc getNimbleTempDir*(): string = importc: "GetCurrentProcessId".} result.add($GetCurrentProcessId()) else: - result.add($getpid()) \ No newline at end of file + result.add($getpid())