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

Commit 45b18a2

Browse files
author
mikkomaa
authored
Merge branch 'master' into annotation-processing-tests-aleksi
2 parents 7a50d41 + ea30c7e commit 45b18a2

15 files changed

Lines changed: 133 additions & 50 deletions

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ Now that you've installed tmc-cli, you can view all available commands by runnin
4646
Once installation is complete, you can log in using `tmc login`. This saves your TMC login information to a configuration file in ~/.config/tmc-cli/ (or %LOCALAPPDATA% on Windows) - you will only have to log in once.
4747
```
4848
~ $ tmc login
49-
username: my-username
50-
password:
5149
server address:
50+
username:
51+
password:
5252
Login successful.
5353
```
5454

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>fi.helsinki.cs.tmc.cli</groupId>
55
<artifactId>tmc-cli</artifactId>
6-
<version>0.5.2</version>
6+
<version>0.6.0</version>
77
<packaging>jar</packaging>
88
<properties>
99
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

src/main/java/fi/helsinki/cs/tmc/cli/Application.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ public void setWorkdir(WorkDir workDir) {
246246
this.workDir = workDir;
247247
}
248248

249+
public void setTmcProjectDirectory(Path path) {
250+
this.settings.setTmcProjectDirectory(path);
251+
}
252+
249253
public HashMap<String, String> getProperties() {
250254
// Loads properties from the global configuration file in .config/tmc-cli/
251255
return this.properties;

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/LoginCommand.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ public void getOptions(Options options) {
3636
@Override
3737
public void run(CommandLine args, Io io) {
3838
this.io = io;
39+
String serverAddress = getLoginInfo(args, "s", "server address: ");
3940
String username = getLoginInfo(args, "u", "username: ");
4041
String password = getLoginInfo(args, "p", "password: ");
41-
String serverAddress = getLoginInfo(args, "s", "server address: ");
42-
42+
4343
Settings settings = new Settings(serverAddress, username, password);
4444
if (loginPossible(settings) && saveLoginSettings(settings)) {
4545
io.println("Login successful.");

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

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

3+
import static fi.helsinki.cs.tmc.langs.domain.RunResult.Status.PASSED;
4+
35
import fi.helsinki.cs.tmc.cli.Application;
46
import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand;
57
import fi.helsinki.cs.tmc.cli.command.core.Command;
68
import fi.helsinki.cs.tmc.cli.io.Color;
79
import fi.helsinki.cs.tmc.cli.io.Io;
810
import fi.helsinki.cs.tmc.cli.io.ResultPrinter;
911
import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver;
12+
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo;
1013
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfoIo;
1114
import fi.helsinki.cs.tmc.cli.tmcstuff.Settings;
1215
import fi.helsinki.cs.tmc.cli.tmcstuff.WorkDir;
@@ -25,6 +28,7 @@
2528
import java.nio.file.Path;
2629
import java.util.List;
2730

31+
2832
@Command(name = "test", desc = "Run local exercise tests")
2933
public class RunTestsCommand extends AbstractCommand {
3034

@@ -58,13 +62,13 @@ public void run(CommandLine args, Io io) {
5862
return;
5963
}
6064
}
61-
String courseName = getCourseName(workDir);
6265
List<String> exerciseNames = workDir.getExerciseNames();
6366

6467
if (exerciseNames.isEmpty()) {
6568
io.println("You have to be in a course directory to run tests");
6669
return;
6770
}
71+
CourseInfo info = CourseInfoIo.load(workDir.getConfigFile());
6872

6973
// Local tests don't require login so make sure tmcCore is never null.
7074
app.createTmcCore(new Settings());
@@ -90,16 +94,30 @@ public void run(CommandLine args, Io io) {
9094

9195
io.println(Color.colorString("Testing: " + name, Color.AnsiColor.ANSI_YELLOW));
9296
//name = name.replace("-", File.separator);
93-
Exercise exercise = new Exercise(name, courseName);
97+
Exercise exercise = info.getExercise(name);
98+
// Exercise exercise = new Exercise(name, courseName);
9499

95100
// TmcCliProgressObserver progobs = new TmcCliProgressObserver(io);
96101
runResult = core.runTests(ProgressObserver.NULL_OBSERVER, exercise).call();
97102
// progobs.end(0);
98103

99-
resultPrinter.printRunResult(runResult, isOnlyExercise, color1, color2);
104+
resultPrinter.printRunResult(runResult, exercise.isCompleted(),
105+
isOnlyExercise, color1, color2);
100106
total += runResult.testResults.size();
101107
passed += ResultPrinter.passedTests(runResult.testResults);
108+
exercise.setAttempted(true);
109+
if (runResult.status == PASSED && !exercise.isCompleted()) {
110+
// add exercise to locally tested exercises
111+
if (!info.getLocalCompletedExercises().contains(exercise.getName())) {
112+
info.getLocalCompletedExercises().add(exercise.getName());
113+
}
114+
} else {
115+
if (info.getLocalCompletedExercises().contains(exercise.getName())) {
116+
info.getLocalCompletedExercises().remove(exercise.getName());
117+
}
118+
}
102119
}
120+
CourseInfoIo.save(info, workDir.getConfigFile());
103121
if (total > 0 && !isOnlyExercise) {
104122
// Print a progress bar showing how the ratio of passed exercises
105123
// But only if more than one exercise was tested
@@ -115,15 +133,6 @@ public void run(CommandLine args, Io io) {
115133
}
116134
}
117135

118-
private String getCourseName(WorkDir dirUtil) {
119-
Path courseDir = dirUtil.getCourseDirectory();
120-
try {
121-
return courseDir.getName(courseDir.getNameCount() - 1).toString();
122-
} catch (Exception e) {
123-
}
124-
return null;
125-
}
126-
127136
private String[] parseArgs(CommandLine args) {
128137
this.showPassed = args.hasOption("a");
129138
this.showDetails = args.hasOption("d");

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

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

3+
import static fi.helsinki.cs.tmc.core.domain.submission.SubmissionResult.TestResultStatus.NONE_FAILED;
4+
35
import fi.helsinki.cs.tmc.cli.Application;
46
import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand;
57
import fi.helsinki.cs.tmc.cli.command.core.Command;
@@ -38,6 +40,8 @@ public class SubmitCommand extends AbstractCommand {
3840
public void getOptions(Options options) {
3941
options.addOption("a", "all", false, "Show all test results");
4042
options.addOption("d", "details", false, "Show detailed error message");
43+
options.addOption("c", "completed", false,
44+
"Filter out exercises that haven't been locally tested");
4145
}
4246

4347
@Override
@@ -58,14 +62,25 @@ public void run(CommandLine args, Io io) {
5862
WorkDir workDir = app.getWorkDir();
5963
for (String exercise : exercisesFromArgs) {
6064
if (!workDir.addPath(exercise)) {
61-
io.println("Error: '" + exercise + "' is not a valid exercise.");
65+
io.println("Error: " + exercise + " is not a valid exercise.");
6266
return;
6367
}
6468
}
6569

66-
List<String> exerciseNames = workDir.getExerciseNames();
70+
List<String> exerciseNames;
71+
if (args.hasOption("c")) {
72+
workDir.addPath(workDir.getCourseDirectory());
73+
exerciseNames = workDir.getExerciseNames(true, true, false);
74+
} else {
75+
exerciseNames = workDir.getExerciseNames();
76+
}
77+
6778
if (exerciseNames.isEmpty()) {
68-
io.println("You have to be in a course directory to submit");
79+
if (args.hasOption("c") && workDir.getCourseDirectory() != null) {
80+
io.println("No locally tested exercises.");
81+
return;
82+
}
83+
io.println("No exercises specified.");
6984
return;
7085
}
7186

@@ -95,8 +110,17 @@ public void run(CommandLine args, Io io) {
95110
resultPrinter.printSubmissionResult(result, isOnlyExercise, color1, color2);
96111
total += result.getTestCases().size();
97112
passed += ResultPrinter.passedTests(result.getTestCases());
113+
114+
exercise.setAttempted(true);
115+
if (result.getTestResultStatus() == NONE_FAILED) {
116+
if (info.getLocalCompletedExercises().contains(exercise.getName())) {
117+
info.getLocalCompletedExercises().remove(exercise.getName());
118+
}
119+
exercise.setCompleted(true);
120+
}
98121
}
99122
}
123+
CourseInfoIo.save(info, workDir.getConfigFile());
100124
if (total > 0 && !isOnlyExercise) {
101125
// Print a progress bar showing how the ratio of passed exercises
102126
io.println("");

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import fi.helsinki.cs.tmc.cli.command.core.AbstractCommand;
44
import fi.helsinki.cs.tmc.cli.command.core.Command;
5+
import fi.helsinki.cs.tmc.cli.io.Color;
56
import fi.helsinki.cs.tmc.cli.io.Io;
67
import fi.helsinki.cs.tmc.cli.io.TmcCliProgressObserver;
78
import fi.helsinki.cs.tmc.cli.tmcstuff.CourseInfo;
@@ -65,8 +66,10 @@ public void updateExercises(TmcCore core, CourseInfo info, Path configFile) {
6566
printExercises(exerciseUpdater.getUpdatedExercises(), "Modified exercises:");
6667
io.println("");
6768

69+
Color.AnsiColor color1 = getApp().getColor("progressbar-left");
70+
Color.AnsiColor color2 = getApp().getColor("progressbar-right");
6871
List<Exercise> downloaded = exerciseUpdater.downloadUpdates(
69-
new TmcCliProgressObserver(io));
72+
new TmcCliProgressObserver(io, color1, color2));
7073
if (downloaded.isEmpty()) {
7174
io.println("Failed to download exercises");
7275
return;

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void printSubmissionResult(SubmissionResult result, Boolean printProgress
107107
}
108108
}
109109

110-
public void printRunResult(RunResult result, Boolean printProgressBar,
110+
public void printRunResult(RunResult result, Boolean submitted, Boolean printProgressBar,
111111
Color.AnsiColor color1, Color.AnsiColor color2) {
112112
printTestResults(result.testResults);
113113
this.total = result.testResults.size();
@@ -120,9 +120,10 @@ public void printRunResult(RunResult result, Boolean printProgressBar,
120120
String msg = null;
121121
switch (result.status) {
122122
case PASSED:
123-
msg = "All tests passed!";
124-
msg = Color.colorString(msg, Color.AnsiColor.ANSI_GREEN)
125-
+ " Submit to server with 'tmc submit'";
123+
msg = Color.colorString("All tests passed!", Color.AnsiColor.ANSI_GREEN);
124+
if (!submitted) {
125+
msg += " Submit to server with 'tmc submit'";
126+
}
126127
break;
127128
case TESTS_FAILED:
128129
msg = "Please review your answer before submitting";

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,10 @@ public Course getCourse() {
4646
public List<String> getLocalCompletedExercises() {
4747
// Check for null pointer in case of old .tmc.json files
4848
// Remove this when we are sure nobody's using 0.5.1 anymore
49-
if (this.localCompletedExercises != null) {
50-
return this.localCompletedExercises;
51-
} else {
52-
return new ArrayList<String>();
49+
if (this.localCompletedExercises == null) {
50+
this.localCompletedExercises = new ArrayList<String>();
5351
}
52+
return this.localCompletedExercises;
5453
}
5554

5655
public List<Exercise> getExercises() {

0 commit comments

Comments
 (0)