Skip to content
Open
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
131 changes: 84 additions & 47 deletions newIDE/app/scripts/import-libGD.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,28 @@ if (shell.test('-f', path.join(sourceDirectory, 'libGD.js'))) {
return branch;
};

// Try to download libGD.js from a specific commit on the current branch
const downloadCommitLibGdJs = (branch, gitRef) =>
const getHashFromGitRef = gitRef => {
const hashShellString = shell.exec(`git rev-parse "${gitRef}"`, {
silent: true,
});
const hash = (hashShellString.stdout || 'unknown-hash').trim();

if (hashShellString.stderr || hashShellString.code) {
shell.echo(`⚠️ Can't find the hash of the associated commit.`);
return null;
}

return hash;
};

// Try to download libGD.js from a specific commit on the inferred branch.
const downloadCommitLibGdJs = gitRef =>
new Promise((resolve, reject) => {
shell.echo(`ℹ️ Trying to download libGD.js for ${gitRef}.`);

var hashShellString = shell.exec(`git rev-parse "${gitRef}"`, {
silent: true,
});
const hash = (hashShellString.stdout || 'unknown-hash').trim();
const hash = getHashFromGitRef(gitRef);
const branch = getBranchFromGitRef(gitRef);
if (hashShellString.stderr || hashShellString.code || !branch) {
if (!hash || !branch) {
shell.echo(
`⚠️ Can't find the hash or branch of the associated commit.`
);
Expand All @@ -91,6 +102,25 @@ if (shell.test('-f', path.join(sourceDirectory, 'libGD.js'))) {
);
});

const downloadMasterCommitLibGdJs = gitRef =>
new Promise((resolve, reject) => {
shell.echo(
`ℹ️ Trying to download libGD.js for ${gitRef} from master.`
);

const hash = getHashFromGitRef(gitRef);
if (!hash) {
reject();
return;
}

resolve(
downloadLibGdJs(
`https://s3.amazonaws.com/gdevelop-gdevelop.js/master/commit/${hash}`
)
);
});

// Try to download libGD.js from the latest version built for master branch.
const downloadBranchLatestLibGdJs = branchName => {
shell.echo(
Expand Down Expand Up @@ -151,48 +181,55 @@ if (shell.test('-f', path.join(sourceDirectory, 'libGD.js'))) {
};

const branch = getBranchFromGitRef('HEAD');
const downloadCommitLibGdJsWithMasterFallback = gitRef =>
downloadCommitLibGdJs(gitRef).catch(() =>
downloadMasterCommitLibGdJs(gitRef)
);
const tryDownloadInOrder = downloaders =>
downloaders.reduce(
(previousDownload, download) => previousDownload.catch(() => download()),
Promise.reject()
);

// Try to download the latest libGD.js, fallback to previous or master ones
// if not found (including different parents, for handling of merge commits).
downloadCommitLibGdJs(branch, 'HEAD').then(onLibGdJsDownloaded, () => {
// Force the exact version of GDevelop.js to be downloaded for AppVeyor - because
// this means we build the app and we don't want to risk mismatch (Core C++ not up to date
// with the IDE JavaScript).
if (process.env.APPVEYOR || process.env.REQUIRES_EXACT_LIBGD_JS_VERSION) {
shell.echo(
`❌ Can't download the exact required version of libGD.js - check it was built by CircleCI before running this CI.`
);
shell.echo(
`ℹ️ See the pipeline on https://app.circleci.com/pipelines/github/4ian/GDevelop.`
);
shell.exit(1);
}
downloadCommitLibGdJsWithMasterFallback('HEAD').then(
onLibGdJsDownloaded,
() => {
// Force the exact version of GDevelop.js to be downloaded for AppVeyor - because
// this means we build the app and we don't want to risk mismatch (Core C++ not up to date
// with the IDE JavaScript).
if (process.env.APPVEYOR || process.env.REQUIRES_EXACT_LIBGD_JS_VERSION) {
shell.echo(
`❌ Can't download the exact required version of libGD.js - check it was built by CircleCI before running this CI.`
);
shell.echo(
`ℹ️ See the pipeline on https://app.circleci.com/pipelines/github/4ian/GDevelop.`
);
shell.exit(1);
}

downloadCommitLibGdJs(branch, 'HEAD~1').then(onLibGdJsDownloaded, () =>
downloadCommitLibGdJs(branch, 'HEAD~2').then(onLibGdJsDownloaded, () =>
downloadCommitLibGdJs(branch, 'HEAD~3').then(onLibGdJsDownloaded, () =>
downloadBranchLatestLibGdJs(branch).then(onLibGdJsDownloaded, () =>
downloadBranchLatestLibGdJs('master').then(
onLibGdJsDownloaded,
() => {
if (alreadyHasLibGdJs) {
shell.echo(
`ℹ️ Can't download any version of libGD.js, assuming you can go ahead with the existing one.`
);
shell.exit(0);
return;
} else {
shell.echo(
`❌ Can't download any version of libGD.js, please check your internet connection.`
);
shell.exit(1);
return;
}
}
)
)
)
)
);
});
tryDownloadInOrder([
() => downloadCommitLibGdJsWithMasterFallback('HEAD~1'),
() => downloadCommitLibGdJsWithMasterFallback('HEAD~2'),
() => downloadCommitLibGdJsWithMasterFallback('HEAD~3'),
() => downloadBranchLatestLibGdJs(branch),
() => downloadBranchLatestLibGdJs('master'),
]).then(onLibGdJsDownloaded, () => {
if (alreadyHasLibGdJs) {
shell.echo(
`ℹ️ Can't download any version of libGD.js, assuming you can go ahead with the existing one.`
);
shell.exit(0);
return;
} else {
shell.echo(
`❌ Can't download any version of libGD.js, please check your internet connection.`
);
shell.exit(1);
return;
}
});
}
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
// @flow
import optionalRequire from '../../Utils/OptionalRequire';

const path = optionalRequire('path');

export const editorSettingsDirectoryName = '.gdevelop';
export const editorSettingsFileName = 'editor-settings.json';

export type ProjectEditorSettings = {|
layoutSettings: { [layoutName: string]: Object },
externalLayoutSettings: { [externalLayoutName: string]: Object },
eventsBasedObjectVariantSettings: {
[variantIdentifier: string]: Object,
},
|};

export const getProjectEditorSettingsFilePath = (
projectPath: string
): string => {
if (!path) {
throw new Error('Filesystem paths are not supported.');
}

return path.join(
projectPath,
editorSettingsDirectoryName,
editorSettingsFileName
);
};

const makeProjectEditorSettings = (): ProjectEditorSettings => ({
layoutSettings: {},
externalLayoutSettings: {},
eventsBasedObjectVariantSettings: {},
});

const hasOwn = (object: Object, propertyName: string): boolean =>
Object.keys(object).indexOf(propertyName) !== -1;

const isEmpty = (object: Object): boolean => Object.keys(object).length === 0;

const makeVariantIdentifier = (
extensionName: string,
objectName: string,
variantName: string
): string => `${extensionName}::${objectName}::${variantName}`;

export const extractProjectEditorSettings = (
serializedProjectObject: Object
): ?ProjectEditorSettings => {
const projectEditorSettings = makeProjectEditorSettings();

if (Array.isArray(serializedProjectObject.layouts)) {
serializedProjectObject.layouts.forEach(layout => {
if (
layout &&
typeof layout.name === 'string' &&
hasOwn(layout, 'uiSettings')
) {
projectEditorSettings.layoutSettings[layout.name] = layout.uiSettings;
delete layout.uiSettings;
}
});
}

if (Array.isArray(serializedProjectObject.externalLayouts)) {
serializedProjectObject.externalLayouts.forEach(externalLayout => {
if (
externalLayout &&
typeof externalLayout.name === 'string' &&
hasOwn(externalLayout, 'editionSettings')
) {
projectEditorSettings.externalLayoutSettings[externalLayout.name] =
externalLayout.editionSettings;
delete externalLayout.editionSettings;
}
});
}

if (Array.isArray(serializedProjectObject.eventsFunctionsExtensions)) {
serializedProjectObject.eventsFunctionsExtensions.forEach(extension => {
if (
!extension ||
typeof extension.name !== 'string' ||
!Array.isArray(extension.eventsBasedObjects)
) {
return;
}

extension.eventsBasedObjects.forEach(eventsBasedObject => {
if (!eventsBasedObject || typeof eventsBasedObject.name !== 'string') {
return;
}

if (hasOwn(eventsBasedObject, 'editionSettings')) {
projectEditorSettings.eventsBasedObjectVariantSettings[
makeVariantIdentifier(extension.name, eventsBasedObject.name, '')
] = eventsBasedObject.editionSettings;
delete eventsBasedObject.editionSettings;
}

if (Array.isArray(eventsBasedObject.variants)) {
eventsBasedObject.variants.forEach(variant => {
if (
variant &&
typeof variant.name === 'string' &&
hasOwn(variant, 'editionSettings')
) {
projectEditorSettings.eventsBasedObjectVariantSettings[
makeVariantIdentifier(
extension.name,
eventsBasedObject.name,
variant.name
)
] = variant.editionSettings;
delete variant.editionSettings;
}
});
}
});
});
}

if (
isEmpty(projectEditorSettings.layoutSettings) &&
isEmpty(projectEditorSettings.externalLayoutSettings) &&
isEmpty(projectEditorSettings.eventsBasedObjectVariantSettings)
) {
return null;
}

return projectEditorSettings;
};

export const applyProjectEditorSettings = (
serializedProjectObject: Object,
projectEditorSettings: ?ProjectEditorSettings
) => {
if (!projectEditorSettings) return;

const { layoutSettings } = projectEditorSettings;
if (layoutSettings && Array.isArray(serializedProjectObject.layouts)) {
serializedProjectObject.layouts.forEach(layout => {
if (
layout &&
typeof layout.name === 'string' &&
layoutSettings[layout.name]
) {
layout.uiSettings = layoutSettings[layout.name];
}
});
}

const { externalLayoutSettings } = projectEditorSettings;
if (
externalLayoutSettings &&
Array.isArray(serializedProjectObject.externalLayouts)
) {
serializedProjectObject.externalLayouts.forEach(externalLayout => {
if (
externalLayout &&
typeof externalLayout.name === 'string' &&
externalLayoutSettings[externalLayout.name]
) {
externalLayout.editionSettings =
externalLayoutSettings[externalLayout.name];
}
});
}

const { eventsBasedObjectVariantSettings } = projectEditorSettings;
if (
eventsBasedObjectVariantSettings &&
Array.isArray(serializedProjectObject.eventsFunctionsExtensions)
) {
serializedProjectObject.eventsFunctionsExtensions.forEach(extension => {
if (
!extension ||
typeof extension.name !== 'string' ||
!Array.isArray(extension.eventsBasedObjects)
) {
return;
}

extension.eventsBasedObjects.forEach(eventsBasedObject => {
if (!eventsBasedObject || typeof eventsBasedObject.name !== 'string') {
return;
}

const defaultVariantSettings =
eventsBasedObjectVariantSettings[
makeVariantIdentifier(extension.name, eventsBasedObject.name, '')
];
if (defaultVariantSettings) {
eventsBasedObject.editionSettings = defaultVariantSettings;
}

if (Array.isArray(eventsBasedObject.variants)) {
eventsBasedObject.variants.forEach(variant => {
if (!variant || typeof variant.name !== 'string') return;

const variantSettings =
eventsBasedObjectVariantSettings[
makeVariantIdentifier(
extension.name,
eventsBasedObject.name,
variant.name
)
];
if (variantSettings) {
variant.editionSettings = variantSettings;
}
});
}
});
});
}
};
Loading