Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions showcases/format-showcases.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash

# Script to run the ShowcaseFormatter

# Build the project
mvn clean package

# Run the formatter
java -cp target/legend-showcases-1.0-SNAPSHOT-jar-with-dependencies.jar org.example.ShowcaseFormatter $@
43 changes: 35 additions & 8 deletions showcases/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,51 +26,53 @@
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-extensions-collection-generation</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-extensions-collection-execution</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>

<!-- DEPENDENCIES BELOW ARE MISSING FROM COLLECTIONS ABOVE -->
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-test-runner-service</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-test-runner-function</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-test-runner-mapping</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-configuration-contract-extension-pure</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-configuration-plan-generation-serialization</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-shared-core</artifactId>
<version>${legend.engine.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-language-pure-grammar</artifactId>
<version>${legend.engine.version}</version>
</dependency>
<dependency>
<groupId>org.finos.legend.engine</groupId>
<artifactId>legend-engine-language-pure-compiler</artifactId>
<version>${legend.engine.version}</version>
</dependency>
<!-- -->
<dependency>
Expand Down Expand Up @@ -128,6 +130,31 @@
<target>11</target>
</configuration>
</plugin>
<!-- Add this plugin to create an executable jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>org.example.ShowcaseFormatter</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
112 changes: 112 additions & 0 deletions showcases/src/main/java/org/example/ShowcaseFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.example;

import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser;
import org.finos.legend.engine.language.pure.grammar.to.PureGrammarComposer;
import org.finos.legend.engine.language.pure.grammar.to.PureGrammarComposerContext;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.shared.core.api.grammar.RenderStyle;

import java.io.IOException;
import java.nio.file.*;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* Utility class to format showcase .pure files using the PureGrammarParser and PureGrammarComposer.
* This helps developers maintain consistent formatting when adding new showcases.
*/
public class ShowcaseFormatter {
private static final PathMatcher PURE_FILE_MATCHER = FileSystems.getDefault().getPathMatcher("glob:*.pure");

/**
* Main method to run the formatter from the command line.
* Usage: java org.example.ShowcaseFormatter [directory]
* If no directory is specified, defaults to "data" in the current directory.
*/
public static void main(String[] args) {
String directory = args.length > 0 ? args[0] : "data";
try {
formatDirectory(Paths.get(directory));
System.out.println("Formatting completed successfully.");
} catch (IOException e) {
System.err.println("Error formatting files: " + e.getMessage());
e.printStackTrace();
}
}

/**
* Format all .pure files in the specified directory and its subdirectories.
*
* @param directory the directory containing .pure files to format
* @throws IOException if an I/O error occurs
*/
public static void formatDirectory(Path directory) throws IOException {
if (!Files.isDirectory(directory)) {
throw new IllegalArgumentException("Not a directory: " + directory);
}

Set<Path> pureFiles = findPureFiles(directory);
System.out.println("Found " + pureFiles.size() + " .pure files to format.");

for (Path file : pureFiles) {
formatFile(file);
}
}

/**
* Find all .pure files in the specified directory and its subdirectories.
*
* @param directory the directory to search in
* @return a set of paths to .pure files
* @throws IOException if an I/O error occurs
*/
private static Set<Path> findPureFiles(Path directory) throws IOException {
try (Stream<Path> pathStream = Files.walk(directory)) {
return pathStream
.filter(p -> !Files.isDirectory(p))
.filter(p -> PURE_FILE_MATCHER.matches(p.getFileName()))
.collect(Collectors.toSet());
}
}

/**
* Format a single .pure file.
*
* @param filePath the path to the .pure file
* @throws IOException if an I/O error occurs
*/
public static void formatFile(Path filePath) throws IOException {
System.out.println("Formatting file: " + filePath);

try {
// Read the file content and strip comments
String pureGrammar = Files.readAllLines(filePath).stream()
.filter(l -> !l.stripLeading().startsWith("//"))
.collect(Collectors.joining("\n"));

if (pureGrammar.isEmpty()) {
System.out.println("Skipping empty file: " + filePath);
return;
}

// Parse the grammar
PureModelContextData pureModelContextData = PureGrammarParser.newInstance().parseModel(pureGrammar, "", 0, 0, true);

// Format the grammar with pretty printing
PureGrammarComposer grammarComposer = PureGrammarComposer.newInstance(
PureGrammarComposerContext.Builder.newInstance().withRenderStyle(RenderStyle.PRETTY).build());

// Get the formatted grammar
String composedPureGrammar = grammarComposer.renderPureModelContextData(pureModelContextData);

// Write the formatted grammar back to the file
Files.write(filePath, composedPureGrammar.getBytes());

System.out.println("Successfully formatted: " + filePath);
} catch (Exception e) {
System.err.println("Error formatting file " + filePath + ": " + e.getMessage());
e.printStackTrace();
}
}
}
59 changes: 59 additions & 0 deletions showcases/src/test/java/org/example/ShowcaseFormatterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.example;

import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import static org.junit.Assert.assertTrue;

public class ShowcaseFormatterTest {

@Test
public void testFindPureFiles() throws IOException {
// Create a temporary directory structure
Path tempDir = Files.createTempDirectory("showcase-formatter-test");

// Create a sample .pure file
Path sampleFile = tempDir.resolve("sample.pure");
Files.write(sampleFile, List.of("// This is a test file"));

// Create a subdirectory with another .pure file
Path subDir = tempDir.resolve("subdir");
Files.createDirectories(subDir);
Path subDirFile = subDir.resolve("subdir-sample.pure");
Files.write(subDirFile, List.of("// This is another test file"));

// Create a non-.pure file
Path nonPureFile = tempDir.resolve("not-pure.txt");
Files.write(nonPureFile, List.of("This is not a .pure file"));

// Test that the formatter can find all .pure files
int pureFileCount = 0;
File dir = tempDir.toFile();
for (File file : dir.listFiles()) {
if (file.getName().endsWith(".pure")) {
pureFileCount++;
}
if (file.isDirectory()) {
for (File subFile : file.listFiles()) {
if (subFile.getName().endsWith(".pure")) {
pureFileCount++;
}
}
}
}

// Verify we found 2 .pure files
assertTrue("Should find 2 .pure files", pureFileCount == 2);

// Clean up
Files.deleteIfExists(subDirFile);
Files.deleteIfExists(subDir);
Files.deleteIfExists(sampleFile);
Files.deleteIfExists(nonPureFile);
Files.deleteIfExists(tempDir);
}
}