Skip to content

Commit 8125d98

Browse files
mehdi.cheracher@gmail.comchermehdi
authored andcommitted
Add create command.
1 parent 3cdd6b0 commit 8125d98

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed

commands/create.go

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package commands
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"github.com/chermehdi/egor/config"
7+
"github.com/fatih/color"
8+
"github.com/urfave/cli/v2"
9+
"io"
10+
"os"
11+
"strings"
12+
)
13+
14+
func ReadLine(reader io.Reader) string {
15+
result := ""
16+
r := bufio.NewReader(reader)
17+
for true {
18+
readBytes, isPrefix, _ := r.ReadLine()
19+
result += string(readBytes)
20+
if !isPrefix {
21+
break
22+
}
23+
}
24+
return result
25+
}
26+
27+
func askInt(reader io.Reader, question string, defaultValue float64) float64 {
28+
color.Green("%s (%d by default): ", question, int(defaultValue))
29+
input := ReadLine(reader)
30+
var value = -1
31+
n, err := fmt.Sscanf(input, "%d", &value)
32+
if err != nil || n == 0 || value == -1 {
33+
return defaultValue
34+
}
35+
return float64(value)
36+
}
37+
38+
func askBool(reader io.Reader, question string, defaultValue bool) bool {
39+
value := "N"
40+
if defaultValue {
41+
value = "Y"
42+
}
43+
response := ask(reader, question, value)
44+
return response == "Y" || response == "y"
45+
}
46+
47+
func ask(reader io.Reader, question, defaultValue string) string {
48+
color.Green("%s (%s by default): ", question, defaultValue)
49+
value := ReadLine(reader)
50+
if value == "" {
51+
return defaultValue
52+
}
53+
return value
54+
}
55+
56+
func askEndOfFile(question string) string {
57+
color.Green(question)
58+
scanner := bufio.NewScanner(os.Stdin)
59+
result := ""
60+
for scanner.Scan() {
61+
result += scanner.Text()
62+
result += "\n"
63+
}
64+
return result
65+
}
66+
67+
func fillTaskFromQuestions(task *config.Task, reader io.Reader) error {
68+
task.Name = ask(reader, "Task Name?", task.Name)
69+
task.TimeLimit = askInt(reader, "Time limit in ms?", task.TimeLimit)
70+
testCases := askInt(reader, "Number of test cases?", 0)
71+
for i := 0; i < int(testCases); i++ {
72+
input := askEndOfFile(fmt.Sprintf("Enter testcase #%d input:\n", i))
73+
output := askEndOfFile(fmt.Sprintf("Enter testcase #%d expected output:\n", i))
74+
task.Tests = append(task.Tests, config.TestCase{
75+
Input: input,
76+
Output: output,
77+
})
78+
}
79+
// TODO(chermehdi): This information is irrelevant now, because we don't do anything special with the languages sections, make sure to remove
80+
// When this is updated.
81+
isJava := askBool(reader, "Is your language Java (you will be asked other questions if it's a yes)? (Y/N)?", false)
82+
if isJava {
83+
className := ask(reader, "\nMain class name?", "Main")
84+
// Avoid class names with strings
85+
className = strings.Join(strings.Split(className, " "), "")
86+
task.Languages["java"] = config.LanguageDescription{
87+
MainClass: "Main",
88+
TaskClass: className,
89+
}
90+
}
91+
return nil
92+
}
93+
94+
// Creates a task directory structure, either in a default manner (a task with a generic name, and default settings).
95+
// Or by specifying the values in an interactive manner, if `-i` flag is specified.
96+
func CreateTaskAction(context *cli.Context) error {
97+
// Default task containing default values.
98+
task := config.Task{
99+
Name: "Random Task",
100+
TimeLimit: 2000,
101+
MemoryLimit: 256,
102+
Tests: nil,
103+
TestType: "single",
104+
Input: config.IOType{
105+
Type: "stdin",
106+
},
107+
Output: config.IOType{
108+
Type: "stdout",
109+
},
110+
Languages: nil,
111+
}
112+
configuration, err := config.LoadDefaultConfiguration()
113+
if err != nil {
114+
return err
115+
}
116+
curDir, err := os.Getwd()
117+
if err != nil {
118+
return err
119+
}
120+
if context.Bool("i") {
121+
// interactive mode
122+
if err = fillTaskFromQuestions(&task, os.Stdin); err != nil {
123+
return err
124+
}
125+
}
126+
location, err := CreateDirectoryStructure(task, *configuration, curDir)
127+
if err != nil {
128+
return err
129+
}
130+
color.Green("Task created at %s\n", location)
131+
return nil
132+
}
133+
134+
// Command will ask the user for a bunch of questions about the task name
135+
// Input and outputs and other metadata required to create the task
136+
var CreateTaskCommand = cli.Command{
137+
Name: "create",
138+
Aliases: []string{"c"},
139+
Usage: "Create a new task directory",
140+
UsageText: "egor showcases",
141+
Action: CreateTaskAction,
142+
Flags: []cli.Flag{
143+
&cli.BoolFlag{
144+
Name: "interactive",
145+
Aliases: []string{"i"},
146+
Usage: "Create the task in an interactive form (answer questions, egor will do the rest)",
147+
Value: false,
148+
},
149+
},
150+
}

main.go

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ func main() {
4848
&commands.CopyCommand,
4949
&commands.PrintCaseCommand,
5050
&commands.TestCommand,
51+
&commands.CreateTaskCommand,
5152
},
5253
}
5354

0 commit comments

Comments
 (0)