Skip to content

Commit

Permalink
Merge pull request #470 from JoyOfCodingPDX/1.1.1-SNAPSHOT
Browse files Browse the repository at this point in the history
Version 1.1.1 of top-level POM and version 1.2.0 of grader that add the ability to capture a student's GitHub username (#452) and validate that all of the desired Gradle files are submitted with an Android project (#455).
  • Loading branch information
DavidWhitlock authored Jun 17, 2024
2 parents 0f36559 + 2193188 commit 980afad
Show file tree
Hide file tree
Showing 50 changed files with 526 additions and 124 deletions.
10 changes: 5 additions & 5 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@
<parent>
<artifactId>joy</artifactId>
<groupId>io.github.davidwhitlock.joy</groupId>
<version>1.1.0</version>
<version>1.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>examples</artifactId>
<name>examples</name>
<version>1.2.0</version>
<version>1.2.1</version>
<url>https://www.cs.pdx.edu/~whitlock</url>
<dependencies>
<dependency>
<groupId>io.github.davidwhitlock.joy</groupId>
<artifactId>family</artifactId>
<version>1.1.0</version>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>io.github.davidwhitlock.joy</groupId>
<artifactId>projects</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
Expand All @@ -45,7 +45,7 @@
<dependency>
<groupId>io.github.davidwhitlock.joy</groupId>
<artifactId>projects</artifactId>
<version>1.0.0</version>
<version>2.1.1</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
Expand Down
6 changes: 3 additions & 3 deletions family/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
<parent>
<artifactId>joy</artifactId>
<groupId>io.github.davidwhitlock.joy</groupId>
<version>1.1.0</version>
<version>1.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>family</artifactId>
<packaging>jar</packaging>
<version>1.1.0</version>
<version>1.1.1</version>
<name>Family Tree Application</name>
<description>An Family Tree application for The Joy of Coding</description>
<url>https://www.cs.pdx.edu/~whitlock</url>
<dependencies>
<dependency>
<groupId>io.github.davidwhitlock.joy</groupId>
<artifactId>projects</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
</dependency>
</dependencies>
<build>
Expand Down
4 changes: 2 additions & 2 deletions grader/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<parent>
<artifactId>joy</artifactId>
<groupId>io.github.davidwhitlock.joy</groupId>
<version>1.1.0</version>
<version>1.1.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>grader</artifactId>
Expand All @@ -19,7 +19,7 @@
<dependency>
<groupId>io.github.davidwhitlock.joy</groupId>
<artifactId>projects</artifactId>
<version>2.1.0</version>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package edu.pdx.cs.joy.grader;

import org.junit.jupiter.api.BeforeEach;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class SubmitAndroidProjectIT extends SubmitIT {

@BeforeEach
@Override
public void createFilesToSubmit() throws IOException {
File mainDir = createDirectories("app", "src", "main", "java", "edu", "pdx", "cs", "joy", studentLoginId);
for (String fileName : Arrays.asList("MainActivity.java", "FirstFragment.java", "SecondFragment.java")) {
this.filesToSubmit.add(createEmptyFile(mainDir, fileName));
}

File root = tempDirectory;
for (String fileName : Arrays.asList("build.gradle", "gradle.properties", "gradlew", "settings.gradle")) {
this.filesToSubmit.add(createEmptyFile(root, fileName));
}

File appDir = createDirectories("app");
this.filesToSubmit.add(createEmptyFile(appDir, "build.gradle"));

File gradleDir = createDirectories("gradle");
this.filesToSubmit.add(createEmptyFile(gradleDir, "libs.versions.toml"));

File wrapperDir = createDirectories("gradle", "wrapper");
for (String fileName : Arrays.asList("gradle-wrapper.jar", "gradle-wrapper.properties")) {
this.filesToSubmit.add(createEmptyFile(wrapperDir, fileName));
}

}

@Override
protected ProjectSubmitter submitter() {
return new AndroidProjectSubmitter();
}

private class AndroidProjectSubmitter extends ProjectSubmitter {
@Override
protected Submit getSubmitProgram() {
return new SubmitAndroidProject(() -> submitTime);
}
}
}
28 changes: 16 additions & 12 deletions grader/src/it/java/edu/pdx/cs/joy/grader/SubmitIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public class SubmitIT extends EmailSenderIntegrationTestCase {
private final String studentFirstName = "First";
private final String studentLastName = "Last";
private final String studentName = studentFirstName + " " + studentLastName;
private final Collection<File> filesToSubmit = new ArrayList<>();
private final String studentLoginId = "student";
protected final Collection<File> filesToSubmit = new ArrayList<>();
protected final String studentLoginId = "student";
private final String projectName = "Project";
private final String graderEmail = TA_EMAIL.getAddress();

Expand Down Expand Up @@ -111,7 +111,7 @@ public void submitFilesAndDownloadSubmission() throws IOException, MessagingExce
assertThat(grade.getScore(), equalTo(Grade.NO_GRADE));
assertThat(grade.getSubmissionTimes().size(), equalTo(1));

assertZipFileContainsFilesInMavenProjectDirectories();
assertZipFileContainsFilesInProjectDirectories();
}

@Test
Expand Down Expand Up @@ -139,7 +139,7 @@ void estimatedHoursArePassedThroughToManifest() throws MessagingException, IOExc

}

private void assertZipFileContainsFilesInMavenProjectDirectories() throws IOException {
private void assertZipFileContainsFilesInProjectDirectories() throws IOException {
File zipFile = findNewestZipFileInTempDirectory();
assertThat(zipFile, is(notNullValue()));
List<String> entryNames = getZipFileEntryNames(zipFile);
Expand Down Expand Up @@ -176,27 +176,27 @@ private File findNewestZipFileInTempDirectory() {
}
}

private FileSubmitter submitter() {
return new FileSubmitter();
protected ProjectSubmitter submitter() {
return new ProjectSubmitter();
}

private class FileSubmitter {
protected class ProjectSubmitter {

private LocalDateTime submitTime = LocalDateTime.now();
protected LocalDateTime submitTime = LocalDateTime.now();
private Double estimatedHours = null;
private boolean sendReceipt = false;

public FileSubmitter setSubmitTime(LocalDateTime submitTime) {
public ProjectSubmitter setSubmitTime(LocalDateTime submitTime) {
this.submitTime = submitTime;
return this;
}

public FileSubmitter setEstimatedHours(Double estimatedHours) {
public ProjectSubmitter setEstimatedHours(Double estimatedHours) {
this.estimatedHours = estimatedHours;
return this;
}

public FileSubmitter setSendReceipt(boolean sendReceipt) {
public ProjectSubmitter setSendReceipt(boolean sendReceipt) {
this.sendReceipt = sendReceipt;
return this;
}
Expand All @@ -207,7 +207,7 @@ private void submitFiles() throws IOException, MessagingException {
student.setFirstName(studentFirstName);
student.setLastName(studentLastName);

Submit submit = new Submit(() -> submitTime);
Submit submit = getSubmitProgram();
submit.setProjectName(projectName);
submit.setStudent(student);
submit.setEstimatedHours(estimatedHours);
Expand All @@ -223,6 +223,10 @@ private void submitFiles() throws IOException, MessagingException {
submit.submit(false);
}

protected Submit getSubmitProgram() {
return new Submit(() -> submitTime);
}

}

@Override
Expand Down
86 changes: 86 additions & 0 deletions grader/src/main/java/edu/pdx/cs/joy/grader/GitConfigParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package edu.pdx.cs.joy.grader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GitConfigParser {
static final Pattern PROPERTY_PATTERN = Pattern.compile("\\s+(.*) = (.*)");
static final Pattern REMOTE_PATTERN = Pattern.compile("\\[remote \"(.*)\"]");
private final Reader reader;
private String currentSection;

public GitConfigParser(Reader reader) {
this.reader = reader;
}

public void parse(Callback callback) throws IOException {
try (BufferedReader br = new BufferedReader(this.reader)) {
for (String line = br.readLine(); line != null; line = br.readLine()) {
parseLine(line, callback);
}

endCurrentSection(callback);
}

}

private void endCurrentSection(Callback callback) {
callback.endSection(currentSection);
}

private void parseLine(String line, Callback callback) {
if (line.startsWith("[core]")) {
endCurrentSection(callback);
startCoreSection(callback);

} else if (line.startsWith("[remote ")) {
endCurrentSection(callback);
startRemoteSection(line, callback);

} else if (line.contains(" = ")) {
parseProperty(line, callback);
}

}

private void startCoreSection(Callback callback) {
this.currentSection = "core";
callback.startCoreSection();
}

private void startRemoteSection(String line, Callback callback) {
Matcher matcher = REMOTE_PATTERN.matcher(line);
if (!matcher.matches()) {
throw new IllegalStateException("Cannot parse line with remote: \"" + line + "\"");
}

String remoteName = matcher.group(1);
this.currentSection = remoteName;
callback.startRemoteSection(remoteName);
}

private void parseProperty(String line, Callback callback) {
Matcher matcher = PROPERTY_PATTERN.matcher(line);
if (!matcher.matches()) {
throw new IllegalStateException("Cannot parse line with property: \"" + line + "\"");
}

String propertyName = matcher.group(1);
String propertyValue = matcher.group(2);

callback.property(propertyName, propertyValue);
}

public interface Callback {
void startCoreSection();

void property(String name, String value);

void endSection(String name);

void startRemoteSection(String name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package edu.pdx.cs.joy.grader;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GitHubUserNameFinder implements GitConfigParser.Callback {
private String gitHubUserName;
private boolean isInOrigin;

@Override
public void startCoreSection() {

}

@Override
public void property(String name, String value) {
if (name.equals("url") && this.isInOrigin) {
extractGitHubUserNameFrom(value);
}
}

private void extractGitHubUserNameFrom(String gitUrl) {
Pattern pattern = Pattern.compile("git@github.com:(.*)/.*\\.git");
Matcher matcher = pattern.matcher(gitUrl);
if (matcher.matches()) {
this.gitHubUserName = matcher.group(1);
}
}

@Override
public void endSection(String name) {
this.isInOrigin = false;
}

@Override
public void startRemoteSection(String name) {
if (name.equals("origin")) {
this.isInOrigin = true;
}
}

public String getGitHubUserName() {
return gitHubUserName;
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package edu.pdx.cs.joy.grader;

import com.google.common.annotations.VisibleForTesting;
import jakarta.mail.MessagingException;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Set;

public class SubmitAndroidProject extends Submit {

private SubmitAndroidProject() {
this(LocalDateTime::now);
}

@VisibleForTesting
SubmitAndroidProject(CurrentTimeProvider currentTimeProvider) {
super(currentTimeProvider);
}

@Override
Expand Down
Loading

0 comments on commit 980afad

Please sign in to comment.