Skip to content

Commit 36cea94

Browse files
authored
Merge pull request #47 from chermehdi/feature/create-task
Feature/create task
2 parents 3cdd6b0 + df7c392 commit 36cea94

File tree

2 files changed

+153
-0
lines changed

2 files changed

+153
-0
lines changed

commands/create.go

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
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+
// Fill the given task reference according to input coming from the reader object.
68+
func fillTaskFromQuestions(task *config.Task, reader io.Reader) error {
69+
task.Name = ask(reader, "Task Name?", task.Name)
70+
task.TimeLimit = askInt(reader, "Time limit in ms?", task.TimeLimit)
71+
testCases := askInt(reader, "Number of test cases?", 0)
72+
for i := 0; i < int(testCases); i++ {
73+
input := askEndOfFile(fmt.Sprintf("Enter testcase #%d input:\n", i))
74+
output := askEndOfFile(fmt.Sprintf("Enter testcase #%d expected output:\n", i))
75+
task.Tests = append(task.Tests, config.TestCase{
76+
Input: input,
77+
Output: output,
78+
})
79+
}
80+
// TODO(chermehdi): This information is irrelevant now, because we don't do anything special with the languages
81+
// sections, make sure to remove When this is updated.
82+
isJava := askBool(reader, "Is your language Java (you will be asked other questions if it's a yes)? (Y/N)?",
83+
false)
84+
if isJava {
85+
className := ask(reader, "\nMain class name?", "Main")
86+
// Avoid class names with strings
87+
className = strings.Join(strings.Split(className, " "), "")
88+
task.Languages["java"] = config.LanguageDescription{
89+
MainClass: "Main",
90+
TaskClass: className,
91+
}
92+
}
93+
return nil
94+
}
95+
96+
// Creates a task directory structure, either in a default manner (a task with a generic name, and default settings).
97+
// Or by specifying the values in an interactive manner, if `-i` flag is specified.
98+
func CreateTaskAction(context *cli.Context) error {
99+
// Default task containing default values.
100+
task := config.Task{
101+
Name: "Random Task",
102+
TimeLimit: 10000,
103+
MemoryLimit: 256,
104+
Tests: nil,
105+
TestType: "single",
106+
Input: config.IOType{
107+
Type: "stdin",
108+
},
109+
Output: config.IOType{
110+
Type: "stdout",
111+
},
112+
Languages: nil,
113+
}
114+
configuration, err := config.LoadDefaultConfiguration()
115+
if err != nil {
116+
return err
117+
}
118+
curDir, err := os.Getwd()
119+
if err != nil {
120+
return err
121+
}
122+
if context.Bool("i") {
123+
// interactive mode
124+
if err = fillTaskFromQuestions(&task, os.Stdin); err != nil {
125+
return err
126+
}
127+
}
128+
location, err := CreateDirectoryStructure(task, *configuration, curDir)
129+
if err != nil {
130+
return err
131+
}
132+
color.Green("Task created at %s\n", location)
133+
return nil
134+
}
135+
136+
// Command will ask the user for a bunch of questions about the task name
137+
// Input and outputs and other metadata required to create the task
138+
var CreateTaskCommand = cli.Command{
139+
Name: "create",
140+
Aliases: []string{"c"},
141+
Usage: "Create a new task directory",
142+
UsageText: "egor create or egor create -i",
143+
Action: CreateTaskAction,
144+
Flags: []cli.Flag{
145+
&cli.BoolFlag{
146+
Name: "interactive",
147+
Aliases: []string{"i"},
148+
Usage: "Create the task in an interactive form (answer questions, egor will do the rest)",
149+
Value: false,
150+
},
151+
},
152+
}

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)