func main(args) { var dd = Tesses.CrossLang.Args(args); if(dd.Arguments.Count > 0) { var commandName = dd.Arguments[0]; if(commandName == "args") { each(var arg : dd.Arguments) { Console.WriteLine(arg); } } else if(commandName == "build") { var offline=false; var buildPath = "."; if(dd.Arguments.Count > 1) { buildPath = dd.Arguments[1]; } each(var flag : dd.Flags) { if(flag == "offline") { offline = true; } if(flag == "help") { Console.WriteLine("USAGE: crosslang build [build-flags-and-options]"); Console.WriteLine("FLAGS:"); Console.WriteLine("offline: build with no internet (don't fetch files)"); Console.WriteLine("help: this help"); Console.WriteLine(); Console.WriteLine("OPTIONS:"); Console.WriteLine("conf=CONFIGSTRING: specify a conf string for compile_tool(s), is the property Config"); return 0; } } var conf = ""; each(var option : dd.Options) { if(option.Key == "conf") { conf = option.Value; } } var pm = Tesses.CrossLang.PackageManager(); pm.Offline = offline; var bt = Tesses.CrossLang.BuildTool(pm); bt.Config = conf; bt.BuildProject(buildPath); } else if(commandName == "run") { var offline=false; var buildPath = "."; var nobuild=false; var output=""; each(var flag : dd.Flags) { if(flag == "offline") { offline = true; } else if(flag == "help") { Console.WriteLine("USAGE: crosslang run [run-flags-and-options] program-arguments..."); Console.WriteLine("USAGE: crosslang run [run-flags-and-options] -- program-arguments-and-options..."); Console.WriteLine("FLAGS:"); Console.WriteLine("offline: build with no internet (don't fetch files)"); Console.WriteLine("help: this help"); Console.WriteLine("nobuild: don't build, just run"); Console.WriteLine(); Console.WriteLine("OPTIONS:"); Console.WriteLine("conf=CONFIGSTRING: specify a conf string for compile_tool(s), is the property Config"); return 0; } else if(flag == "nobuild") { nobuild=true; } } var conf = ""; each(var option : dd.Options) { if(option.Key == "conf") { conf = option.Value; } } if(nobuild) { if(FS.Local.FileExists("config.json")) { var proj = Json.Decode(FS.ReadAllText(FS.Local, "config.json")); var nameVer = $"{proj.name}-{proj.version}.crvm"; var buildDir = TypeOf(proj.bin_directory) == "String" ? proj.bin_directory : "bin"; output = ./buildDir/nameVer; if(!FS.Local.FileExists(output)) { Console.WriteLine($"ERROR: file {output} does not exist."); } } else { Console.WriteLine("ERROR: could not find project."); return 1; } } else { var pm = Tesses.CrossLang.PackageManager(); pm.Offline = offline; var bt = Tesses.CrossLang.BuildTool(pm); bt.Config = conf; output = bt.BuildProject(buildPath).Output; } var env = VM.CreateEnvironment({}); env.RegisterEverything(); env.LockRegister(); env.LoadFileWithDependencies(FS.Local,output); var myArgs = [output]; for(var i = 1; i < dd.Arguments.Count; i++) { myArgs.Add(dd.Arguments[i]); } return env.GetDictionary().main(myArgs); } else if(commandName == "new") { func newHelp() { Console.WriteLine($"crosslang new [FLAGS] [directory_for_project]"); Console.WriteLine("FLAGS"); Console.WriteLine("--help: Shows this help"); Console.WriteLine("--list: Lists all templates"); Console.WriteLine("ARGUMENTS:"); Console.WriteLine("template_name: The name of the template"); Console.WriteLine("directory_for_project: The directory for the project, defaults to current directory"); } var dir = FS.MakeFull(Env.Config) / "Tesses" / "CrossLang" / "Templates"; each(var flag : dd.Flags) { if(flag == "list") { Console.WriteLine("List of templates:"); each(var item : FS.Local.EnumeratePaths(dir)) { Console.WriteLine(Tesses.CrossLang.GetNameAndDescription(item)); } return 0; } else if(flag == "help") { newHelp(); return 1; } } if(dd.Arguments.Count < 2) { newHelp(); return 1; } else { var templateFile = dir / $"{dd.Arguments[1]}.crvm"; if(FS.Local.RegularFileExists(templateFile)) { var projectPath = "."; if(dd.Arguments.Count > 2) projectPath = dd.Arguments[2]; projectPath = FS.MakeFull(projectPath); FS.Local.CreateDirectory(projectPath); var projectDir = FS.SubdirFilesystem(FS.Local, projectPath); var strm = FS.Local.OpenFile(templateFile,"rb"); var res = FS.ExtractArchive(strm,projectDir); strm.Close(); if(!projectDir.RegularFileExists("/cross.json")) { Console.WriteLine("Could not find /cross.json in template"); return 1; } var jsonText = FS.ReadAllText(projectDir, "/cross.json"); var proj = Json.Decode(jsonText); proj.name = projectPath.GetFileName(); proj.version = "1.0.0.0-prod"; var old_info = proj.info; proj.info = old_info.template_info; proj.dependencies = old_info.template_project_dependencies; var srcDir = proj.source_directory; if(TypeOf(srcDir) == "Undefined") srcDir = "/src"; var filesToMutate = old_info.template_extra_text_ftles; if(TypeOf(filesToMutate) == "Undefined") filesToMutate = []; each(var f : projectDir.EnumeratePaths(srcDir)) { if(projectDir.RegularFileExists(f) && f.GetExtension() == ".tcross") { filesToMutate.Add(f); } } each(var ent : filesToMutate) { if(projectDir.RegularFileExists(ent)) { var src = FS.ReadAllText(projectDir, ent); var src = src.Replace("%PROJECT_NAME%",projectPath.GetFileName()); var src = src.Replace("%TEMPLATE_PROJECT_NAME%","%PROJECT_NAME"); FS.WriteAllText(projectDir, ent, src); } } FS.WriteAllText(projectDir, "/cross.json", Json.Encode(proj,true)); projectDir.Close(); return 0; } else { Console.WriteLine($"Error could not find template {templateFile}"); return 1; } } } else if(commandName == "install-console") { //crosslang install-console } else if(commandName == "install-app") { //crosslang install-app } else if(commandName == "install-template") { //crosslang install-template Tesses.CrossLang.Template.Console --version=1.0.0.0-prod } else if(commandName == "install-tool") { //crosslang install-tool Tesses.CrossLang.Tool.SomeTool --version=1.0.0.0-prod var toolsDir = Path.FromString(Env.Config) / "Tesses" / "CrossLang" / "Tools"; var offline=false; var buildPath = "."; var nobuild=false; var output=.; each(var flag : dd.Flags) { if(flag == "offline") { offline = true; } else if(flag == "help") { Console.WriteLine("USAGE: crosslang install-tool [flags-and-options]"); Console.WriteLine("USAGE: crosslang install-tool [PackageName] [flags-and-options]"); Console.WriteLine("FLAGS:"); Console.WriteLine("offline: build with no internet (don't fetch files)"); Console.WriteLine("help: this help"); Console.WriteLine("nobuild: don't build, just install (irrelevant if you specify a PackageName)"); Console.WriteLine(); Console.WriteLine("OPTIONS:"); Console.WriteLine("conf=CONFIGSTRING: specify a conf string for compile_tool(s), is the property Config (irrelevant if you specify a PackageName)"); Console.WriteLine("version=1.0.0.0-prod: specify the package version (irrelevant if you don't specify a PackageName)"); Console.WriteLine(); Console.WriteLine("ARGUMENTS:"); Console.WriteLine("PackageName: the package name of a tool you want to download and install, if not specified we install the tool from the current directory"); return 0; } else if(flag == "nobuild") { nobuild=true; } } if(dd.Arguments.Length == 1) { var conf = ""; each(var option : dd.Options) { if(option.Key == "conf") { conf = option.Value; } } if(FS.Local.FileExists("cross.json")) { var proj = Json.Decode(FS.ReadAllText(FS.Local,"cross.json")); var name = TypeOf(proj.info.toolname) == "String" ? proj.info.toolname : proj.name; if(proj.info.type != "tool") { Console.WriteLine("The project is not a tool"); return 1; } if(TypeOf(name) != "String") { Console.WriteLine("The tool does not have a name"); return 1; } var toolDir = toolsDir / name; FS.Local.CreateDirectory(toolDir); var toolFile = toolDir / name + ".crvm"; if(nobuild) { var nameVer = $"{proj.name}-{proj.version}.crvm"; var buildDir = TypeOf(proj.bin_directory) == "String" ? proj.bin_directory : "bin"; output = ./buildDir/nameVer; if(!FS.Local.FileExists(output)) { Console.WriteLine($"ERROR: file {output} does not exist."); return 1; } } else { var pm = Tesses.CrossLang.PackageManager(); pm.Offline = offline; var bt = Tesses.CrossLang.BuildTool(pm); bt.Config = conf; output = bt.BuildProject(buildPath).Output; } func CopyCRVM(src,dest) { func copyFile(src,dest) { var _src = FS.Local.OpenFile(src,"rb"); var _dest = FS.Local.OpenFile(dest, "wb"); _src.CopyTo(_dest); _src.Close(); _dest.Close(); Console.WriteLine($"{src} -> {dest}"); } if(FS.Local.FileExists(dest)) return; copyFile(src,dest); var srcStrm = FS.Local.OpenFile(src,"rb"); var crvm = VM.LoadExecutable(srcStrm); srcStrm.Close(); each(var dep : crvm.Dependencies) { var name = $"{dep.Name}-{dep.Version.ToString()}.crvm"; CopyCRVM(src.GetParent()/name, dest.GetParent()/name); } } CopyCRVM(output,toolFile); return 0; } else { Console.WriteLine("The current directory does not have a project"); return 1; } } } else if(commandName == "console") { //crosslang console myfavoriteapp } else if(commandName == "tool") { var dir = FS.MakeFull(Env.Config) / "Tesses" / "CrossLang" / "Tools"; if(dd.Arguments.Length == 1) { Console.WriteLine("List of tools:"); each(var item : FS.Local.EnumeratePaths(dir)) { Console.WriteLine(Tesses.CrossLang.GetNameAndDescription(item / item.GetFileName() + ".crvm")); } return 0; } } else if(commandName == "tool-test") { var pm = Tesses.CrossLang.PackageManager(); pm.Offline = false; var bt = Tesses.CrossLang.BuildTool(pm); var proj=bt.BuildProject("."); var output = proj.Output; var env = VM.CreateEnvironment({}); env.RegisterEverything(); env.LockRegister(); env.LoadFileWithDependencies(FS.Local,output); var myArgs = []; for(var i = 1; i < dd.Arguments.Count; i++) { myArgs.Add(dd.Arguments[i]); } return env.GetDictionary().RunTool({ Arguments=myArgs, Options = dd.Options, Flags = dd.Flags, ToolName = proj.Info.toolname }); } else if(commandName == "add-project") { //crosslang add-project /path/to/project if(dd.Arguments.Count > 1) { var dep = dd.Arguments[1]; if(FS.Local.DirectoryExists(dep)) { var path = Path.FromString(dep) / "cross.json"; var pathStr = FS.MakeFull(dep).CollapseRelativeParents().ToString(); if(FS.Local.FileExists(path)) { if(FS.Local.FileExists("cross.json")) { var f = FS.ReadAllText(FS.Local,"cross.json"); var json = Json.Decode(f); if(TypeOf(json.project_dependencies) == "List") { each(var item : json.project_dependencies) { var _path = FS.MakeFull(item).CollapseRelativeParents().ToString(); if(_path == pathStr) { Console.WriteLine($"The project {dep} already exists in cross.json."); return 0; } } json.project_dependencies.Add(dep); } else { json.project_dependencies = [dep]; } Console.WriteLine($"Added project {dep} to cross.json."); FS.WriteAllText(FS.Local, "cross.json", Json.Encode(json,true)); return 0; } else { Console.WriteLine("The current directory does not have a project"); return 1; } } else { Console.WriteLine($"The project file {path} does not exist"); return 1; } } else { Console.WriteLine("The project directory does not exist"); return 1; } } return 1; } else if(commandName == "add-dependency") { //crosslang add-dependency Tesses.CrossLang.Markup --version=1.0.0.0-prod } else if(commandName == "upload-package") { //crosslang upload-package [PACKAGE_NAME] } else if(commandName == "configdir") { Console.WriteLine(Tesses.CrossLang.ConfigDir); } } else { each(var flag : dd.Flags) { if(flag == "version") { Console.WriteLine($"VM version: {VM.RuntimeVersion}"); Console.WriteLine($"Shell version: {main.File.Version}"); Console.WriteLine($"Args version: {Tesses.CrossLang.Args.File.Version}"); Console.WriteLine($"BuildTool version: {Tesses.CrossLang.BuildTool.File.Version}"); return 0; } } Console.WriteLine($"USAGE: crosslang COMMAND [command-arguments]"); Console.WriteLine("COMMANDS:"); Console.WriteLine("new: create new project"); Console.WriteLine("build: build a project"); Console.WriteLine("run: run a project"); Console.WriteLine("configdir: print the config directory"); return 0; } return 0; }