Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
**/*.rs.bk
.vscode
/test-cache
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/bindings/tmc-langs-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ fn login(mut cx: FunctionContext) -> JsResult<JsValue> {
password
};
let token = with_client(&client_name, client_version, |client| {
tmc_langs::login_with_password(client, &client_name, email, decoded)
tmc_langs::login_with_password(client, email, decoded)
})
.map_err(|e| convert_err(&mut cx, e))?;

Expand Down
34 changes: 7 additions & 27 deletions crates/plugins/csharp/src/policy.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,12 @@
//! Student file policy for the C# plugin.

use std::path::Path;
use std::{ffi::OsStr, path::Path};
use tmc_langs_framework::{StudentFilePolicy, TmcProjectYml};

pub struct CSharpStudentFilePolicy {
project_config: TmcProjectYml,
}

impl CSharpStudentFilePolicy {
/// Goes up directories until a bin or obj directory is found, either indicating that the path is in a binary directory.
fn is_child_of_binary_dir(path: &Path) -> bool {
// checks each parent directory for bin or obj
for ancestor in path.ancestors().skip(1) {
if let Some(file_name) = ancestor.file_name() {
if file_name == "bin" || file_name == "obj" {
return true;
}
}
}
false
}
}

impl StudentFilePolicy for CSharpStudentFilePolicy {
fn new_with_project_config(project_config: TmcProjectYml) -> Self
where
Expand All @@ -34,14 +19,9 @@ impl StudentFilePolicy for CSharpStudentFilePolicy {
&self.project_config
}

// false for .csproj files and files in bin or obj directories
// true for files in src except for .csproj files
// .cs files in src
fn is_non_extra_student_file(&self, path: &Path) -> bool {
path.starts_with("src")
// exclude files in bin
&& !Self::is_child_of_binary_dir(path)
// exclude .csproj files
&& !path.extension().map(|ext| ext == "csproj").unwrap_or_default()
path.starts_with("src") && path.extension() == Some(OsStr::new("cs"))
}
}

Expand All @@ -53,14 +33,14 @@ mod test {
fn file_in_binary_dir_is_not_student_file() {
let policy = CSharpStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(!policy.is_student_file(Path::new("src/bin/any/file")));
assert!(!policy.is_student_file(Path::new("obj/any/src/file")));
assert!(!policy.is_student_file(Path::new("obj/any/src/file.cs")));
}

#[test]
fn file_in_src_is_student_file() {
fn cs_file_in_src_is_student_file() {
let policy = CSharpStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(policy.is_student_file(Path::new("src/file")));
assert!(policy.is_student_file(Path::new("src/any/file")));
assert!(policy.is_student_file(Path::new("src/file.cs")));
assert!(policy.is_student_file(Path::new("src/any/file.cs")));
}

#[test]
Expand Down
9 changes: 5 additions & 4 deletions crates/plugins/java/src/ant_policy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Ant student file policy

use std::path::Path;
use std::{ffi::OsStr, path::Path};
use tmc_langs_framework::{StudentFilePolicy, TmcProjectYml};

pub struct AntStudentFilePolicy {
Expand All @@ -20,7 +20,7 @@ impl StudentFilePolicy for AntStudentFilePolicy {
}

fn is_non_extra_student_file(&self, path: &Path) -> bool {
path.starts_with("src")
path.starts_with("src") && path.extension() == Some(OsStr::new("java"))
}
}

Expand All @@ -31,13 +31,14 @@ mod test {
#[test]
fn is_student_file() {
let policy = AntStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(policy.is_student_file(Path::new("src/file")));
assert!(policy.is_student_file(Path::new("src/dir/file")));
assert!(policy.is_student_file(Path::new("src/file.java")));
assert!(policy.is_student_file(Path::new("src/dir/file.java")));
}

#[test]
fn is_not_student_source_file() {
let policy = AntStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(!policy.is_student_file(Path::new("src/file")));
assert!(!policy.is_student_file(Path::new("file")));
assert!(!policy.is_student_file(Path::new("dir/src/file")));
assert!(!policy.is_student_file(Path::new("srca/file")));
Expand Down
12 changes: 6 additions & 6 deletions crates/plugins/java/src/maven_plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
};
use flate2::read::GzDecoder;
use std::{
ffi::OsString,
ffi::{OsStr, OsString},
io::{Cursor, Read, Seek},
ops::ControlFlow::{Break, Continue},
path::{Path, PathBuf},
Expand All @@ -17,7 +17,7 @@ use tmc_langs_framework::{
Archive, ExerciseDesc, Language, LanguagePlugin, RunResult, StyleValidationResult, TmcCommand,
TmcError, nom::IResult, nom_language::error::VerboseError,
};
use tmc_langs_util::{file_util, path_util};
use tmc_langs_util::file_util;

const MVN_ARCHIVE: &[u8] = include_bytes!("../deps/apache-maven-3.8.1-bin.tar.gz");
const MVN_PATH_IN_ARCHIVE: &str = "apache-maven-3.8.1"; // the name of the base directory in the maven archive
Expand Down Expand Up @@ -132,14 +132,14 @@ impl LanguagePlugin for MavenPlugin {
archive: &mut Archive<R>,
) -> Result<PathBuf, TmcError> {
let mut iter = archive.iter()?;

let project_dir = loop {
let next = iter.with_next(|file| {
let file_path = file.path()?;

if file.is_file() {
// check for pom.xml
if let Some(parent) = path_util::get_parent_of_named(&file_path, "pom.xml") {
return Ok(Break(Some(parent)));
if file.is_file() && file_path.file_name() == Some(OsStr::new("pom.xml")) {
if let Some(pom_parent) = file_path.parent() {
return Ok(Break(Some(pom_parent.to_path_buf())));
}
}
Ok(Continue(()))
Expand Down
9 changes: 5 additions & 4 deletions crates/plugins/java/src/maven_policy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Maven student file policy

use std::path::Path;
use std::{ffi::OsStr, path::Path};
use tmc_langs_framework::{StudentFilePolicy, TmcProjectYml};

pub struct MavenStudentFilePolicy {
Expand All @@ -20,7 +20,8 @@ impl StudentFilePolicy for MavenStudentFilePolicy {
}

fn is_non_extra_student_file(&self, path: &Path) -> bool {
path.starts_with("src/main")
// technically pom.xml would need to be included to differentiate between maven and ant projects
path.starts_with("src/main") && path.extension() == Some(OsStr::new("java"))
}
}

Expand All @@ -31,8 +32,8 @@ mod test {
#[test]
fn is_student_file() {
let policy = MavenStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(policy.is_student_file(Path::new("src/main/file")));
assert!(policy.is_student_file(Path::new("src/main/dir/file")));
assert!(policy.is_student_file(Path::new("src/main/file.java")));
assert!(policy.is_student_file(Path::new("src/main/dir/file.java")));
}

#[test]
Expand Down
14 changes: 9 additions & 5 deletions crates/plugins/make/src/policy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Contains the language policy for the plugin.

use std::path::Path;
use std::{ffi::OsStr, path::Path};
use tmc_langs_framework::{StudentFilePolicy, TmcProjectYml};

pub struct MakeStudentFilePolicy {
Expand All @@ -20,7 +20,8 @@ impl StudentFilePolicy for MakeStudentFilePolicy {
}

fn is_non_extra_student_file(&self, path: &Path) -> bool {
path.starts_with("src")
let ext = path.extension();
path.starts_with("src") && (ext == Some(OsStr::new("c")) || ext == Some(OsStr::new("h")))
}
}

Expand All @@ -31,14 +32,17 @@ mod test {
#[test]
fn is_student_file() {
let policy = MakeStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(policy.is_student_file(Path::new("src")));
assert!(policy.is_student_file(Path::new("src/file")));
assert!(policy.is_student_file(Path::new("src/dir/file")));
assert!(policy.is_student_file(Path::new("src/file.c")));
assert!(policy.is_student_file(Path::new("src/file.h")));
assert!(policy.is_student_file(Path::new("src/dir/file.c")));
assert!(policy.is_student_file(Path::new("src/dir/file.h")));
}

#[test]
fn is_not_student_source_file() {
let policy = MakeStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(!policy.is_student_file(Path::new("a.c")));
assert!(!policy.is_student_file(Path::new("a.h")));
assert!(!policy.is_student_file(Path::new("srcc")));
assert!(!policy.is_student_file(Path::new("dir/src/file")));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <stdio.h>
#include "source.h"
#include <stdlib.h>

int one(void)
{
Expand Down
31 changes: 9 additions & 22 deletions crates/plugins/python3/src/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,20 @@ impl StudentFilePolicy for Python3StudentFilePolicy {
}

fn is_non_extra_student_file(&self, path: &Path) -> bool {
// no files in tmc, test and venv subdirectories are considered student files
let is_cache_file = path.extension() == Some(OsStr::new("pyc"))
|| path
.components()
.any(|c| c.as_os_str() == OsStr::new("__pycache__"));
let is_in_exercise_subdir = path.starts_with("test") || path.starts_with("tmc");
let is_in_venv = path.starts_with(".venv") || path.starts_with("venv");
if is_cache_file || is_in_exercise_subdir || is_in_venv {
// never include pyc files
let is_pyc = path.extension() == Some(OsStr::new("pyc"));
if is_pyc {
return false;
}

// all non-pyc or __pycache__ files in src are student source files
let in_src = path.starts_with("src");
// .py files in exercise root are student source files
let is_in_project_root = match path.parent() {
let in_exercise_root = match path.parent() {
Some(s) => s.as_os_str().is_empty(),
None => true,
};
let is_py_file = path.extension() == Some(OsStr::new("py"));
let is_py = path.extension() == Some(OsStr::new("py"));
let is_ipynb = path.extension() == Some(OsStr::new("ipynb"));

// all in all, excluding cache files and the exception subdirs,
// we take non-cache files in src, py files in root, everything not in the root and not in src, and all ipynb files
in_src
|| is_in_project_root && is_py_file
|| !is_in_exercise_subdir && !is_in_project_root
|| is_ipynb
(in_src || in_exercise_root) && (is_py || is_ipynb)
}
}

Expand Down Expand Up @@ -83,10 +70,10 @@ mod test {
}

#[test]
fn subdirs_are_student_files() {
fn subdirs_are_not_student_files() {
let policy = Python3StudentFilePolicy::new(Path::new(".")).unwrap();
assert!(policy.is_student_file(Path::new("subdir/something")));
assert!(policy.is_student_file(Path::new("another/mid/else")));
assert!(!policy.is_student_file(Path::new("subdir/something")));
assert!(!policy.is_student_file(Path::new("another/mid/else")));
}

#[test]
Expand Down
8 changes: 4 additions & 4 deletions crates/plugins/r/src/policy.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Contains the R student file policy

use std::path::Path;
use std::{ffi::OsStr, path::Path};
use tmc_langs_framework::{StudentFilePolicy, TmcProjectYml};

pub struct RStudentFilePolicy {
Expand All @@ -20,7 +20,7 @@ impl StudentFilePolicy for RStudentFilePolicy {
}

fn is_non_extra_student_file(&self, path: &Path) -> bool {
path.starts_with("R")
path.starts_with("R") && path.extension() == Some(OsStr::new("R"))
}
}

Expand All @@ -39,15 +39,15 @@ mod test {
init();

let policy = RStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(policy.is_student_file(Path::new("R")));
assert!(policy.is_student_file(Path::new("R/file")));
assert!(policy.is_student_file(Path::new("R/file.R")));
}

#[test]
fn is_not_student_source_file() {
init();

let policy = RStudentFilePolicy::new(Path::new(".")).unwrap();
assert!(!policy.is_student_file(Path::new("a.R")));
assert!(!policy.is_student_file(Path::new("dir/R")));
assert!(!policy.is_student_file(Path::new("dir/R/file")));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/tmc-langs-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ fn run_tmc_inner(
} else {
password
};
tmc_langs::login_with_password(client, client_name, email, decoded)?
tmc_langs::login_with_password(client, email, decoded)?
} else {
unreachable!("validation error");
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: b1221f4d32193235543d57c173c4b7ebe75586f4cc56c455df67da761cfc5af8
output-data: 0fd4baebce75eed92c41c7213c3e052308c2c0f6e91ebef9b5fa8ccae93cb607
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: 34856483dead601201bdf0e75c26481e97fdf36af401b3729b410711d57c13f5
output-data: 65e4df36150280d62c526097d328c38b677ea0ebb6c4a88f7a52597c5a719dcd
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: 753a9a1d15a783ca6b874ca9d4d38f647eabbf9897b2c91102dcbb284cfde7c9
output-data: f9887325928a81c8b84c7a7fd457742606969f1504b47a8a8d7d562cc218c071
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: cd89870f4c9a5c09b1a13fd7119fa1a8e29ab8b06faf125e3f8dc30d3cee519e
output-data: dd4d587c1c25524f92321216bc2a32e75890fbe75e055155f48452789070be71
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: dac5a9a56c89053fbcbf5d2c14618247b62584dfb1af4aa9602510a2f048b779
output-data: b319b9e0a36dbc40a63e4f84ae67e86f8bf97b8963ecfd70d610c36c2cfa9def
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: beed439db1934bfe9210893772a4e1ba312ed323b4f8c9b1e4b30f850e283b5e
output-data: 4a6e0ea2c5af8a57dcf350922414034206ee1459a393b79e671312a5275f2cc6
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ input_file: sample_exercises/make/failing-exercise
---
- failing-exercise
- failing-exercise/src
- failing-exercise/src/Makefile
- failing-exercise/src/main
- failing-exercise/src/main.c
- failing-exercise/src/source.c
- failing-exercise/src/source.h

Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ message: compressed project from [PATH] to [PATH]
result: executed-command
data:
output-data-kind: compressed-project-hash
output-data: d8473af22ec3f6f558a8dfe030e5d80eeeb4b3a2bdb9cae495b5089083440966
output-data: 42dd190e70d9e3cdaebf2302adc4ecacca771c2d3df55343e78bf48a9ca494d5
Loading
Loading