Skip to content

Commit 943052f

Browse files
authored
Merge pull request #91 from rage/make-project-detection
only detect project as make if it contains src
2 parents a3a6181 + 20da3ff commit 943052f

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

plugins/make/src/plugin.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::valgrind_log::ValgrindLog;
77
use lazy_static::lazy_static;
88
use regex::Regex;
99
use std::collections::HashMap;
10-
use std::io::{self, BufRead, BufReader};
10+
use std::io::{self, BufRead, BufReader, Read, Seek};
1111
use std::path::{Path, PathBuf};
1212
use std::time::Duration;
1313
use tmc_langs_framework::{
@@ -19,6 +19,7 @@ use tmc_langs_framework::{
1919
nom::{bytes, character, combinator, sequence, IResult},
2020
plugin::LanguagePlugin,
2121
subprocess::PopenError,
22+
zip::ZipArchive,
2223
TmcError, TmcProjectYml,
2324
};
2425

@@ -288,9 +289,40 @@ impl LanguagePlugin for MakePlugin {
288289
Ok(run_result)
289290
}
290291

291-
/// Checks if the directory has a Makefile in it.
292+
fn find_project_dir_in_zip<R: Read + Seek>(
293+
zip_archive: &mut ZipArchive<R>,
294+
) -> Result<PathBuf, TmcError> {
295+
for i in 0..zip_archive.len() {
296+
// zips don't necessarily contain entries for intermediate directories,
297+
// so we need to check every path for src
298+
let file = zip_archive.by_index(i)?;
299+
let file_path = PathBuf::from(file.name());
300+
drop(file);
301+
302+
// todo: do in one pass somehow
303+
if file_path.components().any(|c| c.as_os_str() == "src") {
304+
let path: PathBuf = file_path
305+
.components()
306+
.take_while(|c| c.as_os_str() != "src")
307+
.collect();
308+
309+
if path.components().any(|p| p.as_os_str() == "__MACOSX") {
310+
continue;
311+
}
312+
// found src not in __MACOSX, check for Makefile
313+
if let Some(makefile_path) = path.join("Makefile").to_str() {
314+
if zip_archive.by_name(makefile_path).is_ok() {
315+
return Ok(path);
316+
}
317+
}
318+
}
319+
}
320+
Err(TmcError::NoProjectDirInZip)
321+
}
322+
323+
/// Checks if the directory has a src dir and a Makefile file in it.
292324
fn is_exercise_type_correct(path: &Path) -> bool {
293-
path.join("Makefile").is_file()
325+
path.join("src").is_dir() && path.join("Makefile").is_file()
294326
}
295327

296328
// does not check for success
@@ -539,6 +571,7 @@ test [invalid] point6
539571
init();
540572
let temp_dir = tempfile::tempdir().unwrap();
541573
dir_to(&temp_dir, "Outer/Inner/make_project/src");
574+
file_to(&temp_dir, "Outer/Inner/make_project/Makefile", "");
542575

543576
let zip_contents = dir_to_zip(&temp_dir);
544577
let mut zip = ZipArchive::new(std::io::Cursor::new(zip_contents)).unwrap();
@@ -551,7 +584,8 @@ test [invalid] point6
551584
init();
552585

553586
let temp_dir = tempfile::tempdir().unwrap();
554-
dir_to(&temp_dir, "Outer/Inner/make_project/srcb");
587+
dir_to(&temp_dir, "Outer/Inner/make_project/src");
588+
file_to(&temp_dir, "Outer/Inner/make_project/Makefil", "");
555589

556590
let zip_contents = dir_to_zip(&temp_dir);
557591
let mut zip = ZipArchive::new(std::io::Cursor::new(zip_contents)).unwrap();

0 commit comments

Comments
 (0)