Skip to content

Commit

Permalink
vscode-extension: added more project templates
Browse files Browse the repository at this point in the history
  • Loading branch information
joshtynjala committed Sep 18, 2023
1 parent 4ea9576 commit 6cf333b
Show file tree
Hide file tree
Showing 3 changed files with 444 additions and 37 deletions.
316 changes: 279 additions & 37 deletions vscode-extension/src/main/ts/commands/createNewProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,28 @@ import * as fs from "fs";
import * as path from "path";
import selectWorkspaceSDK from "./selectWorkspaceSDK";
import validateFrameworkSDK from "../utils/validateFrameworkSDK";
import validateRoyale from "../utils/validateRoyale";
import validateFlex from "../utils/validateFlex";
import validateFeathers from "../utils/validateFeathers";

const FILE_ASCONFIG_JSON = "asconfig.json";
const FILE_SETTINGS_JSON = "settings.json";
const FILE_LAUNCH_JSON = "launch.json";
const FILE_EXTENSION_AS = ".as";
const FILE_EXTENSION_MXML = ".mxml";
const FILE_EXTENSION_SWF = ".swf";

interface WorkspaceFolderQuickPickItem extends vscode.QuickPickItem {
workspaceFolder?: vscode.WorkspaceFolder;
}

interface ProjectQuickPickItem {
flex?: boolean;
royale?: boolean;
feathers?: boolean;
mobile?: boolean;
}

export function createNewProject() {
var workspaceFolders = vscode.workspace.workspaceFolders;
if (workspaceFolders == null) {
Expand Down Expand Up @@ -128,6 +139,59 @@ async function createNewProjectAtUri(uri: vscode.Uri): Promise<boolean> {
return Promise.resolve(false);
}

const isFeathers = validateFeathers(sdkPath);
const isRoyale = validateRoyale(sdkPath);
const isFlex = !isFeathers && !isRoyale && validateFlex(sdkPath);
let projectType: ProjectQuickPickItem = {};

if (isFlex) {
await vscode.window
.showQuickPick(
[
{ label: "Apache Flex Desktop", flex: true },
{ label: "Apache Flex Mobile", flex: true, mobile: true },
{ label: "ActionScript Desktop" },
{ label: "ActionScript Mobile", mobile: true },
] as (vscode.QuickPickItem & ProjectQuickPickItem)[],
{
title: "Select a project type…",
}
)
.then((result) => (projectType = result));
} else if (isRoyale) {
projectType = { royale: true };
} else if (isFeathers) {
await vscode.window
.showQuickPick(
[
{ label: "Feathers SDK Desktop", feathers: true },
{ label: "Feathers SDK Mobile", feathers: true, mobile: true },
{ label: "ActionScript Desktop" },
{ label: "ActionScript Mobile", mobile: true },
] as (vscode.QuickPickItem & ProjectQuickPickItem)[],
{
title: "Select a project type…",
}
)
.then((result) => (projectType = result));
} else {
await vscode.window
.showQuickPick(
[
{ label: "ActionScript Desktop" },
{ label: "ActionScript Mobile", mobile: true },
] as (vscode.QuickPickItem & ProjectQuickPickItem)[],
{
title: "Select a project type…",
}
)
.then((result) => (projectType = result));
}

if (!projectType) {
return;
}

fs.mkdirSync(projectRoot, { recursive: true });
const srcPath = path.resolve(projectRoot, "src");
fs.mkdirSync(srcPath, { recursive: true });
Expand All @@ -144,8 +208,9 @@ async function createNewProjectAtUri(uri: vscode.Uri): Promise<boolean> {
encoding: "utf8",
});

const launchJsonPath = path.resolve(vscodePath, FILE_LAUNCH_JSON);
const launchJsonContents = `{
if (!isRoyale) {
const launchJsonPath = path.resolve(vscodePath, FILE_LAUNCH_JSON);
const launchJsonContents = `{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
Expand All @@ -158,7 +223,8 @@ async function createNewProjectAtUri(uri: vscode.Uri): Promise<boolean> {
}
]
}`;
fs.writeFileSync(launchJsonPath, launchJsonContents, { encoding: "utf8" });
fs.writeFileSync(launchJsonPath, launchJsonContents, { encoding: "utf8" });
}

// generate the main class name from the project name
let mainClassName = path
Expand All @@ -173,44 +239,52 @@ async function createNewProjectAtUri(uri: vscode.Uri): Promise<boolean> {
}
const swfFileName = `${mainClassName}${FILE_EXTENSION_SWF}`;
const descriptorFileName = `${mainClassName}-app.xml`;
const mainClassFileName = `${mainClassName}${FILE_EXTENSION_AS}`;

const descriptorTemplatePath = sdkPath
? path.resolve(sdkPath, "templates/air/descriptor-template.xml")
: undefined;
const airDescriptorContents = createAirDescriptor(
descriptorTemplatePath,
swfFileName,
mainClassName,
mainClassName
);
if (airDescriptorContents) {
const descriptorOutputPath = path.resolve(srcPath, descriptorFileName);
fs.writeFileSync(descriptorOutputPath, airDescriptorContents, {
encoding: "utf8",
});
}

const asconfigContents = createAsconfigJson(
mainClassName,
swfFileName,
airDescriptorContents ? descriptorFileName : null,
false
);
const asconfigPath = path.resolve(projectRoot, FILE_ASCONFIG_JSON);
fs.writeFileSync(asconfigPath, asconfigContents, { encoding: "utf8" });
let hasAirDescriptor = false;
if (!isRoyale) {
const descriptorTemplatePath = sdkPath
? path.resolve(sdkPath, "templates/air/descriptor-template.xml")
: undefined;
const airDescriptorContents = createAirDescriptor(
descriptorTemplatePath,
projectType,
swfFileName,
mainClassName,
mainClassName
);
if (airDescriptorContents) {
hasAirDescriptor = true;
const descriptorOutputPath = path.resolve(srcPath, descriptorFileName);
fs.writeFileSync(descriptorOutputPath, airDescriptorContents, {
encoding: "utf8",
});
}
}

const mainClassOutputPath = path.resolve(srcPath, `${mainClassFileName}`);
const mainClassContents = createMainClassAS3(mainClassName);
fs.writeFileSync(mainClassOutputPath, mainClassContents, {
let asconfigJsonContents: string | undefined = undefined;
if (projectType.royale) {
asconfigJsonContents = createAsconfigJsonRoyale(mainClassName);
} else {
asconfigJsonContents = createAsconfigJson(
mainClassName,
swfFileName,
hasAirDescriptor ? descriptorFileName : null,
projectType.mobile
);
}
const asconfigJsonPath = path.resolve(projectRoot, FILE_ASCONFIG_JSON);
fs.writeFileSync(asconfigJsonPath, asconfigJsonContents, {
encoding: "utf8",
});

createSourceFiles(projectType, srcPath, mainClassName);

return Promise.resolve(true);
}

function createAirDescriptor(
descriptorTemplatePath: string,
projectType: ProjectQuickPickItem,
swfFileName: string,
applicationId: string,
fileName: string
Expand All @@ -234,10 +308,12 @@ function createAirDescriptor(
/<filename>.*<\/filename>(?!\s*-->)/,
`<filename>${fileName}</filename>`
);
descriptorContents = descriptorContents.replace(
/<!-- <visible><\/visible> -->/,
`<visible>true</visible>`
);
if (!projectType.flex && !projectType.royale && !projectType.feathers) {
descriptorContents = descriptorContents.replace(
/<!-- <visible><\/visible> -->/,
`<visible>true</visible>`
);
}

return descriptorContents;
}
Expand All @@ -264,10 +340,51 @@ function createAsconfigJson(
`;
}

function createMainClassAS3(mainClassName: string): string {
return `package
function createAsconfigJsonRoyale(mainClassName: string): string {
return `{
"config": "royale",
"compilerOptions": {
"targets": [
"JSRoyale"
],
"source-path": [
"src"
],
"library-path": [
"libs"
]
},
"mainClass": "${mainClassName}"
}
`;
}

function createSourceFiles(
projectType: ProjectQuickPickItem,
srcPath: string,
mainClassName: string
) {
if (projectType.flex) {
if (projectType.mobile) {
createSourceFilesFlexMobile(srcPath, mainClassName);
} else {
createSourceFilesFlexDesktop(srcPath, mainClassName);
}
} else if (projectType.royale) {
createSourceFilesRoyaleBasic(srcPath, mainClassName);
} else if (projectType.feathers) {
createSourceFilesFeathers(srcPath, mainClassName);
} else {
createSourceFilesAS3(srcPath, mainClassName);
}
}

function createSourceFilesAS3(srcPath: string, mainClassName: string) {
const mainClassContents = `package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
Expand All @@ -278,6 +395,9 @@ function createMainClassAS3(mainClassName: string): string {
{
super();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var textField:TextField = new TextField();
textField.autoSize = TextFieldAutoSize.LEFT;
textField.defaultTextFormat = new TextFormat("_sans", 12, 0x0000cc);
Expand All @@ -287,4 +407,126 @@ function createMainClassAS3(mainClassName: string): string {
}
}
`;
const mainClassOutputPath = path.resolve(
srcPath,
`${mainClassName}${FILE_EXTENSION_AS}`
);
fs.writeFileSync(mainClassOutputPath, mainClassContents, {
encoding: "utf8",
});
}

function createSourceFilesFlexDesktop(srcPath: string, mainClassName: string) {
const mainClassContents = `<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label text="Hello, Flex!"/>
</s:WindowedApplication>
`;
const mainClassOutputPath = path.resolve(
srcPath,
`${mainClassName}${FILE_EXTENSION_MXML}`
);
fs.writeFileSync(mainClassOutputPath, mainClassContents, {
encoding: "utf8",
});
}

function createSourceFilesFlexMobile(srcPath: string, mainClassName: string) {
const mainClassContents = `<?xml version="1.0" encoding="utf-8"?>
<s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
firstView="views.HomeView"
applicationDPI="160">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:ViewNavigatorApplication>
`;
const mainClassOutputPath = path.resolve(
srcPath,
`${mainClassName}${FILE_EXTENSION_MXML}`
);
fs.writeFileSync(mainClassOutputPath, mainClassContents, {
encoding: "utf8",
});

const viewsPath = path.resolve(srcPath, "views");
fs.mkdirSync(viewsPath, { recursive: true });
const homeViewClassContents = `<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="Home">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label text="Hello, Flex Mobile!"/>
</s:View>
`;
const homeViewClassOutputPath = path.resolve(
srcPath,
`views/HomeView${FILE_EXTENSION_MXML}`
);
fs.writeFileSync(homeViewClassOutputPath, homeViewClassContents, {
encoding: "utf8",
});
}

function createSourceFilesRoyaleBasic(srcPath: string, mainClassName: string) {
const mainClassContents = `<?xml version="1.0" encoding="utf-8"?>
<js:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:js="library://ns.apache.org/royale/basic">
<fx:Declarations>
</fx:Declarations>
<js:valuesImpl>
<js:SimpleCSSValuesImpl/>
</js:valuesImpl>
<js:initialView>
<js:View>
<js:Label text="Hello, Apache Royale!"/>
</js:View>
</js:initialView>
<fx:Script>
<![CDATA[
]]>
</fx:Script>
</js:Application>
`;
const mainClassOutputPath = path.resolve(
srcPath,
`${mainClassName}${FILE_EXTENSION_MXML}`
);
fs.writeFileSync(mainClassOutputPath, mainClassContents, {
encoding: "utf8",
});
}

function createSourceFilesFeathers(srcPath: string, mainClassName: string) {
const mainClassContents = `<?xml version="1.0" encoding="utf-8"?>
<f:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:f="library://ns.feathersui.com/mxml">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<f:Label text="Hello, Feathers!"/>
</f:Application>
`;
const mainClassOutputPath = path.resolve(
srcPath,
`${mainClassName}${FILE_EXTENSION_MXML}`
);
fs.writeFileSync(mainClassOutputPath, mainClassContents, {
encoding: "utf8",
});
}
Loading

0 comments on commit 6cf333b

Please sign in to comment.