Skip to content

Commit adcaeac

Browse files
committed
simplified project dir discovery in zip
1 parent c6c7dac commit adcaeac

File tree

9 files changed

+31
-99
lines changed

9 files changed

+31
-99
lines changed

plugins/java/src/ant.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -109,40 +109,6 @@ impl LanguagePlugin for AntPlugin {
109109
|| path.join("test").exists() && path.join("src").exists()
110110
}
111111

112-
/// Tries to find a directory which contains both a src and a test directory.
113-
fn find_project_dir_in_zip<R: Read + Seek>(
114-
zip_archive: &mut ZipArchive<R>,
115-
) -> Result<PathBuf, TmcError> {
116-
let mut dirs_with_src = HashSet::new();
117-
let mut dirs_with_test = HashSet::new();
118-
for i in 0..zip_archive.len() {
119-
// zips don't necessarily contain entries for intermediate directories,
120-
// so we need to check every path for src and test
121-
let file = zip_archive.by_index(i)?;
122-
let file_path = file.sanitized_name();
123-
// todo: do in one pass somehow
124-
if file_path.components().any(|c| c.as_os_str() == "src") {
125-
let path: PathBuf = file_path
126-
.components()
127-
.take_while(|c| c.as_os_str() != "src")
128-
.collect();
129-
dirs_with_src.insert(path);
130-
}
131-
if file_path.components().any(|c| c.as_os_str() == "test") {
132-
let path: PathBuf = file_path
133-
.components()
134-
.take_while(|c| c.as_os_str() != "test")
135-
.collect();
136-
dirs_with_test.insert(path);
137-
}
138-
}
139-
// return any dir with src and test
140-
if let Some(val) = dirs_with_src.intersection(&dirs_with_test).next() {
141-
return Ok(val.clone());
142-
}
143-
Err(TmcError::NoProjectDirInZip)
144-
}
145-
146112
fn get_student_file_policy(project_path: &Path) -> Self::StudentFilePolicy {
147113
AntStudentFilePolicy::new(project_path.to_path_buf())
148114
}
@@ -528,7 +494,7 @@ mod test {
528494

529495
#[test]
530496
fn doesnt_find_project_dir_in_zip() {
531-
let file = File::open("tests/data/AntWithoutTest.zip").unwrap();
497+
let file = File::open("tests/data/AntWithoutSrc.zip").unwrap();
532498
let mut zip = ZipArchive::new(file).unwrap();
533499
let dir = AntPlugin::find_project_dir_in_zip(&mut zip);
534500
assert!(dir.is_err());

plugins/java/src/maven.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -103,22 +103,6 @@ impl LanguagePlugin for MavenPlugin {
103103
path.join("pom.xml").exists()
104104
}
105105

106-
/// Tries to find a directory which contains a pom.xml file.
107-
fn find_project_dir_in_zip<R: Read + Seek>(
108-
zip_archive: &mut ZipArchive<R>,
109-
) -> Result<PathBuf, TmcError> {
110-
for i in 0..zip_archive.len() {
111-
let file = zip_archive.by_index(i)?;
112-
let file_path = file.sanitized_name();
113-
if file_path.file_name() == Some(OsStr::new("pom.xml")) {
114-
if let Some(parent) = file_path.parent() {
115-
return Ok(parent.to_path_buf());
116-
}
117-
}
118-
}
119-
Err(TmcError::NoProjectDirInZip)
120-
}
121-
122106
fn get_student_file_policy(project_path: &Path) -> Self::StudentFilePolicy {
123107
MavenStudentFilePolicy::new(project_path.to_path_buf())
124108
}
@@ -452,7 +436,7 @@ mod test {
452436

453437
#[test]
454438
fn doesnt_find_project_dir_in_zip() {
455-
let file = File::open("tests/data/MavenWithoutPom.zip").unwrap();
439+
let file = File::open("tests/data/MavenWithoutSrc.zip").unwrap();
456440
let mut zip = ZipArchive::new(file).unwrap();
457441
let dir = MavenPlugin::find_project_dir_in_zip(&mut zip);
458442
assert!(dir.is_err());

plugins/make/src/plugin.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -256,22 +256,6 @@ impl LanguagePlugin for MakePlugin {
256256
path.join("Makefile").is_file()
257257
}
258258

259-
/// Tries to find a directory with a Makefile in it.
260-
fn find_project_dir_in_zip<R: Read + Seek>(
261-
zip_archive: &mut ZipArchive<R>,
262-
) -> Result<PathBuf, TmcError> {
263-
for i in 0..zip_archive.len() {
264-
let file = zip_archive.by_index(i)?;
265-
let file_path = file.sanitized_name();
266-
if file_path.file_name() == Some(OsStr::new("Makefile")) {
267-
if let Some(parent) = file_path.parent() {
268-
return Ok(parent.to_path_buf());
269-
}
270-
}
271-
}
272-
Err(TmcError::NoProjectDirInZip)
273-
}
274-
275259
// does not check for success
276260
fn clean(&self, path: &Path) -> Result<(), TmcError> {
277261
let mut command = TmcCommand::new("make");
@@ -419,7 +403,7 @@ mod test {
419403

420404
#[test]
421405
fn doesnt_find_project_dir_in_zip() {
422-
let file = File::open("tests/data/MakeWithoutMakefile.zip").unwrap();
406+
let file = File::open("tests/data/MakeWithoutSrc.zip").unwrap();
423407
let mut zip = ZipArchive::new(file).unwrap();
424408
let dir = MakePlugin::find_project_dir_in_zip(&mut zip);
425409
assert!(dir.is_err());

plugins/python3/src/plugin.rs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,22 +109,6 @@ impl LanguagePlugin for Python3Plugin {
109109
setup.exists() || requirements.exists() || test.exists() || tmc.exists()
110110
}
111111

112-
// returns the parent of the src directory, if one is found
113-
fn find_project_dir_in_zip<R: Read + Seek>(
114-
zip_archive: &mut ZipArchive<R>,
115-
) -> Result<PathBuf, TmcError> {
116-
for i in 0..zip_archive.len() {
117-
let file = zip_archive.by_index(i)?;
118-
let file_path = file.sanitized_name();
119-
if file_path.file_name() == Some(OsStr::new("src")) {
120-
if let Some(parent) = file_path.parent() {
121-
return Ok(parent.to_path_buf());
122-
}
123-
}
124-
}
125-
Err(TmcError::NoProjectDirInZip)
126-
}
127-
128112
fn clean(&self, exercise_path: &Path) -> Result<(), TmcError> {
129113
for entry in WalkDir::new(exercise_path)
130114
.into_iter()

plugins/r/src/plugin.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,17 @@ impl LanguagePlugin for RPlugin {
131131
zip_archive: &mut ZipArchive<R>,
132132
) -> Result<PathBuf, TmcError> {
133133
for i in 0..zip_archive.len() {
134+
// zips don't necessarily contain entries for intermediate directories,
135+
// so we need to check every path for R
134136
let file = zip_archive.by_index(i)?;
135137
let file_path = file.sanitized_name();
136-
if file_path.file_name() == Some(OsStr::new("R")) {
137-
if let Some(parent) = file_path.parent() {
138-
return Ok(parent.to_path_buf());
139-
}
140-
}
141-
if file_path.file_name() == Some(OsStr::new("testthat")) {
142-
if let Some(init_parent) = file_path.parent() {
143-
if init_parent.file_name() == Some(OsStr::new("tests")) {
144-
if let Some(test_parent) = init_parent.parent() {
145-
return Ok(test_parent.to_path_buf());
146-
}
147-
}
148-
}
138+
// todo: do in one pass somehow
139+
if file_path.components().any(|c| c.as_os_str() == "R") {
140+
let path: PathBuf = file_path
141+
.components()
142+
.take_while(|c| c.as_os_str() != "R")
143+
.collect();
144+
return Ok(path);
149145
}
150146
}
151147
Err(TmcError::NoProjectDirInZip)

tmc-langs-framework/src/plugin.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,25 @@ pub trait LanguagePlugin {
360360

361361
/// Searches the zip for a valid project directory.
362362
/// Note that the returned path may not actually have an entry in the zip.
363-
fn find_project_dir_in_zip<R: Read + Seek>(zip_archive: &mut ZipArchive<R>) -> Result<PathBuf>;
363+
/// The default implementation tries to find a directory that contains a "src" directory,
364+
/// which may be sufficient for some languages.
365+
fn find_project_dir_in_zip<R: Read + Seek>(zip_archive: &mut ZipArchive<R>) -> Result<PathBuf> {
366+
for i in 0..zip_archive.len() {
367+
// zips don't necessarily contain entries for intermediate directories,
368+
// so we need to check every path for src
369+
let file = zip_archive.by_index(i)?;
370+
let file_path = file.sanitized_name();
371+
// todo: do in one pass somehow
372+
if file_path.components().any(|c| c.as_os_str() == "src") {
373+
let path: PathBuf = file_path
374+
.components()
375+
.take_while(|c| c.as_os_str() != "src")
376+
.collect();
377+
return Ok(path);
378+
}
379+
}
380+
Err(TmcError::NoProjectDirInZip)
381+
}
364382

365383
/// Tells if there's a valid exercise in this path.
366384
fn is_exercise_type_correct(path: &Path) -> bool;

0 commit comments

Comments
 (0)