Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 0b8a97f

Browse files
author
jclc
committed
Merge branch 'cache-test-results-jclc' of github.com:tmc-cli/tmc-cli into cache-test-results-jclc
2 parents dae2f06 + 0d763e1 commit 0b8a97f

10 files changed

Lines changed: 293 additions & 78 deletions

File tree

src/main/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommand.java

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package fi.helsinki.cs.tmc.cli.command;
22

3+
import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_BLUE;
4+
import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_GREEN;
5+
import static fi.helsinki.cs.tmc.cli.io.Color.AnsiColor.ANSI_RED;
6+
37
import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand;
48
import fi.helsinki.cs.tmc.cli.command.core.Command;
9+
import fi.helsinki.cs.tmc.cli.io.Color;
510
import fi.helsinki.cs.tmc.cli.io.Io;
611
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo;
712
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo;
@@ -53,13 +58,13 @@ public void run(CommandLine args, Io io) {
5358
if (workDir.getExerciseNames().size() == 1 && stringArgs.length == 0) {
5459
String currentExercise = workDir.getExerciseNames().get(0);
5560
exercise = info.getExercise(currentExercise);
56-
printExerciseDetails();
61+
printOneExercise(args.hasOption("a"));
5762
return;
5863

5964
} else if (stringArgs.length != 0) {
6065
if (info.getExercise(stringArgs[0]) != null) {
6166
exercise = info.getExercise(stringArgs[0]);
62-
printExerciseDetails();
67+
printOneExercise(args.hasOption("a"));
6368
return;
6469

6570
} else {
@@ -109,11 +114,32 @@ private void printCourseDetails() {
109114
io.println("CometUrl: " + course.getCometUrl());
110115
}
111116

112-
private void printExerciseDetails() {
113-
io.println(exercise.getName());
114-
io.println("Completed: " + exercise.isCompleted());
115-
io.println("Attempted: " + exercise.isAttempted());
116-
io.println("Deadline: " + exercise.getDeadline());
117+
private void printOneExercise(boolean showAll) {
118+
if (showAll) {
119+
printExercise(exercise);
120+
} else {
121+
printExerciseShort();
122+
}
123+
}
124+
125+
private void printExerciseShort() {
126+
io.println("Exercise: " + exercise.getName());
127+
io.println("Deadline: " + getDeadline(exercise));
128+
io.println(formatString("completed", exercise.isCompleted()));
129+
if (!exercise.isCompleted() && exercise.isAttempted()) {
130+
io.println(Color.colorString("attempted", ANSI_BLUE));
131+
}
132+
if (exercise.requiresReview()) {
133+
io.println(formatString("reviewed", exercise.isReviewed()));
134+
}
135+
}
136+
137+
private String formatString(String string, boolean color) {
138+
if (color) {
139+
return Color.colorString(string, ANSI_GREEN);
140+
} else {
141+
return Color.colorString("not " + string, ANSI_RED);
142+
}
117143
}
118144

119145
private void printExercises(boolean showAll) {
@@ -169,4 +195,13 @@ private void printExercise(Exercise exercise) {
169195
io.println(" Checksum: " + exercise.getChecksum());
170196
io.println("");
171197
}
198+
199+
private String getDeadline(Exercise exercise) {
200+
String deadline = exercise.getDeadline();
201+
if (deadline == null) {
202+
return "not available";
203+
}
204+
deadline = deadline.substring(0, 19);
205+
return deadline.replace("T", " at ");
206+
}
172207
}

src/main/java/fi/helsinki/cs/tmc/cli/command/DownloadExercisesCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void run(CommandLine args, Io io) {
7474
.resolve(stringArgs[0])
7575
.resolve(CourseInfoIo.COURSE_CONFIG);
7676
CourseInfo info = app.createCourseInfo(course);
77-
info.setExercises(exercises);
77+
info.setExercises(course.getExercises());
7878
CourseInfoIo.save(info, configFile);
7979
}
8080

src/main/java/fi/helsinki/cs/tmc/cli/command/SubmitCommand.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir;
1717
import fi.helsinki.cs.tmc.core.TmcCore;
1818
import fi.helsinki.cs.tmc.core.domain.Course;
19+
import fi.helsinki.cs.tmc.core.domain.Exercise;
1920
import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult;
2021

2122
import org.apache.commons.cli.CommandLine;
2223
import org.apache.commons.cli.Options;
2324
import org.slf4j.Logger;
2425
import org.slf4j.LoggerFactory;
2526

27+
import java.nio.file.Path;
2628
import java.util.List;
2729

2830
@Command(name = "submit", desc = "Submit exercises")
@@ -77,11 +79,8 @@ public void run(CommandLine args, Io io) {
7779
}
7880

7981
CourseInfo info = CourseInfoIo.load(workDir.getConfigFile());
80-
String courseName = info.getCourseName();
81-
Course course = TmcUtil.findCourse(core, courseName);
82-
83-
if (course == null) {
84-
io.println("Could not fetch course info from server.");
82+
Course currentCourse = info.getCourse();
83+
if (currentCourse == null) {
8584
return;
8685
}
8786

@@ -93,10 +92,12 @@ public void run(CommandLine args, Io io) {
9392
Color.AnsiColor color1 = app.getColor("testresults-left");
9493
Color.AnsiColor color2 = app.getColor("testresults-right");
9594

96-
for (String exerciseName : exerciseNames) {
97-
io.println(Color.colorString("Submitting: " + exerciseName,
95+
List<Exercise> submitExercises = info.getExercises(exerciseNames);
96+
97+
for (Exercise exercise : submitExercises) {
98+
io.println(Color.colorString("Submitting: " + exercise.getName(),
9899
Color.AnsiColor.ANSI_YELLOW));
99-
SubmissionResult result = TmcUtil.submitExercise(core, course, exerciseName);
100+
SubmissionResult result = TmcUtil.submitExercise(core, exercise);
100101
if (result == null) {
101102
io.println("Submission failed.");
102103
} else {
@@ -120,10 +121,34 @@ public void run(CommandLine args, Io io) {
120121
io.println("Total tests passed: " + passed + "/" + total);
121122
io.println(TmcCliProgressObserver.getPassedTestsBar(passed, total, color1, color2));
122123
}
123-
checkForExerciseUpdates(core, course);
124+
125+
updateCourseJson(core, submitExercises, info, workDir.getConfigFile());
126+
checkForExerciseUpdates(core, currentCourse);
127+
}
128+
129+
protected void updateCourseJson(TmcCore core, List<Exercise> submittedExercises,
130+
CourseInfo courseInfo, Path courseInfoFile) {
131+
132+
Course updatedCourse = TmcUtil.findCourse(core, courseInfo.getCourseName());
133+
if (updatedCourse == null) {
134+
io.println("Failed to update .tmc.json file for course " + courseInfo.getCourseName());
135+
return;
136+
}
137+
138+
for (Exercise submitted : submittedExercises) {
139+
Exercise updatedEx = TmcUtil.findExercise(updatedCourse, submitted.getName());
140+
if (updatedEx == null) {
141+
// Does this reaaally ever happen?
142+
io.println("Failed to update .tmc.json file for exercise " + submitted.getName()
143+
+ ". The exercise doesn't exist in server anymore.");
144+
continue;
145+
}
146+
courseInfo.replaceOldExercise(updatedEx);
147+
}
148+
CourseInfoIo.save(courseInfo, courseInfoFile);
124149
}
125150

126-
public void checkForExerciseUpdates(TmcCore core, Course course) {
151+
protected void checkForExerciseUpdates(TmcCore core, Course course) {
127152
ExerciseUpdater exerciseUpdater = new ExerciseUpdater(core, course);
128153
if (!exerciseUpdater.updatesAvailable()) {
129154
return;

src/main/java/fi/helsinki/cs/tmc/cli/io/ResultPrinter.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package fi.helsinki.cs.tmc.cli.io;
22

3-
import fi.helsinki.cs.tmc.cli.Application;
43
import fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult;
54
import fi.helsinki.cs.tmc.langs.domain.RunResult;
5+
import fi.helsinki.cs.tmc.langs.domain.SpecialLogs;
66
import fi.helsinki.cs.tmc.langs.domain.TestResult;
77

88
import java.util.List;
@@ -56,9 +56,27 @@ public void printSubmissionResult(SubmissionResult result, Boolean printProgress
5656

5757
printTestResults(result.getTestCases());
5858

59-
if (result.getStatus() == SubmissionResult.Status.ERROR) {
60-
io.println("");
61-
io.println(result.getError());
59+
switch (result.getStatus()) {
60+
case ERROR:
61+
io.println("");
62+
io.println(result.getError());
63+
break;
64+
case FAIL:
65+
String valgrind = result.getValgrind();
66+
if (valgrind != null && !valgrind.isEmpty()) {
67+
io.println(Color.colorString("Valgrind error:",
68+
Color.AnsiColor.ANSI_RED));
69+
io.println(valgrind);
70+
return;
71+
}
72+
break;
73+
case PROCESSING:
74+
io.println("PROCESSING");
75+
break;
76+
case OK:
77+
//io.println("OK");
78+
break;
79+
default:
6280
}
6381

6482
if (printProgressBar && this.total > 0) {
@@ -85,7 +103,6 @@ public void printSubmissionResult(SubmissionResult result, Boolean printProgress
85103
if (msg != null) {
86104
io.println(msg);
87105
}
88-
return;
89106
}
90107

91108
public void printRunResult(RunResult result, Boolean submitted, Boolean printProgressBar,
@@ -112,6 +129,12 @@ public void printRunResult(RunResult result, Boolean submitted, Boolean printPro
112129
case COMPILE_FAILED:
113130
msg = ResultPrinter.COMPILE_ERROR_MESSAGE;
114131
break;
132+
case TESTRUN_INTERRUPTED:
133+
msg = "Testrun interrupted";
134+
break;
135+
case GENERIC_ERROR:
136+
msg = new String(result.logs.get(SpecialLogs.GENERIC_ERROR_MESSAGE));
137+
break;
115138
default:
116139
}
117140
if (msg != null) {

src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/CourseInfo.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,20 @@ public List<Exercise> getExercises() {
5656
return this.course.getExercises();
5757
}
5858

59+
/**
60+
* Get a list of exercises by their names.
61+
*/
62+
public List<Exercise> getExercises(List<String> exerciseNames) {
63+
List<Exercise> exercises = new ArrayList<>();
64+
for (String exerciseName : exerciseNames) {
65+
Exercise exercise = getExercise(exerciseName);
66+
if (exercise != null) {
67+
exercises.add(exercise);
68+
}
69+
}
70+
return exercises;
71+
}
72+
5973
public List<String> getExerciseNames() {
6074
List<String> names = new ArrayList<>();
6175
for (Exercise ex : this.course.getExercises()) {
@@ -77,6 +91,37 @@ public void setExercises(List<Exercise> exercises) {
7791
this.course.setExercises(exercises);
7892
}
7993

94+
/**
95+
* Replaces an old identically named exercise with a new one. Adds if no old exercise is found.
96+
*/
97+
public void replaceOldExercise(Exercise newExercise) {
98+
List<Exercise> exercises = getExercises();
99+
String exerciseName = newExercise.getName();
100+
101+
Exercise oldExercise = null;
102+
for (Exercise exercise : exercises) {
103+
if (exercise.getName().equals(exerciseName)) {
104+
oldExercise = exercise;
105+
break;
106+
}
107+
}
108+
109+
if (oldExercise == null) {
110+
exercises.add(newExercise);
111+
} else {
112+
int index = exercises.indexOf(oldExercise);
113+
exercises.set(index, newExercise);
114+
}
115+
116+
setExercises(exercises);
117+
}
118+
119+
public void replaceOldExercises(List<Exercise> newExercises) {
120+
for (Exercise newExercise : newExercises) {
121+
replaceOldExercise(newExercise);
122+
}
123+
}
124+
80125
public void removeProperty(String prop) {
81126
this.properties.remove(prop);
82127
}

src/main/java/fi/helsinki/cs/tmc/cli/tmcstuff/TmcUtil.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package fi.helsinki.cs.tmc.cli.tmcstuff;
22

3-
import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver;
43
import fi.helsinki.cs.tmc.core.TmcCore;
54
import fi.helsinki.cs.tmc.core.commands.GetUpdatableExercises.UpdateResult;
65
import fi.helsinki.cs.tmc.core.domain.Course;
@@ -65,7 +64,7 @@ public static Exercise findExercise(Course course, String name) {
6564
}
6665

6766
public static List<Exercise> downloadExercises(TmcCore core, List<Exercise> exercises,
68-
ProgressObserver progobs) {
67+
ProgressObserver progobs) {
6968
try {
7069
return core.downloadOrUpdateExercises(progobs, exercises).call();
7170
} catch (Exception e) {
@@ -75,7 +74,7 @@ public static List<Exercise> downloadExercises(TmcCore core, List<Exercise> exer
7574
}
7675

7776
public static List<Exercise> downloadAllExercises(TmcCore core, Course course,
78-
ProgressObserver progobs) {
77+
ProgressObserver progobs) {
7978
if (!course.isExercisesLoaded()) {
8079
course = getDetails(core, course);
8180
}
@@ -84,17 +83,15 @@ public static List<Exercise> downloadAllExercises(TmcCore core, Course course,
8483
}
8584

8685
public static SubmissionResult submitExercise(TmcCore core, Course course, String name) {
87-
// Exercise has directories separated with a - but core needs them to be separated with a / for submission
8886
Exercise exercise = TmcUtil.findExercise(course, name);
89-
//String fixedName = exercise.getName().replace("-", File.separator);
90-
//exercise.setName(fixedName);
87+
return submitExercise(core, exercise);
88+
}
89+
90+
public static SubmissionResult submitExercise(TmcCore core, Exercise exercise) {
9191
try {
92-
// TODO: replace null-observer with a real observer
93-
// once it shows up correctly in core/langs
94-
return core.submit(ProgressObserver.NULL_OBSERVER,
95-
exercise).call();
96-
} catch (Exception e) {
97-
logger.warn("Failed to submit the exercise", e);
92+
return core.submit(ProgressObserver.NULL_OBSERVER, exercise).call();
93+
} catch (Exception ex) {
94+
logger.warn("Failed to submit the exercise", ex);
9895
return null;
9996
}
10097
}

src/test/java/fi/helsinki/cs/tmc/cli/command/CourseInfoCommandTest.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public void printExerciseIfInExerciseDirectoryWithoutParameters() {
149149
String[] args = {"info"};
150150
app.run(args);
151151
assertTrue(io.out().contains(EXERCISE1_NAME));
152-
assertTrue(io.out().contains("Completed: "));
152+
assertTrue(io.out().contains("Exercise"));
153153
}
154154

155155
@Test
@@ -159,7 +159,7 @@ public void printExerciseIfInCourseDirectoryAndGivenExerciseName() {
159159
String[] args = {"info", EXERCISE1_NAME};
160160
app.run(args);
161161
assertTrue(io.out().contains(EXERCISE1_NAME));
162-
assertTrue(io.out().contains("Completed: "));
162+
assertTrue(io.out().contains("Exercise"));
163163
}
164164

165165
@Test
@@ -207,4 +207,15 @@ public void printsErrorIfInCourseDirectoryAndGivenCourseNameThatDoesntExist() {
207207
app.run(args);
208208
assertTrue(io.out().contains("exercise"));
209209
}
210+
211+
@Test
212+
public void printsLongExerciseInfoWithOption() {
213+
workDir = new WorkDir(pathToDummyExercise);
214+
app.setWorkdir(workDir);
215+
String[] args = {"info", "-a"};
216+
app.run(args);
217+
218+
assertTrue(io.out().contains("Exercise name"));
219+
assertTrue(io.out().contains("Is returnable"));
220+
}
210221
}

0 commit comments

Comments
 (0)