Skip to content

Commit 2ecab2c

Browse files
committed
Warn on unmaintained Python
1 parent 16a826d commit 2ecab2c

File tree

17 files changed

+261
-117
lines changed

17 files changed

+261
-117
lines changed

plugins/csharp/src/plugin.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::io::{BufReader, Cursor, Read, Seek};
1111
use std::path::{Path, PathBuf};
1212
use std::time::Duration;
1313
use tmc_langs_framework::{
14+
anyhow,
1415
command::TmcCommand,
1516
domain::{
1617
ExerciseDesc, RunResult, RunStatus, Strategy, TestDesc, TestResult, ValidationResult,
@@ -154,7 +155,12 @@ impl LanguagePlugin for CSharpPlugin {
154155
}
155156

156157
/// Runs --generate-points-file and parses the generated .tmc_available_points.json.
157-
fn scan_exercise(&self, path: &Path, exercise_name: String) -> Result<ExerciseDesc, TmcError> {
158+
fn scan_exercise(
159+
&self,
160+
path: &Path,
161+
exercise_name: String,
162+
_warnings: &mut Vec<anyhow::Error>,
163+
) -> Result<ExerciseDesc, TmcError> {
158164
let exercise_desc_json_path = path.join(".tmc_available_points.json");
159165
if exercise_desc_json_path.exists() {
160166
file_util::remove_file(&exercise_desc_json_path)?;
@@ -189,6 +195,7 @@ impl LanguagePlugin for CSharpPlugin {
189195
&self,
190196
path: &Path,
191197
timeout: Option<Duration>,
198+
_warnings: &mut Vec<anyhow::Error>,
192199
) -> Result<RunResult, TmcError> {
193200
let test_results_path = path.join(".tmc_test_results.json");
194201
if test_results_path.exists() {
@@ -384,7 +391,7 @@ mod test {
384391
let plugin = CSharpPlugin::new();
385392
let temp = copy_test_dir("tests/data/PassingProject");
386393
let scan = plugin
387-
.scan_exercise(temp.path(), "name".to_string())
394+
.scan_exercise(temp.path(), "name".to_string(), &mut vec![])
388395
.unwrap();
389396
assert_eq!(scan.name, "name");
390397
assert_eq!(scan.tests.len(), 6);
@@ -395,7 +402,7 @@ mod test {
395402
init();
396403
let plugin = CSharpPlugin::new();
397404
let temp = copy_test_dir("tests/data/PassingProject");
398-
let res = plugin.run_tests(temp.path()).unwrap();
405+
let res = plugin.run_tests(temp.path(), &mut vec![]).unwrap();
399406
assert_eq!(res.status, RunStatus::Passed);
400407
assert_eq!(res.test_results.len(), 2);
401408
for tr in res.test_results {
@@ -409,7 +416,7 @@ mod test {
409416
init();
410417
let plugin = CSharpPlugin::new();
411418
let temp = copy_test_dir("tests/data/FailingProject");
412-
let res = plugin.run_tests(temp.path()).unwrap();
419+
let res = plugin.run_tests(temp.path(), &mut vec![]).unwrap();
413420
assert_eq!(res.status, RunStatus::TestsFailed);
414421
assert_eq!(res.test_results.len(), 1);
415422
let test_result = &res.test_results[0];
@@ -425,7 +432,7 @@ mod test {
425432
init();
426433
let plugin = CSharpPlugin::new();
427434
let temp = copy_test_dir("tests/data/NonCompilingProject");
428-
let res = plugin.run_tests(temp.path()).unwrap();
435+
let res = plugin.run_tests(temp.path(), &mut vec![]).unwrap();
429436
assert_eq!(res.status, RunStatus::CompileFailed);
430437
assert!(!res.logs.is_empty());
431438
assert!(res
@@ -448,7 +455,7 @@ mod test {
448455
.join("obj");
449456
assert!(!bin_path.exists());
450457
assert!(!obj_path_test.exists());
451-
plugin.run_tests(temp.path()).unwrap();
458+
plugin.run_tests(temp.path(), &mut vec![]).unwrap();
452459
assert!(bin_path.exists());
453460
assert!(obj_path_test.exists());
454461
plugin.clean(temp.path()).unwrap();

plugins/java/src/ant.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::ffi::OsStr;
1010
use std::path::{Path, PathBuf};
1111
use std::time::Duration;
1212
use tmc_langs_framework::{
13+
anyhow,
1314
command::TmcCommand,
1415
domain::{ExerciseDesc, RunResult, ValidationResult},
1516
io::file_util,
@@ -78,7 +79,12 @@ impl LanguagePlugin for AntPlugin {
7879
Ok(Some(self.run_checkstyle(&locale, path)?))
7980
}
8081

81-
fn scan_exercise(&self, path: &Path, exercise_name: String) -> Result<ExerciseDesc, TmcError> {
82+
fn scan_exercise(
83+
&self,
84+
path: &Path,
85+
exercise_name: String,
86+
_warnings: &mut Vec<anyhow::Error>,
87+
) -> Result<ExerciseDesc, TmcError> {
8288
if !Self::is_exercise_type_correct(path) {
8389
return JavaError::InvalidExercise(path.to_path_buf()).into();
8490
}
@@ -91,6 +97,7 @@ impl LanguagePlugin for AntPlugin {
9197
&self,
9298
project_root_path: &Path,
9399
_timeout: Option<Duration>,
100+
_warnings: &mut Vec<anyhow::Error>,
94101
) -> Result<RunResult, TmcError> {
95102
Ok(self.run_java_tests(project_root_path)?)
96103
}
@@ -416,7 +423,7 @@ mod test {
416423
let test_path = temp_dir.path();
417424
let plugin = AntPlugin::new().unwrap();
418425
let exercises = plugin
419-
.scan_exercise(&test_path, "test".to_string())
426+
.scan_exercise(&test_path, "test".to_string(), &mut vec![])
420427
.unwrap();
421428
assert_eq!(exercises.name, "test");
422429
assert_eq!(exercises.tests.len(), 4);

plugins/java/src/maven.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::path::{Path, PathBuf};
1212
use std::time::Duration;
1313
use tar::Archive;
1414
use tmc_langs_framework::{
15+
anyhow,
1516
command::TmcCommand,
1617
domain::{ExerciseDesc, RunResult, ValidationResult},
1718
io::file_util,
@@ -83,7 +84,12 @@ impl LanguagePlugin for MavenPlugin {
8384
Ok(Some(self.run_checkstyle(&locale, path)?))
8485
}
8586

86-
fn scan_exercise(&self, path: &Path, exercise_name: String) -> Result<ExerciseDesc, TmcError> {
87+
fn scan_exercise(
88+
&self,
89+
path: &Path,
90+
exercise_name: String,
91+
_warnings: &mut Vec<anyhow::Error>,
92+
) -> Result<ExerciseDesc, TmcError> {
8793
if !Self::is_exercise_type_correct(path) {
8894
return JavaError::InvalidExercise(path.to_path_buf()).into();
8995
}
@@ -96,6 +102,7 @@ impl LanguagePlugin for MavenPlugin {
96102
&self,
97103
project_root_path: &Path,
98104
_timeout: Option<Duration>,
105+
_warnings: &mut Vec<anyhow::Error>,
99106
) -> Result<RunResult, TmcError> {
100107
Ok(self.run_java_tests(project_root_path)?)
101108
}
@@ -333,7 +340,7 @@ mod test {
333340
let test_path = temp_dir.path();
334341
let plugin = MavenPlugin::new().unwrap();
335342
let exercises = plugin
336-
.scan_exercise(&test_path, "test".to_string())
343+
.scan_exercise(&test_path, "test".to_string(), &mut vec![])
337344
.unwrap();
338345
assert_eq!(exercises.name, "test");
339346
assert_eq!(exercises.tests.len(), 1);

plugins/make/src/plugin.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::io::{self, BufRead, BufReader};
1111
use std::path::{Path, PathBuf};
1212
use std::time::Duration;
1313
use tmc_langs_framework::{
14+
anyhow,
1415
command::{Output, TmcCommand},
1516
domain::{ExerciseDesc, RunResult, RunStatus, TestDesc, TmcProjectYml},
1617
error::{CommandError, FileIo},
@@ -125,7 +126,12 @@ impl LanguagePlugin for MakePlugin {
125126
const BLOCK_COMMENT: Option<(&'static str, &'static str)> = Some(("/*", "*/"));
126127
type StudentFilePolicy = MakeStudentFilePolicy;
127128

128-
fn scan_exercise(&self, path: &Path, exercise_name: String) -> Result<ExerciseDesc, TmcError> {
129+
fn scan_exercise(
130+
&self,
131+
path: &Path,
132+
exercise_name: String,
133+
_warnings: &mut Vec<anyhow::Error>,
134+
) -> Result<ExerciseDesc, TmcError> {
129135
if !Self::is_exercise_type_correct(path) {
130136
return MakeError::NoExerciseFound(path.to_path_buf()).into();
131137
}
@@ -145,6 +151,7 @@ impl LanguagePlugin for MakePlugin {
145151
&self,
146152
path: &Path,
147153
_timeout: Option<Duration>,
154+
_warnings: &mut Vec<anyhow::Error>,
148155
) -> Result<RunResult, TmcError> {
149156
let output = self.build(path)?;
150157
if !output.status.success() {
@@ -378,7 +385,7 @@ mod test {
378385
let temp = copy_test("tests/data/passing");
379386
let plugin = MakePlugin::new();
380387
let exercise_desc = plugin
381-
.scan_exercise(temp.path(), "test".to_string())
388+
.scan_exercise(temp.path(), "test".to_string(), &mut vec![])
382389
.unwrap();
383390

384391
assert_eq!(exercise_desc.name, "test");
@@ -395,7 +402,7 @@ mod test {
395402

396403
let temp = copy_test("tests/data/passing");
397404
let plugin = MakePlugin::new();
398-
let run_result = plugin.run_tests(temp.path()).unwrap();
405+
let run_result = plugin.run_tests(temp.path(), &mut vec![]).unwrap();
399406
assert_eq!(run_result.status, RunStatus::Passed);
400407
// assert!(run_result.logs.is_empty());
401408
let test_results = run_result.test_results;
@@ -417,7 +424,7 @@ mod test {
417424

418425
let temp = copy_test("tests/data/failing");
419426
let plugin = MakePlugin::new();
420-
let run_result = plugin.run_tests(temp.path()).unwrap();
427+
let run_result = plugin.run_tests(temp.path(), &mut vec![]).unwrap();
421428
assert_eq!(run_result.status, RunStatus::TestsFailed);
422429
let test_results = &run_result.test_results;
423430
assert_eq!(test_results.len(), 1);
@@ -438,7 +445,7 @@ mod test {
438445

439446
let temp = copy_test("tests/data/valgrind-failing");
440447
let plugin = MakePlugin::new();
441-
let run_result = plugin.run_tests(temp.path()).unwrap();
448+
let run_result = plugin.run_tests(temp.path(), &mut vec![]).unwrap();
442449
assert_eq!(run_result.status, RunStatus::TestsFailed);
443450
let test_results = &run_result.test_results;
444451
assert_eq!(test_results.len(), 2);

plugins/notests/src/lib.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
66
use std::time::Duration;
77
pub use tmc_langs_framework::policy::EverythingIsStudentFilePolicy as NoTestsStudentFilePolicy;
88
use tmc_langs_framework::{
9+
anyhow,
910
domain::{ExerciseDesc, RunResult, RunStatus, TestDesc, TestResult},
1011
nom::IResult,
1112
zip::ZipArchive,
@@ -35,7 +36,12 @@ impl LanguagePlugin for NoTestsPlugin {
3536
const BLOCK_COMMENT: Option<(&'static str, &'static str)> = None;
3637
type StudentFilePolicy = NoTestsStudentFilePolicy;
3738

38-
fn scan_exercise(&self, path: &Path, exercise_name: String) -> Result<ExerciseDesc, TmcError> {
39+
fn scan_exercise(
40+
&self,
41+
path: &Path,
42+
exercise_name: String,
43+
_warnings: &mut Vec<anyhow::Error>,
44+
) -> Result<ExerciseDesc, TmcError> {
3945
let test_name = format!("{}Test", exercise_name);
4046
Ok(ExerciseDesc {
4147
name: exercise_name,
@@ -50,6 +56,7 @@ impl LanguagePlugin for NoTestsPlugin {
5056
&self,
5157
path: &Path,
5258
_timeout: Option<Duration>,
59+
_warnings: &mut Vec<anyhow::Error>,
5360
) -> Result<RunResult, TmcError> {
5461
Ok(RunResult {
5562
status: RunStatus::Passed,
@@ -116,11 +123,11 @@ mod test {
116123
let path = Path::new("tests/data/notests");
117124
assert!(NoTestsPlugin::is_exercise_type_correct(path));
118125
let desc = plugin
119-
.scan_exercise(path, "No Tests Exercise".to_string())
126+
.scan_exercise(path, "No Tests Exercise".to_string(), &mut vec![])
120127
.unwrap();
121128
assert_eq!(desc.tests.len(), 1);
122129
assert_eq!(desc.tests[0].points.len(), 0);
123-
let runres = plugin.run_tests(path).unwrap();
130+
let runres = plugin.run_tests(path, &mut vec![]).unwrap();
124131
assert_eq!(runres.status, RunStatus::Passed);
125132
}
126133

@@ -132,13 +139,13 @@ mod test {
132139
let path = Path::new("tests/data/notests-points");
133140
assert!(NoTestsPlugin::is_exercise_type_correct(path));
134141
let desc = plugin
135-
.scan_exercise(path, "No Tests Exercise".to_string())
142+
.scan_exercise(path, "No Tests Exercise".to_string(), &mut vec![])
136143
.unwrap();
137144
assert_eq!(desc.tests.len(), 1);
138145
assert_eq!(desc.tests[0].points.len(), 2);
139146
assert_eq!(desc.tests[0].points[0], "1");
140147
assert_eq!(desc.tests[0].points[1], "notests");
141-
let runres = plugin.run_tests(path).unwrap();
148+
let runres = plugin.run_tests(path, &mut vec![]).unwrap();
142149
assert_eq!(runres.status, RunStatus::Passed);
143150
}
144151
}

plugins/python3/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Oldest maintained Python version
2+
3+
The plugin creates a warning when the Python used is detected to be older than the oldest maintained Python release as per https://devguide.python.org/#branchstatus. The minimum version is hard-coded and needs to be maintained manually. Next EOL: 3.6 in 2021-12-23.
4+
15
## Student file policy
26

37
All files inside `./src` are considered student files, except for files with a `pyc` extension and files inside a `__pycache__` directory. In addition, all files in the project root with a `.py` extension are considered student files.

0 commit comments

Comments
 (0)