Skip to content

Commit

Permalink
Merge pull request #1133 from Snowflake-Labs/snowpark-backend
Browse files Browse the repository at this point in the history
Snowpark backend
  • Loading branch information
stephengoldbaum authored Jan 23, 2024
2 parents d7dbadf + 4689058 commit a697113
Show file tree
Hide file tree
Showing 63 changed files with 11,880 additions and 5 deletions.
12 changes: 10 additions & 2 deletions cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,14 @@ async function gen(input, outputPath, options) {
opts.limitToModules = options.modulesToInclude ? options.modulesToInclude.split(",") : null
opts.includeCodecs = options.includeCodecs ? true : false
opts.filename = options.filename == '' ? '' : options.filename
const fileMap = await generate(opts, JSON.parse(morphirIrJson.toString()))

if (options.decorations) {
if (await fileExist(path.resolve(options.decorations))) {
options.decorationsObj = JSON.parse(await readFile(path.resolve(options.decorations)))
}
}

const fileMap = await generate(opts, JSON.parse(morphirIrJson.toString()))
const writePromises =
fileMap.map(async ([
[dirPath, fileName], content
Expand Down Expand Up @@ -134,7 +140,9 @@ function copyRedistributables(options, outputPath) {
copyScalaFeature('core')
} else if (options.target == 'TypeScript') {
copyFiles('TypeScript/', outputPath)
}
} else if (options.target == 'Snowpark') {
copyFiles('Snowpark/', outputPath)
}
}

function copyRecursiveSync(src, dest) {
Expand Down
1 change: 1 addition & 0 deletions cli/morphir-elm-gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ program
.option('-s, --include-codecs', 'Generate JSON codecs', false)
.option('-f, --filename <filename>', 'Filename of the generated JSON Schema.', '')
.option('-ls, --include <comma.separated,list.of,strings>', 'Limit what will be included.', '')
.option('-dec, --decorations <filename>', 'JSON file with decorations')
.parse(process.argv)

cli.gen(program.opts().input, path.resolve(program.opts().output), program.opts())
Expand Down
8 changes: 8 additions & 0 deletions cli/src/Morphir/Elm/Target.elm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Morphir.SpringBoot.Backend.Codec
import Morphir.TypeScript.Backend
import Morphir.TypeSpec.Backend
import Morphir.TypeSpec.Backend.Codec
import Morphir.Snowpark.Backend



Expand All @@ -34,6 +35,7 @@ type BackendOptions
| SparkOptions Morphir.Scala.Spark.Backend.Options
| JsonSchemaOptions Morphir.JsonSchema.Backend.Options
| TypeSpecOptions Morphir.TypeSpec.Backend.Options
| SnowparkOptions Morphir.Snowpark.Backend.Options


decodeOptions : Result Error String -> Decode.Decoder BackendOptions
Expand All @@ -53,6 +55,9 @@ decodeOptions gen =

Ok "Spark" ->
Decode.map SparkOptions (Decode.succeed Morphir.Scala.Spark.Backend.Options)

Ok "Snowpark" ->
Decode.map SnowparkOptions Morphir.Snowpark.Backend.decodeOptions

Ok "JsonSchema" ->
Decode.map JsonSchemaOptions Morphir.JsonSchema.Backend.Codec.decodeOptions
Expand Down Expand Up @@ -85,6 +90,9 @@ mapDistribution back dist =

SparkOptions options ->
Ok <| Morphir.Spark.Backend.mapDistribution options dist

SnowparkOptions options ->
Ok <| Morphir.Snowpark.Backend.mapDistribution options dist

JsonSchemaOptions options ->
Morphir.JsonSchema.Backend.mapDistribution options dist
Expand Down
146 changes: 146 additions & 0 deletions cli2/morphir-snowpark-gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#!/usr/bin/env node

// NPM imports
import * as fs from "fs";
import path from 'path';
import { Command } from 'commander'
import cli = require('./cli')
import * as util from 'util'

const fsWriteFile = util.promisify(fs.writeFile);
const fsMakeDir = util.promisify(fs.mkdir);
const fsReadFile = util.promisify(fs.readFile);

const worker = require("./../Morphir.Elm.CLI").Elm.Morphir.Elm.CLI.init();

interface CommandOptions {
/**
* Name of the decorations file to load
*/
decorations?: string;

/**
* Internal property used to send the contents of the decorations file to the Elm code.
*/
decorationsObj?: Array<{ [key: string]: Array<string> }>;
limitToModules?: string;
includeCodecs?: boolean;
target?: string;
}

function copyRedistributables(outputPath: string) {
const copyFiles = (src: string, dest: string) => {
const sourceDirectory: string = path.join(
path.dirname(__dirname),
"redistributable",
src
);
if (fs.existsSync(sourceDirectory)) {
fs.cpSync(sourceDirectory, outputPath, { recursive: true, errorOnExist: false });
} else {
console.warn(`WARNING: Cannot find directory ${sourceDirectory}`);
}
};
copyFiles("Snowpark", outputPath);
}

const generate = async (
options: CommandOptions,
ir: string
): Promise<string[]> => {
return new Promise((resolve, reject) => {
worker.ports.jsonDecodeError.subscribe((err: any) => {
reject(err);
});
worker.ports.generateResult.subscribe(([err, ok]: any) => {
if (err) {
reject(err);
} else {
resolve(ok);
}
});

worker.ports.generate.send([options, ir, []]);
});
};

const gen = async (
input: string,
outputPath: string,
options: CommandOptions
) => {
await fsMakeDir(outputPath, {
recursive: true,
});

// Add default values for these options
options.limitToModules = '';
options.includeCodecs = false;
options.target = 'Snowpark'

if (options.decorations) {
if (fs.existsSync(path.resolve(options.decorations))) {
let fileContents = await fsReadFile(path.resolve(options.decorations));
options.decorationsObj = JSON.parse(fileContents.toString());
} else {
console.warn(`WARNING: The specified decorations file do not exist: ${options.decorations}`)
}
}

const morphirIrJson: Buffer = await fsReadFile(path.resolve(input));
const generatedFiles: string[] = await generate(
options,
JSON.parse(morphirIrJson.toString())
);

const writePromises = generatedFiles.map(
async ([[dirPath, fileName], content]: any) => {
const fileDir: string = dirPath.reduce(
(accum: string, next: string) => path.join(accum, next),
outputPath
);
const filePath: string = path.join(fileDir, fileName);

if (await cli.fileExist(filePath)) {
const existingContent: Buffer = await fsReadFile(filePath);

if (existingContent.toString() !== content) {
await fsWriteFile(filePath, content);
console.log(`UPDATE - ${filePath}`);
}
} else {
await fsMakeDir(fileDir, {
recursive: true,
});
await fsWriteFile(filePath, content);
console.log(`INSERT - ${filePath}`);
}
}
);
const filesToDelete = await cli.findFilesToDelete(outputPath, generatedFiles);
const deletePromises = filesToDelete.map(async (fileToDelete: string) => {
console.log(`DELETE - ${fileToDelete}`);
return fs.unlinkSync(fileToDelete);
});
copyRedistributables(outputPath);
return Promise.all(writePromises.concat(deletePromises));
};

const program = new Command()
program
.name('morphir snowpark-gen')
.description('Generate Scala with Snowpark code from Morphir IR')
.option('-i, --input <path>', 'Source location where the Morphir IR will be loaded from.', 'morphir-ir.json')
.option('-o, --output <path>', 'Target location where the generated code will be saved.', './dist')
.option('-dec, --decorations <filename>', 'JSON file with decorations')

.parse(process.argv)

gen(program.opts().input, path.resolve(program.opts().output), program.opts())
.then(() => {
console.log('Done')
})
.catch((err) => {
console.log(err)
process.exit(1)
})
3 changes: 2 additions & 1 deletion cli2/morphir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ const program = new Command()
program
.version(packageJson.version, '-v, --version')
.command('make', 'Translate Elm sources to Morphir IR')
.command('scala-gen','Generate scala code from Morphir IR')
.command('scala-gen', 'Generate scala code from Morphir IR')
.command('json-schema-gen', 'Generate Json Schema from the Morphir IR')
.command('snowpark-gen','Generate Scala with Snowpark code from Morphir IR')
.command('stats', 'Collect morphir features used in a model into a document')
.command('dockerize', 'Creates a docker image of a Morphir IR and Morphir Develop')
.command('test-coverage', 'Generates report on number of branches in a Morphir value and TestCases covered')
Expand Down
9 changes: 8 additions & 1 deletion cli2/src/Morphir/Elm/Target.elm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Morphir.Scala.Spark.Backend
import Morphir.SpringBoot.Backend as SpringBoot
import Morphir.SpringBoot.Backend.Codec
import Morphir.TypeScript.Backend
import Morphir.Snowpark.Backend



Expand All @@ -30,7 +31,7 @@ type BackendOptions
| TypeScriptOptions Morphir.TypeScript.Backend.Options
| SparkOptions Morphir.Scala.Spark.Backend.Options
| JsonSchemaOptions JsonSchemaBackend.Options

| SnowparkOptions Morphir.Snowpark.Backend.Options

type alias Errors =
List String
Expand All @@ -54,6 +55,9 @@ decodeOptions gen =
Ok "Spark" ->
Decode.map SparkOptions (Decode.succeed Morphir.Scala.Spark.Backend.Options)

Ok "Snowpark" ->
Decode.map SnowparkOptions Morphir.Snowpark.Backend.decodeOptions

Ok "JsonSchema" ->
Decode.map (\options -> JsonSchemaOptions options) Morphir.JsonSchema.Backend.Codec.decodeOptions

Expand Down Expand Up @@ -83,6 +87,9 @@ mapDistribution backendOptions morphirTestSuite dist =
SparkOptions options ->
Ok <| Morphir.Scala.Spark.Backend.mapDistribution options dist

SnowparkOptions options ->
Ok <| Morphir.Snowpark.Backend.mapDistribution options dist

JsonSchemaOptions options ->
JsonSchemaBackend.mapDistribution options dist
|> Result.mapError Morphir.JsonSchema.Backend.Codec.encodeErrors
Loading

0 comments on commit a697113

Please sign in to comment.