Skip to content

Commit

Permalink
Support custom package names
Browse files Browse the repository at this point in the history
  • Loading branch information
magaupp committed Nov 26, 2024
1 parent d6c458e commit 667ecc3
Show file tree
Hide file tree
Showing 27 changed files with 117 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,18 +104,27 @@ public class ProgrammingExerciseService {
* (<a href="https://docs.oracle.com/javase/specs/jls/se14/html/jls-7.html#jls-7.4.1">https://docs.oracle.com/javase/specs/jls/se14/html/jls-7.html#jls-7.4.1</a>)
* with the restriction to a-z,A-Z,_ as "Java letter" and 0-9 as digits due to JavaScript/Browser Unicode character class limitations
*/
private static final String PACKAGE_NAME_REGEX = "^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z]\\w*(?:\\.[A-Z_a-z]\\w*)*$";
private static final String PACKAGE_NAME_REGEX_FOR_JAVA_KOTLIN = "^(?!.*(?:\\.|^)(?:abstract|continue|for|new|switch|assert|default|if|package|synchronized|boolean|do|goto|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while|_|true|false|null)(?:\\.|$))[A-Z_a-z]\\w*(?:\\.[A-Z_a-z]\\w*)*$";

/**
* Swift package name Regex derived from
* (<a href="https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412">https://docs.swift.org/swift-book/ReferenceManual/LexicalStructure.html#ID412</a>),
* with the restriction to a-z,A-Z as "Swift letter" and 0-9 as digits where no separators are allowed
*/
private static final String SWIFT_PACKAGE_NAME_REGEX = "^(?!(?:associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|rethrows|static|struct|subscript|typealias|var|break|case|continue|default|defer|do|else|fallthrough|for|guard|if|in|repeat|return|switch|where|while|as|Any|catch|false|is|nil|super|self|Self|throw|throws|true|try|_|[sS]wift)$)[A-Za-z][\\dA-Za-z]*$";
private static final String PACKAGE_NAME_REGEX_FOR_SWIFT = "^(?!(?:associatedtype|class|deinit|enum|extension|fileprivate|func|import|init|inout|internal|let|open|operator|private|protocol|public|rethrows|static|struct|subscript|typealias|var|break|case|continue|default|defer|do|else|fallthrough|for|guard|if|in|repeat|return|switch|where|while|as|Any|catch|false|is|nil|super|self|Self|throw|throws|true|try|_|[sS]wift)$)[A-Za-z][\\dA-Za-z]*$";

private final Pattern packageNamePattern = Pattern.compile(PACKAGE_NAME_REGEX);
/**
* Go package name Regex derived from <a href="https://go.dev/ref/spec#Package_clause">The Go Programming Language Specification</a> limited to ASCII. Package names are
* identifiers.
* They allow letters, digits and underscore. They cannot start with a digit. The package name cannot be a keyword or "_".
*/
private static final String PACKAGE_NAME_REGEX_FOR_GO = "^(?!(?:break|default|func|interface|select|case|defer|go|map|struct|chan|else|goto|package|switch|const|fallthrough|if|range|type|continue|for|import|return|var|_)$)[A-Za-z_][A-Za-z0-9_]*$";

private static final Pattern PACKAGE_NAME_PATTERN_FOR_JAVA_KOTLIN = Pattern.compile(PACKAGE_NAME_REGEX_FOR_JAVA_KOTLIN);

private final Pattern packageNamePatternForSwift = Pattern.compile(SWIFT_PACKAGE_NAME_REGEX);
private static final Pattern PACKAGE_NAME_PATTERN_FOR_SWIFT = Pattern.compile(PACKAGE_NAME_REGEX_FOR_SWIFT);

private static final Pattern PACKAGE_NAME_PATTERN_FOR_GO = Pattern.compile(PACKAGE_NAME_REGEX_FOR_GO);

private static final Logger log = LoggerFactory.getLogger(ProgrammingExerciseService.class);

Expand Down Expand Up @@ -426,12 +435,12 @@ private void validatePackageName(ProgrammingExercise programmingExercise, Progra
}

// Check if package name matches regex
Matcher packageNameMatcher;
switch (programmingExercise.getProgrammingLanguage()) {
case JAVA, KOTLIN -> packageNameMatcher = packageNamePattern.matcher(programmingExercise.getPackageName());
case SWIFT -> packageNameMatcher = packageNamePatternForSwift.matcher(programmingExercise.getPackageName());
Matcher packageNameMatcher = switch (programmingExercise.getProgrammingLanguage()) {
case JAVA, KOTLIN -> PACKAGE_NAME_PATTERN_FOR_JAVA_KOTLIN.matcher(programmingExercise.getPackageName());
case SWIFT -> PACKAGE_NAME_PATTERN_FOR_SWIFT.matcher(programmingExercise.getPackageName());
case GO -> PACKAGE_NAME_PATTERN_FOR_GO.matcher(programmingExercise.getPackageName());
default -> throw new IllegalArgumentException("Programming language not supported");
}
};
if (!packageNameMatcher.matches()) {
throw new BadRequestAlertException("The package name is invalid", "Exercise", "packagenameInvalid");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public JenkinsProgrammingLanguageFeatureService() {
programmingLanguageFeatures.put(C, new ProgrammingLanguageFeature(C, false, false, true, false, false, List.of(FACT, GCC), false, false));
programmingLanguageFeatures.put(C_PLUS_PLUS, new ProgrammingLanguageFeature(C_PLUS_PLUS, false, false, true, false, false, List.of(), false, false));
programmingLanguageFeatures.put(C_SHARP, new ProgrammingLanguageFeature(C_SHARP, false, false, true, false, false, List.of(), false, false));
programmingLanguageFeatures.put(GO, new ProgrammingLanguageFeature(GO, false, false, true, false, false, List.of(), false, false));
programmingLanguageFeatures.put(GO, new ProgrammingLanguageFeature(GO, false, false, true, true, false, List.of(), false, false));
programmingLanguageFeatures.put(HASKELL, new ProgrammingLanguageFeature(HASKELL, false, false, false, false, true, List.of(), false, false));
programmingLanguageFeatures.put(JAVA,
new ProgrammingLanguageFeature(JAVA, true, true, true, true, false, List.of(PLAIN_GRADLE, GRADLE_GRADLE, PLAIN_MAVEN, MAVEN_MAVEN, MAVEN_BLACKBOX), true, false));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public LocalCIProgrammingLanguageFeatureService() {
programmingLanguageFeatures.put(C, new ProgrammingLanguageFeature(C, false, true, true, false, false, List.of(FACT, GCC), false, true));
programmingLanguageFeatures.put(C_PLUS_PLUS, new ProgrammingLanguageFeature(C_PLUS_PLUS, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(C_SHARP, new ProgrammingLanguageFeature(C_SHARP, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(GO, new ProgrammingLanguageFeature(GO, false, false, true, false, false, List.of(), false, true));
programmingLanguageFeatures.put(GO, new ProgrammingLanguageFeature(GO, false, false, true, true, false, List.of(), false, true));
programmingLanguageFeatures.put(HASKELL, new ProgrammingLanguageFeature(HASKELL, true, false, false, false, true, List.of(), false, true));
programmingLanguageFeatures.put(JAVA,
new ProgrammingLanguageFeature(JAVA, true, true, true, true, false, List.of(PLAIN_GRADLE, GRADLE_GRADLE, PLAIN_MAVEN, MAVEN_MAVEN), false, true));
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/exercise/bubblesort.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

type BubbleSort struct{}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/exercise/context.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

type Context struct{}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/exercise/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module artemis/assignment
module artemis/${packageName}

go 1.23.2
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/exercise/mergesort.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

type MergeSort struct{}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/exercise/policy.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

type Policy struct{}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/exercise/sortstrategy.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package assignment
package ${packageName}

type SortStrategy interface{}
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/solution/bubblesort.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

import "time"

Expand Down
6 changes: 3 additions & 3 deletions src/main/resources/templates/go/solution/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"math/rand"
"time"

"artemis/assignment"
"artemis/${packageName}"
)

// Constants define iteration and random date generation bounds.
Expand All @@ -18,8 +18,8 @@ const (
// main demonstrates the sorting process.
func main() {
// Init Context and Policy
context := assignment.NewContext()
policy := assignment.NewPolicy(context)
context := ${packageName}.NewContext()
policy := ${packageName}.NewPolicy(context)

// Run multiple times to simulate different sorting strategies
for i := 0; i < Iterations; i++ {
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/solution/context.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

import "time"

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/solution/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module artemis/assignment
module artemis/${packageName}

go 1.23.2
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/solution/mergesort.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

import "time"

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/solution/policy.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

type Policy struct {
context *Context
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/go/solution/sortstrategy.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package assignment
package ${packageName}

import "time"

Expand Down
18 changes: 9 additions & 9 deletions src/main/resources/templates/go/test/behavior/behavior_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"testing"
"time"

"artemis/assignment"
"artemis/${packageName}"
)

type SortStrategy interface {
Expand All @@ -15,8 +15,8 @@ type SortStrategy interface {
type Context interface {
GetDates() []time.Time
SetDates(dates []time.Time)
GetSortAlgorithm() assignment.SortStrategy
SetSortAlgorithm(strategy assignment.SortStrategy)
GetSortAlgorithm() ${packageName}.SortStrategy
SetSortAlgorithm(strategy ${packageName}.SortStrategy)
}

type Policy interface {
Expand All @@ -28,7 +28,7 @@ func TestBubbleSort(t *testing.T) {

dates, datesWithCorrectOrder := createTestDates()

var bubbleSortAny interface{} = assignment.NewBubbleSort()
var bubbleSortAny interface{} = ${packageName}.NewBubbleSort()
bubbleSort := bubbleSortAny.(SortStrategy)
bubbleSort.PerformSort(dates)

Expand All @@ -42,7 +42,7 @@ func TestMergeSort(t *testing.T) {

dates, datesWithCorrectOrder := createTestDates()

var mergeSortAny interface{} = assignment.NewMergeSort()
var mergeSortAny interface{} = ${packageName}.NewMergeSort()
mergeSort := mergeSortAny.(SortStrategy)
mergeSort.PerformSort(dates)

Expand Down Expand Up @@ -76,7 +76,7 @@ func TestUseMergeSortForBigList(t *testing.T) {
bigList = append(bigList, time.Unix(0, 0))
}
chosenSortStrategy := configurePolicyAndContext(bigList)
_, ok := chosenSortStrategy.(*assignment.MergeSort)
_, ok := chosenSortStrategy.(*${packageName}.MergeSort)
if !ok {
t.Fatal("The sort algorithm of Context was not MergeSort for a list with more than 10 dates.")
}
Expand All @@ -90,19 +90,19 @@ func TestUseBubbleSortForSmallList(t *testing.T) {
bigList = append(bigList, time.Unix(0, 0))
}
chosenSortStrategy := configurePolicyAndContext(bigList)
_, ok := chosenSortStrategy.(*assignment.BubbleSort)
_, ok := chosenSortStrategy.(*${packageName}.BubbleSort)
if !ok {
t.Fatal("The sort algorithm of Context was not MergeSort for a list with more than 10 dates.")
}
}

func configurePolicyAndContext(dates []time.Time) interface{} {
contextOriginal := assignment.NewContext()
contextOriginal := ${packageName}.NewContext()
var contextAny interface{} = contextOriginal
context := contextAny.(Context)
context.SetDates(dates)

var policyAny interface{} = assignment.NewPolicy(contextOriginal)
var policyAny interface{} = ${packageName}.NewPolicy(contextOriginal)
policy := policyAny.(Policy)
policy.Configure()

Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/go/test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module artemis/test

go 1.23.2

replace artemis/assignment => ${studentParentWorkingDirectoryName}
replace artemis/${packageName} => ${studentParentWorkingDirectoryName}

require artemis/assignment v0.0.0-00010101000000-000000000000
require artemis/${packageName} v0.0.0-00010101000000-000000000000
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"
"time"

"artemis/assignment"
"artemis/${packageName}"
)

type SortStrategy interface {
Expand All @@ -14,8 +14,8 @@ type SortStrategy interface {
type Context interface {
GetDates() []time.Time
SetDates(dates []time.Time)
GetSortAlgorithm() assignment.SortStrategy
SetSortAlgorithm(strategy assignment.SortStrategy)
GetSortAlgorithm() ${packageName}.SortStrategy
SetSortAlgorithm(strategy ${packageName}.SortStrategy)
}

type Policy interface {
Expand All @@ -25,31 +25,31 @@ type Policy interface {
func TestBubbleSort(t *testing.T) {
defer handlePanic(t)

var bubbleSort interface{} = new(assignment.BubbleSort)
var bubbleSort interface{} = new(${packageName}.BubbleSort)

_ = bubbleSort.(SortStrategy)
}

func TestMergeSort(t *testing.T) {
defer handlePanic(t)

var mergeSort interface{} = new(assignment.MergeSort)
var mergeSort interface{} = new(${packageName}.MergeSort)

_ = mergeSort.(SortStrategy)
}

func TestContext(t *testing.T) {
defer handlePanic(t)

var context interface{} = new(assignment.Context)
var context interface{} = new(${packageName}.Context)

_ = context.(Context)
}

func TestPolicy(t *testing.T) {
defer handlePanic(t)

var policy interface{} = new(assignment.Policy)
var policy interface{} = new(${packageName}.Policy)

_ = policy.(Policy)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export type ProgrammingExerciseCreationConfig = {
invalidRepositoryNamePattern: RegExp;
isImportFromExistingExercise: boolean;
isImportFromFile: boolean;
appNamePatternForSwift: string;
modePickerOptions?: ModePickerOption<ProjectType>[];
withDependencies: boolean;
onWithDependenciesChanged: (withDependencies: boolean) => boolean;
Expand Down
Loading

0 comments on commit 667ecc3

Please sign in to comment.