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;
}
});
}
);
}
17 changes: 16 additions & 1 deletion newIDE/app/src/ResourcesLoader/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ const isLocalFile = (urlOrFilename: string) => {
);
};

export const getLocalFileUrl = (resourceAbsolutePath: string): string => {
const normalizedPath = resourceAbsolutePath.replace(/\\/g, '/');
const pathWithLeadingSlash = normalizedPath.startsWith('/')
? normalizedPath
: '/' + normalizedPath;

return (
'file://' +
pathWithLeadingSlash
.split('/')
.map(pathSegment => encodeURIComponent(pathSegment).replace(/%3A/g, ':'))
.join('/')
);
};

/**
* A class globally used in the whole IDE to get URLs to resources of games
* (notably images).
Expand Down Expand Up @@ -140,7 +155,7 @@ export default class ResourcesLoader {
return this._cache.cacheLocalFileUrl(
project,
urlOrFilename,
'file://' + resourceAbsolutePath,
getLocalFileUrl(resourceAbsolutePath),
!!disableCacheBurst
);
}
Expand Down
25 changes: 25 additions & 0 deletions newIDE/app/src/ResourcesLoader/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// @flow
import { getLocalFileUrl } from './index';

describe('ResourcesLoader', () => {
it('encodes hash characters in local file paths', () => {
const localFileUrl = getLocalFileUrl(
'E:/Realisations/GDevelop_branding/Press/itch.io/Game Jam/Weekend Jam #1/Parts/hero.png'
);

expect(localFileUrl).toBe(
'file:///E:/Realisations/GDevelop_branding/Press/itch.io/Game%20Jam/Weekend%20Jam%20%231/Parts/hero.png'
);
expect(new URL(localFileUrl).hash).toBe('');
});

it('keeps cache-busting parameters outside of the local file path', () => {
const cachedLocalFileUrl =
getLocalFileUrl('C:/Project/Sprites/hero#idle.png') + '?cache=123';
const parsedUrl = new URL(cachedLocalFileUrl);

expect(parsedUrl.pathname).toBe('/C:/Project/Sprites/hero%23idle.png');
expect(parsedUrl.search).toBe('?cache=123');
expect(parsedUrl.hash).toBe('');
});
});