diff --git a/build.gradle.kts b/build.gradle.kts index 8636268..69182a2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -83,6 +83,7 @@ graalvmNative.binaries { named("main") { imageName.set("justserve") buildArgs.add("--color=always") + buildArgs.add("-march=native") } } diff --git a/src/main/java/org/justserve/cli/command/UnReassignProjects.java b/src/main/java/org/justserve/cli/command/UnReassignProjects.java index 5cb943c..5038402 100644 --- a/src/main/java/org/justserve/cli/command/UnReassignProjects.java +++ b/src/main/java/org/justserve/cli/command/UnReassignProjects.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.nio.file.Files; import java.util.Map; +import java.util.Set; import java.util.UUID; import static org.justserve.cli.util.JustServePrinter.printError; @@ -58,7 +59,7 @@ public void run() { return; } - Map projects; + Map> projects; try { projects = EmailParser.getProjects(emlContent); } catch (MessagingException | IOException | JustServeEmailParserError e) { @@ -76,45 +77,46 @@ public void run() { ProjectClient client = projectClientProvider.get(); int successCount = 0; - for (Map.Entry entry : projects.entrySet()) { + for (Map.Entry> entry : projects.entrySet()) { String projectName = entry.getKey(); - UUID projectId = entry.getValue(); - GetProjectRequest getProjectRequest = new GetProjectRequest(); - Project project; - try { - project = client.getProject(projectId, " ", getProjectRequest).body(); - } catch (HttpClientResponseException | NullPointerException e) { - printError("Failed to get project " + projectName + " (" + projectId + ")"); - log.atError().setCause(e).log("Error getting project"); - continue; - } - if (null == project.getProjectOwnerUserId()) { - warning(String.format("Project %s (%s) has no owner", projectName, projectId)); - log.warn("Project {} ({}) has no owner", projectName, projectId); - continue; - } - if (project.getProjectOwnerUserId().equals(userID)) { - log.warn("Project {} ({}) is already assigned to user {}", projectName, projectId, userID); - continue; - } - - try { - ReassignProjectRequest reassignProjectRequest = new ReassignProjectRequest(userID, project.getProjectOwnerUserId()); - log.atTrace().log("Reassigning project {} ({}) to user {}", projectName, projectId, userID); - HttpResponse reassignResponse = client.reassignProject(projectId, reassignProjectRequest); - if (reassignResponse.status() == HttpStatus.OK) { - printNormal("Successfully reassigned project %s (%s) to user %s", projectName, projectId, userID); - log.atTrace().log("received api response status: {}", reassignResponse.status()); - successCount++; + Set projectIds = entry.getValue(); + for (UUID projectId : projectIds) { + GetProjectRequest getProjectRequest = new GetProjectRequest(); + Project project; + try { + project = client.getProject(projectId, " ", getProjectRequest).body(); + } catch (HttpClientResponseException | NullPointerException e) { + printError("Failed to get project " + projectName + " (" + projectId + ")"); + log.atError().setCause(e).log("Error getting project"); continue; } - printError("Failed to reassign project " + projectName + " (" + projectId + ") to user " + userID + - ". Expected HTTP Status 'OK', but got " + reassignResponse.status()); - log.atError().log("Failed to reassign project {} ({}) to user {}. Expected HTTP Status 'OK', but got {}", - projectName, projectId, userID, reassignResponse.status()); - } catch (HttpClientResponseException e) { - printError("Failed to reassign project " + projectName + " (" + projectId + ") to user " + userID); - log.atError().setCause(e).log("Error response from API: {}", e.getResponse().body()); + if (null == project.getProjectOwnerUserId()) { + warning(String.format("Project %s (%s) has no owner", projectName, projectId)); + log.warn("Project {} ({}) has no owner", projectName, projectId); + continue; + } + if (project.getProjectOwnerUserId().equals(userID)) { + log.warn("Project {} ({}) is already assigned to user {}", projectName, projectId, userID); + continue; + } + try { + ReassignProjectRequest reassignProjectRequest = new ReassignProjectRequest(userID, project.getProjectOwnerUserId()); + log.atTrace().log("Reassigning project {} ({}) to user {}", projectName, projectId, userID); + HttpResponse reassignResponse = client.reassignProject(projectId, reassignProjectRequest); + if (reassignResponse.status() == HttpStatus.OK) { + printNormal("Successfully reassigned project %s (%s) to user %s", projectName, projectId, userID); + log.atTrace().log("received api response status: {}", reassignResponse.status()); + successCount++; + continue; + } + printError("Failed to reassign project " + projectName + " (" + projectId + ") to user " + userID + + ". Expected HTTP Status 'OK', but got " + reassignResponse.status()); + log.atError().log("Failed to reassign project {} ({}) to user {}. Expected HTTP Status 'OK', but got {}", + projectName, projectId, userID, reassignResponse.status()); + } catch (HttpClientResponseException e) { + printError("Failed to reassign project " + projectName + " (" + projectId + ") to user " + userID); + log.atError().setCause(e).log("Error response from API: {}", e.getResponse().body()); + } } } printNormal("Successfully reassigned %d projects to user %s", successCount, userID); diff --git a/src/main/java/org/justserve/util/EmailParser.java b/src/main/java/org/justserve/util/EmailParser.java index db66448..9688f79 100644 --- a/src/main/java/org/justserve/util/EmailParser.java +++ b/src/main/java/org/justserve/util/EmailParser.java @@ -32,7 +32,7 @@ public class EmailParser { * @throws JustServeEmailParserError If the email does not contain an HTML body, is not a JustServe generated email, * or the HTML structure does not conform to the expected format for extracting projects. */ - public static Map getProjects(String emlFileContent) throws MessagingException, IOException, JustServeEmailParserError { + public static Map> getProjects(String emlFileContent) throws MessagingException, IOException, JustServeEmailParserError { return getProjects(parse(emlFileContent)); } @@ -70,8 +70,8 @@ public static Document parse(String emlFileContent) throws MessagingException, I * @return A map where keys are project names (String) and values are project UUIDs. * @throws JustServeEmailParserError If the HTML structure does not conform to the expected format for extracting projects. */ - public static Map getProjects(Document doc) throws JustServeEmailParserError { - Map projects = new HashMap<>(); + public static Map> getProjects(Document doc) throws JustServeEmailParserError { + Map> projects = new HashMap<>(); Collection errors = new ArrayList<>(); /* @@ -102,7 +102,10 @@ public static Map getProjects(Document doc) throws JustServeEmailP if (uuid == null) { errors.add(String.format("Expected link to contain a valid project ID, but found none. URL: %s", link.attr("href"))); } else { - projects.put(link.text(), uuid); + if (!projects.containsKey(link.text())) { + projects.put(link.text(), new HashSet<>()); + } + projects.get(link.text()).add(uuid); } } }); diff --git a/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy b/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy index 13a084d..a680f2d 100644 --- a/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy +++ b/src/test/groovy/org/justserve/cli/command/UnReassignProjectsSpec.groovy @@ -28,7 +28,7 @@ class UnReassignProjectsSpec extends BaseCommandSpec { def setupSpec() { testEmails = new HashMap<>() - Stream.of("sara-anderson-email.eml"/*, "test-with-automated-email.eml", "test-without-automated-email.eml"*/).forEach { file -> + Stream.of("sara-anderson-email.eml", "test-with-automated-email.eml", "test-without-automated-email.eml").forEach { file -> def resource = resourceResolver.getResourceAsStream("classpath:$file") resource.ifPresent { stream -> try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { @@ -40,23 +40,14 @@ class UnReassignProjectsSpec extends BaseCommandSpec { } } - def setup() { - // Create a temporary file for the test - tempEmlFile = File.createTempFile("test-reassign", ".eml") - println "Temp file created at: " + tempEmlFile.absolutePath - } - - def cleanup() { - if (tempEmlFile != null && tempEmlFile.exists()) { - tempEmlFile.delete() - } - } - def "can make reassignments from #title to a user"(String title, String fileContent) { given: - - def args = ["unReassignProjects", "-u", readOnlyUser.uuid.toString(), "-f", "build\\resources\\test\\" + title + ".eml"] - def projectCount = EmailParser.getProjects(fileContent).size() + if (title.contains("without")) { + return + } + String testFile = new File(resourceResolver.getResource("classpath:${title}.eml").get().toURI()).absolutePath + def args = ["unReassignProjects", "-u", readOnlyUser.uuid.toString(), "-f", testFile] + def projectCount = EmailParser.getProjects(fileContent).values().flatten().size() when: def (outputStream, errorStream) = executeCommand(ctx, args as String[]) @@ -70,6 +61,5 @@ class UnReassignProjectsSpec extends BaseCommandSpec { where: [title, fileContent] << testEmails.collect { key, value -> [key, value] } - } } diff --git a/src/test/groovy/org/justserve/util/EmailParserSpec.groovy b/src/test/groovy/org/justserve/util/EmailParserSpec.groovy index b966b96..e708e63 100644 --- a/src/test/groovy/org/justserve/util/EmailParserSpec.groovy +++ b/src/test/groovy/org/justserve/util/EmailParserSpec.groovy @@ -89,7 +89,7 @@ class EmailParserSpec extends Specification { Document doc = EmailParser.parse(fileContent as String) when: - Map projects = EmailParser.getProjects(doc) + Map> projects = EmailParser.getProjects(doc) then: if (!(title as String).toLowerCase().contains("without")) { @@ -105,7 +105,7 @@ class EmailParserSpec extends Specification { def "Can use 'getProjects' to parse entire #title file"() { when: - Map projects = EmailParser.getProjects(fileContent as String) + Map> projects = EmailParser.getProjects(fileContent as String) then: if (!(title as String).toLowerCase().contains("without")) { diff --git a/src/test/resources/SpockConfig.groovy b/src/test/resources/SpockConfig.groovy index ee30777..267ec1e 100644 --- a/src/test/resources/SpockConfig.groovy +++ b/src/test/resources/SpockConfig.groovy @@ -1,5 +1,5 @@ -//runner { -// parallel { -// enabled true -// } -//} \ No newline at end of file +runner { + parallel { + enabled true + } +} \ No newline at end of file