pub trait LanguagePlugin {
type StudentFilePolicy: StudentFilePolicy;
const PLUGIN_NAME: &'static str;
const DEFAULT_SANDBOX_IMAGE: &'static str;
const LINE_COMMENT: &'static str;
const BLOCK_COMMENT: Option<(&'static str, &'static str)>;
Show 16 methods
// Required methods
fn scan_exercise(
&self,
path: &Path,
exercise_name: String,
) -> Result<ExerciseDesc, TmcError>;
fn run_tests_with_timeout(
&self,
path: &Path,
timeout: Option<Duration>,
) -> Result<RunResult, TmcError>;
fn find_project_dir_in_archive<R>(
archive: &mut Archive<R>,
) -> Result<PathBuf, TmcError>
where R: Read + Seek;
fn is_exercise_type_correct(path: &Path) -> bool;
fn clean(&self, path: &Path) -> Result<(), TmcError>;
fn get_default_student_file_paths() -> Vec<PathBuf>;
fn get_default_exercise_file_paths() -> Vec<PathBuf>;
fn points_parser(
i: &str,
) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>;
// Provided methods
fn run_tests(&self, path: &Path) -> Result<RunResult, TmcError> { ... }
fn check_code_style(
&self,
_path: &Path,
_locale: Language,
) -> Result<Option<StyleValidationResult>, TmcError> { ... }
fn extract_project<R>(
archive: &mut Archive<R>,
target_location: &Path,
clean: bool,
) -> Result<(), TmcError>
where R: Read + Seek { ... }
fn extract_student_files(
compressed_project: impl Read + Seek,
compression: Compression,
target_location: &Path,
) -> Result<(), TmcError> { ... }
fn safe_find_project_dir_in_archive<R>(archive: &mut Archive<R>) -> PathBuf
where R: Read + Seek { ... }
fn is_archive_type_correct<R>(archive: &mut Archive<R>) -> bool
where R: Read + Seek { ... }
fn get_exercise_packaging_configuration(
path: &Path,
) -> Result<ExercisePackagingConfiguration, TmcError> { ... }
fn get_available_points(
exercise_path: &Path,
) -> Result<Vec<String>, TmcError> { ... }
}Expand description
The trait that each language plug-in must implement.
These implement the operations needed by the TMC server to support a programming language. These are provided as a library to IDE plug-ins as a convenience. IDE plug-ins often need additional integration work to support a language properly. This interface does NOT attempt to provide everything that an IDE plug-in might need to fully support a language.
Parts of this interface may be called in a TMC sandbox.
Implementations must be thread-safe and preferably fully stateless. Users of this interface are free to cache results if needed.
Required Associated Constants§
const PLUGIN_NAME: &'static str
const DEFAULT_SANDBOX_IMAGE: &'static str
const LINE_COMMENT: &'static str
const BLOCK_COMMENT: Option<(&'static str, &'static str)>
Required Associated Types§
Required Methods§
Sourcefn scan_exercise(
&self,
path: &Path,
exercise_name: String,
) -> Result<ExerciseDesc, TmcError>
fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
Produces an exercise description of an exercise directory.
This involves finding the test cases and the points offered by the exercise.
Must return Err if the given path is not a valid exercise directory for
this language.
Sourcefn run_tests_with_timeout(
&self,
path: &Path,
timeout: Option<Duration>,
) -> Result<RunResult, TmcError>
fn run_tests_with_timeout( &self, path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
Runs the tests for the exercise with the given timeout. Used by run_tests with the timeout from the project config.
Sourcefn find_project_dir_in_archive<R>(
archive: &mut Archive<R>,
) -> Result<PathBuf, TmcError>
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
Searches the zip for a valid project directory. This function is used to detect the language plugin for the archive, so simply finding “src” is not sufficient, e.g. the Python plugin should check that there is an actual “src/*.py” file inside src. Note that the returned path may not actually have an entry in the zip.
Sourcefn is_exercise_type_correct(path: &Path) -> bool
fn is_exercise_type_correct(path: &Path) -> bool
Tells if there’s a valid exercise in this path. Delegates to find_project_dir_in_archive by default.
Unlike is_archive_type_correct, only checks the root directory.
Sourcefn clean(&self, path: &Path) -> Result<(), TmcError>
fn clean(&self, path: &Path) -> Result<(), TmcError>
Runs clean command e.g make clean for make or mvn clean for maven.
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
Sourcefn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
A nom parser that recognizes a points annotation and returns the inner points value(s).
For example implementations, see the existing language plugins.
Provided Methods§
Sourcefn run_tests(&self, path: &Path) -> Result<RunResult, TmcError>
fn run_tests(&self, path: &Path) -> Result<RunResult, TmcError>
Runs the tests for the exercise.
Sourcefn check_code_style(
&self,
_path: &Path,
_locale: Language,
) -> Result<Option<StyleValidationResult>, TmcError>
fn check_code_style( &self, _path: &Path, _locale: Language, ) -> Result<Option<StyleValidationResult>, TmcError>
Run checkstyle or similar plugin to project if applicable, no-op by default
Sourcefn extract_project<R>(
archive: &mut Archive<R>,
target_location: &Path,
clean: bool,
) -> Result<(), TmcError>
fn extract_project<R>( archive: &mut Archive<R>, target_location: &Path, clean: bool, ) -> Result<(), TmcError>
Extract a given archive file containing a compressed project to a target location.
This will overwrite any existing files as long as they are not specified as student files by the language dependent student file policy.
Sourcefn extract_student_files(
compressed_project: impl Read + Seek,
compression: Compression,
target_location: &Path,
) -> Result<(), TmcError>
fn extract_student_files( compressed_project: impl Read + Seek, compression: Compression, target_location: &Path, ) -> Result<(), TmcError>
Extracts student files from the compressed project. It finds the project dir from the zip and extracts the student files from there. Overwrites all files. Important: does not extract .tmcproject.yml from the students’ submission as they control that file and they could use it to modify the test files.
Sourcefn safe_find_project_dir_in_archive<R>(archive: &mut Archive<R>) -> PathBuf
fn safe_find_project_dir_in_archive<R>(archive: &mut Archive<R>) -> PathBuf
A safer variant of find_project_dir_in_archive used by default extraction helpers.
Fallback order:
- Delegate to
find_project_dir_in_archiveimplemented by the language plugin - First directory containing a
.tmcproject.yml - If archive root has only one folder, use that folder
- Archive root (empty path)
Sourcefn is_archive_type_correct<R>(archive: &mut Archive<R>) -> bool
fn is_archive_type_correct<R>(archive: &mut Archive<R>) -> bool
Tells if there’s a valid exercise in this archive.
Unlike is_exercise_type_correct, searches the entire archive.
Sourcefn get_exercise_packaging_configuration(
path: &Path,
) -> Result<ExercisePackagingConfiguration, TmcError>
fn get_exercise_packaging_configuration( path: &Path, ) -> Result<ExercisePackagingConfiguration, TmcError>
Returns configuration which is used to package submission on tmc-server.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
Implementations on Foreign Types§
Source§impl LanguagePlugin for CSharpPlugin
Project directory:
Contains a src directory which contains a .cs or .csproj file (which may be inside a subdirectory).
impl LanguagePlugin for CSharpPlugin
Project directory: Contains a src directory which contains a .cs or .csproj file (which may be inside a subdirectory).
Source§fn scan_exercise(
&self,
path: &Path,
exercise_name: String,
) -> Result<ExerciseDesc, TmcError>
fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
Runs –generate-points-file and parses the generated .tmc_available_points.json.
Source§fn run_tests_with_timeout(
&self,
path: &Path,
timeout: Option<Duration>,
) -> Result<RunResult, TmcError>
fn run_tests_with_timeout( &self, path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
Runs –run-tests and parses the resulting .tmc_test_results.json.
Source§fn check_code_style(
&self,
_path: &Path,
_locale: Language,
) -> Result<Option<StyleValidationResult>, TmcError>
fn check_code_style( &self, _path: &Path, _locale: Language, ) -> Result<Option<StyleValidationResult>, TmcError>
No-op for C#.
const PLUGIN_NAME: &'static str = "csharp"
const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-csharp:latest"
const LINE_COMMENT: &'static str = "//"
const BLOCK_COMMENT: Option<(&'static str, &'static str)>
type StudentFilePolicy = CSharpStudentFilePolicy
fn is_exercise_type_correct(path: &Path) -> bool
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
Source§impl LanguagePlugin for AntPlugin
Project directory:
Contains build.xml file.
OR
Contains src and test directories.
impl LanguagePlugin for AntPlugin
Project directory: Contains build.xml file. OR Contains src and test directories.
Source§fn scan_exercise(
&self,
path: &Path,
exercise_name: String,
) -> Result<ExerciseDesc, TmcError>
fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
Scans the exercise at the given path. Immediately exits if the target directory is not a valid exercise.
Source§fn is_exercise_type_correct(path: &Path) -> bool
fn is_exercise_type_correct(path: &Path) -> bool
Checks if the directory contains a build.xml file, or a src and a test directory.
const PLUGIN_NAME: &'static str = "apache-ant"
const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-java:latest"
const LINE_COMMENT: &'static str = "//"
const BLOCK_COMMENT: Option<(&'static str, &'static str)>
type StudentFilePolicy = AntStudentFilePolicy
fn check_code_style( &self, path: &Path, locale: Language, ) -> Result<Option<StyleValidationResult>, TmcError>
fn run_tests_with_timeout( &self, project_root_path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
fn clean(&self, path: &Path) -> Result<(), TmcError>
fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
Source§impl LanguagePlugin for MavenPlugin
Project directory:
Contains pom.xml file
impl LanguagePlugin for MavenPlugin
Project directory: Contains pom.xml file
Source§fn is_exercise_type_correct(path: &Path) -> bool
fn is_exercise_type_correct(path: &Path) -> bool
Checks if the directory has a pom.xml file.
const PLUGIN_NAME: &'static str = "apache-maven"
const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-java:latest"
const LINE_COMMENT: &'static str = "//"
const BLOCK_COMMENT: Option<(&'static str, &'static str)>
type StudentFilePolicy = MavenStudentFilePolicy
fn check_code_style( &self, path: &Path, locale: Language, ) -> Result<Option<StyleValidationResult>, TmcError>
fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
fn run_tests_with_timeout( &self, project_root_path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
Source§impl LanguagePlugin for MakePlugin
Project directory:
Contains a src directory and a Makefile file
impl LanguagePlugin for MakePlugin
Project directory: Contains a src directory and a Makefile file
Source§fn is_exercise_type_correct(path: &Path) -> bool
fn is_exercise_type_correct(path: &Path) -> bool
Checks if the directory has a src dir and a Makefile file in it.
const PLUGIN_NAME: &'static str = "make"
const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-make:latest"
const LINE_COMMENT: &'static str = "//"
const BLOCK_COMMENT: Option<(&'static str, &'static str)>
type StudentFilePolicy = MakeStudentFilePolicy
fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
fn run_tests_with_timeout( &self, path: &Path, _timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
fn clean(&self, path: &Path) -> Result<(), TmcError>
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
Source§impl LanguagePlugin for NoTestsPlugin
Project directory:
Contains a .tmcproject.yml file that has no-tests set to true.
impl LanguagePlugin for NoTestsPlugin
Project directory:
Contains a .tmcproject.yml file that has no-tests set to true.
const PLUGIN_NAME: &'static str = "No-Tests"
const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-python:latest"
const LINE_COMMENT: &'static str = "//"
const BLOCK_COMMENT: Option<(&'static str, &'static str)> = None
type StudentFilePolicy = NoTestsStudentFilePolicy
fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
fn run_tests_with_timeout( &self, path: &Path, _timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
fn is_exercise_type_correct(path: &Path) -> bool
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
fn clean(&self, _path: &Path) -> Result<(), TmcError>
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
fn points_parser(_: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
Source§impl LanguagePlugin for Python3Plugin
Project directory:
Contains setup.py, requirements.txt, test/init.py, or tmc/main.py
OR
Contains an .ipynb file. This is given lower priority than the prior rule, and if there are multiple .ipynb files, the shallowest directory is returned.
impl LanguagePlugin for Python3Plugin
Project directory: Contains setup.py, requirements.txt, test/init.py, or tmc/main.py OR Contains an .ipynb file. This is given lower priority than the prior rule, and if there are multiple .ipynb files, the shallowest directory is returned.
const PLUGIN_NAME: &'static str = "python3"
const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-python:latest"
const LINE_COMMENT: &'static str = "#"
const BLOCK_COMMENT: Option<(&'static str, &'static str)>
type StudentFilePolicy = Python3StudentFilePolicy
fn scan_exercise( &self, exercise_directory: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>
fn run_tests_with_timeout( &self, exercise_directory: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>
fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
fn is_exercise_type_correct(path: &Path) -> bool
fn clean(&self, exercise_path: &Path) -> Result<(), TmcError>
fn get_default_student_file_paths() -> Vec<PathBuf>
fn get_default_exercise_file_paths() -> Vec<PathBuf>
fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>
Source§impl LanguagePlugin for RPlugin
Project directory:
Contains an R directory.
impl LanguagePlugin for RPlugin
Project directory: Contains an R directory.
Source§fn is_exercise_type_correct(path: &Path) -> bool
fn is_exercise_type_correct(path: &Path) -> bool
Checks if the directory contains R or tests/testthat
Source§fn clean(&self, _path: &Path) -> Result<(), TmcError>
fn clean(&self, _path: &Path) -> Result<(), TmcError>
No operation for now. To be possibly implemented later: remove .Rdata, .Rhistory etc