mirror of
https://github.com/vlang/v.git
synced 2025-09-12 17:07:11 -04:00
tools.vcreate: rework cli arg handling to extend scaffolding and fix issues (#19889)
This commit is contained in:
parent
9308bcd48a
commit
e9258c2a08
@ -3,9 +3,9 @@ module main
|
||||
import os
|
||||
|
||||
fn (mut c Create) set_bin_project_files() {
|
||||
main_path := os.join_path('src', 'main.v')
|
||||
base := if c.new_dir { c.name } else { '' }
|
||||
c.files << ProjectFiles{
|
||||
path: if c.new_dir { os.join_path(c.name, main_path) } else { main_path }
|
||||
path: os.join_path(base, 'src', 'main.v')
|
||||
content: "module main
|
||||
|
||||
fn main() {
|
||||
|
@ -3,8 +3,9 @@ module main
|
||||
import os
|
||||
|
||||
fn (mut c Create) set_lib_project_files() {
|
||||
base := if c.new_dir { c.name } else { '' }
|
||||
c.files << ProjectFiles{
|
||||
path: os.join_path(c.name, 'src', c.name + '.v')
|
||||
path: os.join_path(base, 'src', c.name + '.v')
|
||||
content: 'module ${c.name}
|
||||
|
||||
// square calculates the second power of `x`
|
||||
@ -14,7 +15,7 @@ pub fn square(x int) int {
|
||||
'
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: os.join_path(c.name, 'tests', 'square_test.v')
|
||||
path: os.join_path(base, 'tests', 'square_test.v')
|
||||
content: 'import ${c.name}
|
||||
|
||||
fn test_square() {
|
||||
|
@ -3,8 +3,9 @@ module main
|
||||
import os { join_path }
|
||||
|
||||
fn (mut c Create) set_web_project_files() {
|
||||
base := if c.new_dir { c.name } else { '' }
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'databases', 'config_databases_sqlite.v')
|
||||
path: join_path(base, 'src', 'databases', 'config_databases_sqlite.v')
|
||||
content: "module databases
|
||||
|
||||
import db.sqlite // can change to 'db.mysql', 'db.pg'
|
||||
@ -16,7 +17,7 @@ pub fn create_db_connection() !sqlite.DB {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'templates', 'header_component.html')
|
||||
path: join_path(base, 'src', 'templates', 'header_component.html')
|
||||
content: "<nav>
|
||||
<div class='nav-wrapper'>
|
||||
<a href='javascript:window.history.back();' class='left'>
|
||||
@ -35,7 +36,7 @@ pub fn create_db_connection() !sqlite.DB {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'templates', 'products.css')
|
||||
path: join_path(base, 'src', 'templates', 'products.css')
|
||||
content: 'h1.title {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color: #3b7bbf;
|
||||
@ -49,7 +50,7 @@ div.products-table {
|
||||
}'
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'templates', 'products.html')
|
||||
path: join_path(base, 'src', 'templates', 'products.html')
|
||||
content: "<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@ -146,7 +147,7 @@ div.products-table {
|
||||
</html>"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'auth_controllers.v')
|
||||
path: join_path(base, 'src', 'auth_controllers.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
@ -163,7 +164,7 @@ pub fn (mut app App) controller_auth(username string, password string) vweb.Resu
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'auth_dto.v')
|
||||
path: join_path(base, 'src', 'auth_dto.v')
|
||||
content: 'module main
|
||||
|
||||
struct AuthRequestDto {
|
||||
@ -173,7 +174,7 @@ struct AuthRequestDto {
|
||||
'
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'auth_services.v')
|
||||
path: join_path(base, 'src', 'auth_services.v')
|
||||
content: "module main
|
||||
|
||||
import crypto.hmac
|
||||
@ -268,7 +269,7 @@ fn auth_verify(token string) bool {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'index.html')
|
||||
path: join_path(base, 'src', 'index.html')
|
||||
content: "<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@ -347,7 +348,7 @@ fn auth_verify(token string) bool {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'main.v')
|
||||
path: join_path(base, 'src', 'main.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
@ -392,7 +393,7 @@ pub fn (mut app App) index() vweb.Result {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'product_controller.v')
|
||||
path: join_path(base, 'src', 'product_controller.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
@ -458,7 +459,7 @@ pub fn (mut app App) controller_create_product(product_name string) vweb.Result
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'product_entities.v')
|
||||
path: join_path(base, 'src', 'product_entities.v')
|
||||
content: "module main
|
||||
|
||||
@[table: 'products']
|
||||
@ -471,7 +472,7 @@ struct Product {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'product_service.v')
|
||||
path: join_path(base, 'src', 'product_service.v')
|
||||
content: "module main
|
||||
|
||||
import databases
|
||||
@ -518,7 +519,7 @@ fn (mut app App) service_get_all_products_from(user_id int) ![]Product {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'product_view_api.v')
|
||||
path: join_path(base, 'src', 'product_view_api.v')
|
||||
content: "module main
|
||||
|
||||
import json
|
||||
@ -557,7 +558,7 @@ pub fn get_product(token string) ![]User {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'product_view.v')
|
||||
path: join_path(base, 'src', 'product_view.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
@ -579,7 +580,7 @@ pub fn (mut app App) products() !vweb.Result {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'user_controllers.v')
|
||||
path: join_path(base, 'src', 'user_controllers.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
@ -649,7 +650,7 @@ pub fn (mut app App) controller_create_user(username string, password string) vw
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'user_entities.v')
|
||||
path: join_path(base, 'src', 'user_entities.v')
|
||||
content: "module main
|
||||
|
||||
@[table: 'users']
|
||||
@ -664,7 +665,7 @@ mut:
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'user_services.v')
|
||||
path: join_path(base, 'src', 'user_services.v')
|
||||
content: "module main
|
||||
|
||||
import crypto.bcrypt
|
||||
@ -733,7 +734,7 @@ fn (mut app App) service_get_user(id int) !User {
|
||||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(c.name, 'src', 'user_view_api.v')
|
||||
path: join_path(base, 'src', 'user_view_api.v')
|
||||
content: "module main
|
||||
|
||||
import json
|
||||
|
@ -10,6 +10,6 @@ spawn $v_root/v init
|
||||
expect "Input your project description: " { send "\r" } timeout { exit 1 }
|
||||
expect "Input your project version: (0.0.0) " { send "\r" } timeout { exit 1 }
|
||||
expect "Input your project license: (MIT) " { send "\r" } timeout { exit 1 }
|
||||
expect "Complete!" {} timeout {} timeout { exit 1 }
|
||||
# The completion message is verified in `vcreate_init_test.v`.
|
||||
|
||||
expect eof
|
||||
|
@ -13,6 +13,6 @@ expect "Input your project description: " { send "\r" } timeout { exit 1 }
|
||||
expect "Input your project version: (0.0.0) " { send "\r" } timeout { exit 1 }
|
||||
expect "Input your project license: (MIT) " { send "\r" } timeout { exit 1 }
|
||||
expect "The directory name `$project_dir_name` is invalid as a module name. The module name in `v.mod` was set to `$corrected_mod_name`" {} timeout { exit 1 }
|
||||
expect "Complete!" {} timeout {} timeout { exit 1 }
|
||||
expect "Created binary (application) project `$corrected_mod_name`" {} timeout {} timeout { exit 1 }
|
||||
|
||||
expect eof
|
||||
|
17
cmd/tools/vcreate/tests/init_with_model_arg.expect
Executable file
17
cmd/tools/vcreate/tests/init_with_model_arg.expect
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env expect
|
||||
|
||||
set timeout 3
|
||||
|
||||
# Pass v_root as arg, since we chdir into a temp directory during testing and create a project there.
|
||||
set v_root [lindex $argv 0]
|
||||
set model [lindex $argv 1]
|
||||
|
||||
spawn $v_root/v init $model
|
||||
|
||||
expect "Input your project description: " { send "My Awesome V Application.\r" } timeout { exit 1 }
|
||||
expect "Input your project version: (0.0.0) " { send "0.0.1\r" } timeout { exit 1 }
|
||||
expect "Input your project license: (MIT) " { send "\r" } timeout { exit 1 }
|
||||
expect "Initialising ..." {} timeout { exit 1 }
|
||||
# The completion message is verified in `vcreate_init_test.v`.
|
||||
|
||||
expect eof
|
@ -4,15 +4,15 @@ set timeout 3
|
||||
|
||||
# Pass v_root as arg, since we chdir into a temp directory during testing and create a project there.
|
||||
set v_root [lindex $argv 0]
|
||||
set project_name [lindex $argv 1]
|
||||
set model [lindex $argv 2]
|
||||
set model [lindex $argv 1]
|
||||
set project_name [lindex $argv 2]
|
||||
|
||||
spawn $v_root/v new $project_name $model
|
||||
spawn $v_root/v new $model $project_name
|
||||
|
||||
expect "Input your project description: " { send "My Awesome V Project.\r" } timeout { exit 1 }
|
||||
expect "Input your project version: (0.0.0) " { send "0.0.1\r" } timeout { exit 1 }
|
||||
expect "Input your project license: (MIT) " { send "\r" } timeout { exit 1 }
|
||||
expect "Initialising ..." {} timeout { exit 1 }
|
||||
expect "Complete!" {} timeout { exit 1 }
|
||||
expect "Created library project `$project_name`" {} timeout { exit 1 }
|
||||
|
||||
expect eof
|
||||
|
@ -12,6 +12,6 @@ expect "Input your project description: " { send "\r" } timeout { exit 1 }
|
||||
expect "Input your project version: (0.0.0) " { send "\r" } timeout { exit 1 }
|
||||
expect "Input your project license: (MIT) " { send "\r" } timeout { exit 1 }
|
||||
expect "Initialising ..." {} timeout { exit 1 }
|
||||
expect "Complete!" {} timeout { exit 1 }
|
||||
expect "Created binary (application) project `$project_name`" {} timeout { exit 1 }
|
||||
|
||||
expect eof
|
||||
|
@ -13,6 +13,6 @@ expect "Input your project description: " { send "My Awesome V Project.\r" } tim
|
||||
expect "Input your project version: (0.0.0) " { send "0.1.0\r" } timeout { exit 1 }
|
||||
expect "Input your project license: (MIT) " { send "GPL\r" } timeout { exit 1 }
|
||||
expect "Initialising ..." {} timeout { exit 1 }
|
||||
expect "Complete!" {} timeout { exit 1 }
|
||||
expect "Created binary (application) project `$project_name`" {} timeout { exit 1 }
|
||||
|
||||
expect eof
|
||||
|
@ -3,18 +3,11 @@
|
||||
module main
|
||||
|
||||
import os
|
||||
import cli { Command, Flag }
|
||||
|
||||
// Note: this program follows a similar convention to Rust: `init` makes the
|
||||
// structure of the program in the _current_ directory, while `new`
|
||||
// makes the program structure in a _sub_ directory. Besides that, the
|
||||
// functionality is essentially the same.
|
||||
|
||||
// Note: here are the currently supported invocations so far:
|
||||
// - `v init` -> initialize a new project in the current folder
|
||||
// - `v new` -> create a new project in the directory specified during setup, using the "bin" template by default.
|
||||
// - `v new my_bin_project bin` -> create a new project directory `my_bin_project`, using the bin template.
|
||||
// - `v new my_lib_project lib` -> create a new project directory `my_lib_project`, using the lib template.
|
||||
// - `v new my_web_project web` -> create a new project directory `my_web_project`, using the vweb template.
|
||||
// Note: this program follows a similar convention as Rust cargo:
|
||||
// `init` creates the structure of project in the current directory,
|
||||
// `new` creates the structure of a project in a sub directory.
|
||||
|
||||
struct Create {
|
||||
mut:
|
||||
@ -24,6 +17,7 @@ mut:
|
||||
license string
|
||||
files []ProjectFiles
|
||||
new_dir bool
|
||||
template Template
|
||||
}
|
||||
|
||||
struct ProjectFiles {
|
||||
@ -31,89 +25,125 @@ struct ProjectFiles {
|
||||
content string
|
||||
}
|
||||
|
||||
fn main() {
|
||||
cmd := os.args[1]
|
||||
match cmd {
|
||||
'new' {
|
||||
// list of models allowed
|
||||
project_models := ['bin', 'lib', 'web']
|
||||
if os.args.len == 4 {
|
||||
// validation
|
||||
if os.args.last() !in project_models {
|
||||
mut error_str := 'It is not possible create a "${os.args[os.args.len - 2]}" project.\n'
|
||||
error_str += 'See the list of allowed projects:\n'
|
||||
for model in project_models {
|
||||
error_str += 'v new ${os.args[os.args.len - 2]} ${model}\n'
|
||||
}
|
||||
eprintln(error_str)
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
new_project(os.args[2..])
|
||||
}
|
||||
'init' {
|
||||
init_project(os.args[2..])
|
||||
}
|
||||
else {
|
||||
cerror('unknown command: ${cmd}')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
println('Complete!')
|
||||
enum Template {
|
||||
bin
|
||||
lib
|
||||
web
|
||||
}
|
||||
|
||||
fn new_project(args []string) {
|
||||
mut c := Create{}
|
||||
c.new_dir = true
|
||||
c.prompt(args)
|
||||
|
||||
println('Initialising ...')
|
||||
if args.len == 2 {
|
||||
// E.g.: `v new my_project lib`
|
||||
match os.args.last() {
|
||||
'bin' {
|
||||
c.set_bin_project_files()
|
||||
}
|
||||
'lib' {
|
||||
c.set_lib_project_files()
|
||||
}
|
||||
'web' {
|
||||
c.set_web_project_files()
|
||||
}
|
||||
else {
|
||||
eprintln('${os.args.last()} model not exist')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// E.g.: `v new my_project`
|
||||
c.set_bin_project_files()
|
||||
fn main() {
|
||||
flags := [
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'bin'
|
||||
description: 'Use the template for an executable application [default].'
|
||||
},
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'lib'
|
||||
description: 'Use the template for a library project.'
|
||||
},
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'web'
|
||||
description: 'Use the template for a vweb project.'
|
||||
},
|
||||
]
|
||||
mut cmd := Command{
|
||||
flags: [
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'help'
|
||||
description: 'Print help information.'
|
||||
global: true
|
||||
},
|
||||
]
|
||||
posix_mode: true
|
||||
commands: [
|
||||
Command{
|
||||
name: 'new'
|
||||
usage: '<project_name>'
|
||||
description: [
|
||||
'Creates a new V project in a directory with the specified project name.',
|
||||
'',
|
||||
'A setup prompt is started to create a `v.mod` file with the projects metadata.',
|
||||
'The <project_name> argument can be omitted and entered in the prompts dialog.',
|
||||
'If git is installed, `git init` will be performed during the setup.',
|
||||
].join_lines()
|
||||
parent: &Command{
|
||||
name: 'v'
|
||||
}
|
||||
posix_mode: true
|
||||
disable_man: true
|
||||
flags: flags
|
||||
pre_execute: validate
|
||||
execute: new_project
|
||||
},
|
||||
Command{
|
||||
name: 'init'
|
||||
description: [
|
||||
'Sets up a V project within the current directory.',
|
||||
'',
|
||||
"If no `v.mod` exists, a setup prompt is started to create one with the project's metadata.",
|
||||
'If no `.v` file exists, a project template is generated. If the current directory is not a',
|
||||
'git project and git is installed, `git init` will be performed during the setup.',
|
||||
].join_lines()
|
||||
parent: &Command{
|
||||
name: 'v'
|
||||
}
|
||||
posix_mode: true
|
||||
disable_man: true
|
||||
flags: flags
|
||||
pre_execute: validate
|
||||
execute: init_project
|
||||
},
|
||||
]
|
||||
}
|
||||
cmd.parse(os.args)
|
||||
}
|
||||
|
||||
// gen project based in the `Create.files` info
|
||||
fn validate(cmd Command) ! {
|
||||
if cmd.flags.get_bool('help')! {
|
||||
cmd.execute_help()
|
||||
exit(0)
|
||||
}
|
||||
if cmd.args.len > 1 {
|
||||
cerror('too many arguments.\n')
|
||||
cmd.execute_help()
|
||||
exit(2)
|
||||
}
|
||||
}
|
||||
|
||||
fn new_project(cmd Command) ! {
|
||||
mut c := Create{
|
||||
template: get_template(cmd)
|
||||
new_dir: true
|
||||
}
|
||||
c.prompt(cmd.args)
|
||||
println('Initialising ...')
|
||||
// Generate project files based on `Create.files`.
|
||||
c.create_files_and_directories()
|
||||
|
||||
c.write_vmod()
|
||||
c.write_gitattributes()
|
||||
c.write_editorconfig()
|
||||
c.create_git_repo(c.name)
|
||||
}
|
||||
|
||||
fn init_project(args []string) {
|
||||
mut c := Create{}
|
||||
fn init_project(cmd Command) ! {
|
||||
mut c := Create{
|
||||
template: get_template(cmd)
|
||||
}
|
||||
dir_name := check_name(os.file_name(os.getwd()))
|
||||
if !os.exists('v.mod') {
|
||||
mod_dir_has_hyphens := dir_name.contains('-')
|
||||
c.name = if mod_dir_has_hyphens { dir_name.replace('-', '_') } else { dir_name }
|
||||
c.prompt(args)
|
||||
c.prompt(cmd.args)
|
||||
c.write_vmod()
|
||||
if mod_dir_has_hyphens {
|
||||
println('The directory name `${dir_name}` is invalid as a module name. The module name in `v.mod` was set to `${c.name}`')
|
||||
}
|
||||
}
|
||||
if !os.exists('src/main.v') {
|
||||
c.set_bin_project_files()
|
||||
}
|
||||
println('Initialising ...')
|
||||
c.create_files_and_directories()
|
||||
c.write_gitattributes()
|
||||
c.write_editorconfig()
|
||||
@ -124,15 +154,18 @@ fn (mut c Create) prompt(args []string) {
|
||||
if c.name == '' {
|
||||
c.name = check_name(args[0] or { os.input('Input your project name: ') })
|
||||
if c.name == '' {
|
||||
eprintln('')
|
||||
cerror('project name cannot be empty')
|
||||
exit(1)
|
||||
}
|
||||
if c.name.contains('-') {
|
||||
cerror('"${c.name}" should not contain hyphens')
|
||||
eprintln('')
|
||||
cerror('`${c.name}` should not contain hyphens')
|
||||
exit(1)
|
||||
}
|
||||
if os.is_dir(c.name) {
|
||||
cerror('${c.name} folder already exists')
|
||||
eprintln('')
|
||||
cerror('`${c.name}` folder already exists')
|
||||
exit(3)
|
||||
}
|
||||
}
|
||||
@ -149,12 +182,28 @@ fn (mut c Create) prompt(args []string) {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_template(cmd Command) Template {
|
||||
bin := cmd.flags.get_bool('bin') or { false }
|
||||
lib := cmd.flags.get_bool('lib') or { false }
|
||||
web := cmd.flags.get_bool('web') or { false }
|
||||
if (bin && lib) || (bin && web) || (lib && web) {
|
||||
eprintln("error: can't use more then one template")
|
||||
exit(2)
|
||||
}
|
||||
return match true {
|
||||
lib { .lib }
|
||||
web { .web }
|
||||
else { .bin }
|
||||
}
|
||||
}
|
||||
|
||||
fn cerror(e string) {
|
||||
eprintln('\nerror: ${e}')
|
||||
eprintln('error: ${e}.')
|
||||
}
|
||||
|
||||
fn check_name(name string) string {
|
||||
if name.trim_space().len == 0 {
|
||||
eprintln('')
|
||||
cerror('project name cannot be empty')
|
||||
exit(1)
|
||||
}
|
||||
@ -221,11 +270,12 @@ indent_style = tab
|
||||
}
|
||||
|
||||
fn (c &Create) create_git_repo(dir string) {
|
||||
// Create Git Repo and .gitignore file
|
||||
// Initialize git and add a .gitignore file.
|
||||
if !os.is_dir('${dir}/.git') {
|
||||
res := os.execute('git init ${dir}')
|
||||
if res.exit_code != 0 {
|
||||
cerror('Unable to create git repo')
|
||||
eprintln('')
|
||||
cerror('unable to initialize a git repository')
|
||||
exit(4)
|
||||
}
|
||||
}
|
||||
@ -262,8 +312,22 @@ bin/
|
||||
}
|
||||
|
||||
fn (mut c Create) create_files_and_directories() {
|
||||
// Set project template files for `v new` or when no `.v` files exists during `v init`.
|
||||
if c.new_dir || os.walk_ext('.', '.v').len == 0 {
|
||||
match c.template {
|
||||
.bin { c.set_bin_project_files() }
|
||||
.lib { c.set_lib_project_files() }
|
||||
.web { c.set_web_project_files() }
|
||||
}
|
||||
}
|
||||
for file in c.files {
|
||||
os.mkdir_all(os.dir(file.path)) or { panic(err) }
|
||||
os.write_file(file.path, file.content) or { panic(err) }
|
||||
}
|
||||
kind := match c.template {
|
||||
.bin { 'binary (application)' }
|
||||
.lib { 'library' }
|
||||
.web { 'web' }
|
||||
}
|
||||
println('Created ${kind} project `${c.name}`')
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ fn testsuite_end() {
|
||||
fn init_and_check() ! {
|
||||
os.chdir(test_path)!
|
||||
|
||||
// Keep track of the last modified time of the main file to ensure it is not modifed if it already exists.
|
||||
// Keep track of the last modified time of the main file to ensure it is not modified if it already exists.
|
||||
main_exists := os.exists('src/main.v')
|
||||
main_last_modified := if main_exists { os.file_last_mod_unix('src/main.v') } else { 0 }
|
||||
|
||||
// Initilize project.
|
||||
// Initialize project.
|
||||
os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init.expect')} ${vroot}')
|
||||
|
||||
x := os.execute_or_exit('${vexe} run .')
|
||||
@ -147,13 +147,13 @@ indent_style = tab
|
||||
prepare_test_path()!
|
||||
os.write_file('.gitattributes', git_attributes_content)!
|
||||
os.write_file('.editorconfig', editor_config_content)!
|
||||
os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init.expect')} ${vroot}')
|
||||
|
||||
res := os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init.expect')} ${vroot}')
|
||||
assert res.output.contains('Created binary (application) project `${test_project_dir_name}`')
|
||||
assert os.read_file('.gitattributes')! == git_attributes_content
|
||||
assert os.read_file('.editorconfig')! == editor_config_content
|
||||
}
|
||||
|
||||
fn test_v_init_in_dir_with_invalid_mod_name() {
|
||||
fn test_v_init_in_dir_with_invalid_mod_name_input() {
|
||||
// A project with a directory name with hyphens, which is invalid for a module name.
|
||||
dir_name_with_invalid_mod_name := 'my-proj'
|
||||
corrected_mod_name := 'my_proj'
|
||||
@ -168,3 +168,21 @@ fn test_v_init_in_dir_with_invalid_mod_name() {
|
||||
}
|
||||
assert mod.name == corrected_mod_name
|
||||
}
|
||||
|
||||
fn test_v_init_with_model_arg_input() {
|
||||
prepare_test_path()!
|
||||
model := '--lib'
|
||||
res := os.execute_or_exit('${expect_exe} ${os.join_path(expect_tests_path, 'init_with_model_arg.expect')} ${vroot} ${model}')
|
||||
assert res.output.contains('Created library project `${test_project_dir_name}`'), res.output
|
||||
project_path := os.join_path(test_path)
|
||||
mod := vmod.from_file(os.join_path(project_path, 'v.mod')) or {
|
||||
assert false, err.str()
|
||||
return
|
||||
}
|
||||
assert mod.name == test_project_dir_name
|
||||
assert mod.description == 'My Awesome V Application.'
|
||||
assert mod.version == '0.0.1'
|
||||
assert mod.license == 'MIT'
|
||||
// Assert existence of a model-specific file.
|
||||
assert os.exists(os.join_path(project_path, 'tests', 'square_test.v'))
|
||||
}
|
||||
|
@ -68,12 +68,13 @@ fn test_new_with_name_arg_input() {
|
||||
fn test_new_with_model_arg_input() {
|
||||
prepare_test_path()!
|
||||
project_name := 'my_lib'
|
||||
model := 'lib'
|
||||
os.execute_opt('${expect_exe} ${os.join_path(expect_tests_path, 'new_with_model_arg.expect')} ${vroot} ${project_name} ${model}') or {
|
||||
model := '--lib'
|
||||
os.execute_opt('${expect_exe} ${os.join_path(expect_tests_path, 'new_with_model_arg.expect')} ${vroot} ${model} ${project_name}') or {
|
||||
assert false, err.msg()
|
||||
}
|
||||
project_path := os.join_path(test_module_path, project_name)
|
||||
// Assert mod data set in `new_with_model_arg.expect`.
|
||||
mod := vmod.from_file(os.join_path(test_module_path, project_name, 'v.mod')) or {
|
||||
mod := vmod.from_file(os.join_path(project_path, 'v.mod')) or {
|
||||
assert false, err.str()
|
||||
return
|
||||
}
|
||||
@ -81,4 +82,6 @@ fn test_new_with_model_arg_input() {
|
||||
assert mod.description == 'My Awesome V Project.'
|
||||
assert mod.version == '0.0.1'
|
||||
assert mod.license == 'MIT'
|
||||
// Assert existence of a model-specific file.
|
||||
assert os.exists(os.join_path(project_path, 'tests', 'square_test.v'))
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ module help
|
||||
|
||||
import os
|
||||
|
||||
// Topics whose module uses the cli module.
|
||||
const cli_topics = ['new', 'init']
|
||||
|
||||
fn hdir(base string) string {
|
||||
return os.join_path(base, 'vlib', 'v', 'help')
|
||||
}
|
||||
@ -38,6 +41,10 @@ pub fn print_and_exit(topic string, opts ExitOptions) {
|
||||
exit(fail_code)
|
||||
}
|
||||
}
|
||||
if topic in help.cli_topics {
|
||||
os.system('${@VEXE} ${topic} --help')
|
||||
exit(opts.exit_code)
|
||||
}
|
||||
mut topic_path := ''
|
||||
for path in os.walk_ext(help_dir(), '.txt') {
|
||||
if topic == os.file_name(path).all_before('.txt') {
|
||||
|
@ -49,3 +49,12 @@ fn test_topic_sub_help() {
|
||||
assert res.exit_code == 0, res.output
|
||||
assert res.output != ''
|
||||
}
|
||||
|
||||
fn test_help_topic_with_cli_mod() {
|
||||
res := os.execute_or_exit(vexe + ' help init')
|
||||
assert res.output.contains('Usage: v init [flags]')
|
||||
assert res.output.contains('Sets up a V project within the current directory.')
|
||||
assert res.output.contains('Flags:')
|
||||
assert res.output.contains('--bin Use the template for an executable application [default]')
|
||||
assert res.output.contains('--lib Use the template for a library project.')
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
Sets up a V project within the current directory.
|
||||
|
||||
Usage:
|
||||
v init
|
||||
|
||||
If no '.v' file exists, then will create a 'main.v' file.
|
||||
If no 'v.mod' file exists, one will be created.
|
||||
If the current directory is not already controlled with 'git', will perform
|
||||
'git init' (if git is installed on the system).
|
@ -1,13 +0,0 @@
|
||||
Sets up a new V project
|
||||
|
||||
Usage:
|
||||
v new [NAME] [DESCRIPTION]
|
||||
|
||||
Sets up a new V project with a 'v.mod' file, and a 'main.v' "Hello World"
|
||||
file, and performs 'git init' (if git is installed on the system).
|
||||
|
||||
If NAME is given, the project will be setup in a new directory with that
|
||||
name, and that name will be added to the 'v.mod' file. If no name is given,
|
||||
the user will be prompted for a name.
|
||||
|
||||
If DESCRIPTION is given, the 'v.mod' file is updated with said description.
|
Loading…
x
Reference in New Issue
Block a user