@@ -66,8 +66,11 @@ fn main() {
6666 description: [
6767 'Creates a new V project in a directory with the specified project name.' ,
6868 '' ,
69- 'A setup prompt is started to create a `v.mod` file with the projects metadata.' ,
70- 'The <project_name> argument can be omitted and entered in the prompts dialog.' ,
69+ 'When run in a terminal, a setup prompt is started to create a `v.mod` file with' ,
70+ 'the projects metadata; the <project_name> argument can then be omitted and' ,
71+ 'entered in the prompts dialog. When stdin is not a terminal (piped/redirected,' ,
72+ 'e.g. in CI) the prompts are skipped, defaults are used, and <project_name> is' ,
73+ 'required.' ,
7174 'If git is installed, `git init` will be performed during the setup.' ,
7275 ].join_lines ()
7376 parent: & Command{
@@ -84,6 +87,7 @@ fn main() {
8487 'Sets up a V project within the current directory.' ,
8588 '' ,
8689 "If no `v.mod` exists, a setup prompt is started to create one with the project's metadata." ,
90+ 'The prompts run only when stdin is a terminal; otherwise the defaults are used.' ,
8791 'If no `.v` file exists, a project template is generated. If the current directory is not a' ,
8892 'git project and git is installed, `git init` will be performed during the setup.' ,
8993 ].join_lines ()
@@ -148,12 +152,23 @@ fn init_project(cmd Command) ! {
148152 c.create_git_repo ('.' )
149153}
150154
155+ // prompt_input asks for a line of input, but only when stdin is a terminal.
156+ // When it is not (piped input, CI, some IDE terminals), the interactive prompt
157+ // would block forever waiting for input that never arrives, making
158+ // `v new`/`v init` appear to hang, so return `default` instead. See #28061.
159+ fn prompt_input (prompt string , default string ) string {
160+ if os.is_atty (0 ) == 0 {
161+ return default
162+ }
163+ return os.input (prompt)
164+ }
165+
151166fn (mut c Create) prompt (args []string ) {
152167 if c.name == '' {
153- c.name = check_name (args[0 ] or { os. input ('Input your project name: ' ) })
168+ c.name = check_name (args[0 ] or { prompt_input ('Input your project name: ' , ' ' ) })
154169 if c.name == '' {
155170 eprintln ('' )
156- cerror ('project name cannot be empty' )
171+ cerror ('project name cannot be empty; pass it on the command line, e.g. `v new my_project` ' )
157172 exit (1 )
158173 }
159174 if c.name.contains ('-' ) {
@@ -167,14 +182,14 @@ fn (mut c Create) prompt(args []string) {
167182 exit (3 )
168183 }
169184 }
170- c.description = os. input ('Input your project description: ' )
185+ c.description = prompt_input ('Input your project description: ' , ' ' )
171186 default_version := '0.0.0'
172- c.version = os. input ('Input your project version: (${default_version }) ' )
187+ c.version = prompt_input ('Input your project version: (${default_version }) ' , default_version )
173188 if c.version == '' {
174189 c.version = default_version
175190 }
176191 default_license := 'MIT'
177- c.license = os. input ('Input your project license: (${default_license }) ' )
192+ c.license = prompt_input ('Input your project license: (${default_license }) ' , default_license )
178193 if c.license == '' {
179194 c.license = default_license
180195 }
0 commit comments