Trait LanguagePlugin

Source
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§

Source

const PLUGIN_NAME: &'static str

Source

const DEFAULT_SANDBOX_IMAGE: &'static str

Source

const LINE_COMMENT: &'static str

Source

const BLOCK_COMMENT: Option<(&'static str, &'static str)>

Required Associated Types§

Required Methods§

Source

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.

Source

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.

Source

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

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.

Source

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.

Source

fn clean(&self, path: &Path) -> Result<(), TmcError>

Runs clean command e.g make clean for make or mvn clean for maven.

Source

fn get_default_student_file_paths() -> Vec<PathBuf>

Source

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source

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§

Source

fn run_tests(&self, path: &Path) -> Result<RunResult, TmcError>

Runs the tests for the exercise.

Source

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

Source

fn extract_project<R>( archive: &mut Archive<R>, target_location: &Path, clean: bool, ) -> Result<(), TmcError>
where R: Read + Seek,

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.

Source

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.

Source

fn safe_find_project_dir_in_archive<R>(archive: &mut Archive<R>) -> PathBuf
where R: Read + Seek,

A safer variant of find_project_dir_in_archive used by default extraction helpers.

Fallback order:

  1. Delegate to find_project_dir_in_archive implemented by the language plugin
  2. First directory containing a .tmcproject.yml
  3. If archive root has only one folder, use that folder
  4. Archive root (empty path)
Source

fn is_archive_type_correct<R>(archive: &mut Archive<R>) -> bool
where R: Read + Seek,

Tells if there’s a valid exercise in this archive. Unlike is_exercise_type_correct, searches the entire archive.

Source

fn get_exercise_packaging_configuration( path: &Path, ) -> Result<ExercisePackagingConfiguration, TmcError>

Returns configuration which is used to package submission on tmc-server.

Source

fn get_available_points(exercise_path: &Path) -> Result<Vec<String>, TmcError>

Parses exercise files using Self::LINE_COMMENT and Self::BLOCK_COMMENT to filter out comments and Self::points_parser to parse points from the actual code.

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).

Source§

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>

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>

No-op for C#.

Source§

fn clean(&self, path: &Path) -> Result<(), TmcError>

Removes all bin and obj sub-directories.

Source§

const PLUGIN_NAME: &'static str = "csharp"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-csharp:latest"

Source§

const LINE_COMMENT: &'static str = "//"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)>

Source§

type StudentFilePolicy = CSharpStudentFilePolicy

Source§

fn is_exercise_type_correct(path: &Path) -> bool

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

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.

Source§

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

Checks if the directory contains a build.xml file, or a src and a test directory.

Source§

const PLUGIN_NAME: &'static str = "apache-ant"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-java:latest"

Source§

const LINE_COMMENT: &'static str = "//"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)>

Source§

type StudentFilePolicy = AntStudentFilePolicy

Source§

fn check_code_style( &self, path: &Path, locale: Language, ) -> Result<Option<StyleValidationResult>, TmcError>

Source§

fn run_tests_with_timeout( &self, project_root_path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn clean(&self, path: &Path) -> Result<(), TmcError>

Source§

fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

impl LanguagePlugin for MavenPlugin

Project directory: Contains pom.xml file

Source§

fn is_exercise_type_correct(path: &Path) -> bool

Checks if the directory has a pom.xml file.

Source§

fn clean(&self, path: &Path) -> Result<(), TmcError>

Runs the Maven clean plugin.

Source§

const PLUGIN_NAME: &'static str = "apache-maven"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-java:latest"

Source§

const LINE_COMMENT: &'static str = "//"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)>

Source§

type StudentFilePolicy = MavenStudentFilePolicy

Source§

fn check_code_style( &self, path: &Path, locale: Language, ) -> Result<Option<StyleValidationResult>, TmcError>

Source§

fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>

Source§

fn run_tests_with_timeout( &self, project_root_path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

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

Source§

fn is_exercise_type_correct(path: &Path) -> bool

Checks if the directory has a src dir and a Makefile file in it.

Source§

const PLUGIN_NAME: &'static str = "make"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-make:latest"

Source§

const LINE_COMMENT: &'static str = "//"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)>

Source§

type StudentFilePolicy = MakeStudentFilePolicy

Source§

fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>

Source§

fn run_tests_with_timeout( &self, path: &Path, _timeout: Option<Duration>, ) -> Result<RunResult, TmcError>

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn clean(&self, path: &Path) -> Result<(), TmcError>

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

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.

Source§

const PLUGIN_NAME: &'static str = "No-Tests"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-python:latest"

Source§

const LINE_COMMENT: &'static str = "//"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)> = None

Source§

type StudentFilePolicy = NoTestsStudentFilePolicy

Source§

fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>

Source§

fn run_tests_with_timeout( &self, path: &Path, _timeout: Option<Duration>, ) -> Result<RunResult, TmcError>

Source§

fn is_exercise_type_correct(path: &Path) -> bool

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn clean(&self, _path: &Path) -> Result<(), TmcError>

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

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.

Source§

const PLUGIN_NAME: &'static str = "python3"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-python:latest"

Source§

const LINE_COMMENT: &'static str = "#"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)>

Source§

type StudentFilePolicy = Python3StudentFilePolicy

Source§

fn scan_exercise( &self, exercise_directory: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>

Source§

fn run_tests_with_timeout( &self, exercise_directory: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn is_exercise_type_correct(path: &Path) -> bool

Source§

fn clean(&self, exercise_path: &Path) -> Result<(), TmcError>

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>

Source§

impl LanguagePlugin for RPlugin

Project directory: Contains an R directory.

Source§

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>

No operation for now. To be possibly implemented later: remove .Rdata, .Rhistory etc

Source§

const PLUGIN_NAME: &'static str = "r"

Source§

const DEFAULT_SANDBOX_IMAGE: &'static str = "eu.gcr.io/moocfi-public/tmc-sandbox-r:latest"

Source§

const LINE_COMMENT: &'static str = "#"

Source§

const BLOCK_COMMENT: Option<(&'static str, &'static str)> = None

Source§

type StudentFilePolicy = RStudentFilePolicy

Source§

fn scan_exercise( &self, path: &Path, exercise_name: String, ) -> Result<ExerciseDesc, TmcError>

Source§

fn run_tests_with_timeout( &self, path: &Path, timeout: Option<Duration>, ) -> Result<RunResult, TmcError>

Source§

fn find_project_dir_in_archive<R>( archive: &mut Archive<R>, ) -> Result<PathBuf, TmcError>
where R: Read + Seek,

Source§

fn get_default_student_file_paths() -> Vec<PathBuf>

Source§

fn get_default_exercise_file_paths() -> Vec<PathBuf>

Source§

fn points_parser(i: &str) -> Result<(&str, Vec<&str>), Err<VerboseError<&str>>>

Implementors§