Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alert user of Theme Preview path after they've updated a file within a theme #483

Merged
merged 3 commits into from
Apr 29, 2021
Merged
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
31 changes: 31 additions & 0 deletions packages/cli-lib/lib/files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const findup = require('findup-sync');
const { getEnv } = require('./config');
const { getHubSpotWebsiteOrigin } = require('./urls');
const { ENVIRONMENTS } = require('./constants');

const getThemeJSONPath = path =>
findup('theme.json', {
cwd: path,
nocase: true,
});

const getThemeNameFromPath = filePath => {
const themeJSONPath = getThemeJSONPath(filePath);
if (!themeJSONPath) return;
const pathParts = themeJSONPath.split('/');
if (pathParts.length < 2) return;
return pathParts[pathParts.length - 2];
};

const getThemePreviewUrl = (filePath, accountId) => {
const themeName = getThemeNameFromPath(filePath);
if (!themeName) return;

const baseUrl = getHubSpotWebsiteOrigin(
getEnv() === 'qa' ? ENVIRONMENTS.QA : ENVIRONMENTS.PROD
);

return `${baseUrl}/theme-previewer/${accountId}/edit/${themeName}`;
};

module.exports = { getThemeJSONPath, getThemeNameFromPath, getThemePreviewUrl };
17 changes: 17 additions & 0 deletions packages/cli-lib/lib/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const chokidar = require('chokidar');
const { default: PQueue } = require('p-queue');

const { logger } = require('../logger');
const debounce = require('debounce');
const {
ApiErrorContext,
logApiErrorInstance,
Expand All @@ -16,11 +17,24 @@ const { upload, deleteFile } = require('../api/fileMapper');
const escapeRegExp = require('./escapeRegExp');
const { convertToUnixPath, isAllowedExtension } = require('../path');
const { triggerNotify } = require('./notify');
const { getThemePreviewUrl } = require('./files');

const queue = new PQueue({
concurrency: 10,
});

const _notifyOfThemePreview = (filePath, accountId) => {
if (queue.size > 0) return;
const previewUrl = getThemePreviewUrl(filePath, accountId);
if (!previewUrl) return;

logger.log(`
To preview this theme, visit:
${previewUrl}
`);
};
const notifyOfThemePreview = debounce(_notifyOfThemePreview, 1000);

function uploadFile(accountId, file, dest, options) {
if (!isAllowedExtension(file)) {
logger.debug(`Skipping ${file} due to unsupported extension`);
Expand All @@ -33,10 +47,12 @@ function uploadFile(accountId, file, dest, options) {

logger.debug('Attempting to upload file "%s" to "%s"', file, dest);
const apiOptions = getFileMapperQueryValues(options);

return queue.add(() => {
return upload(accountId, file, dest, apiOptions)
.then(() => {
logger.log(`Uploaded file ${file} to ${dest}`);
notifyOfThemePreview(file, accountId);
Copy link
Contributor

@gcorne gcorne Apr 29, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drewjenkins Is there a reason we're doing this in the watch library instead of the watch command? I ask because the original conception of the library package was that it could be used in other scenarios beyond just @hubspot/cli.

I also wonder if outputting as part of initial command output perhaps after the the uploading of the folder if --initial-upload is passed.

})
.catch(() => {
const uploadFailureMessage = `Uploading file ${file} to ${dest} failed`;
Expand Down Expand Up @@ -68,6 +84,7 @@ async function deleteRemoteFile(accountId, filePath, remoteFilePath) {
return deleteFile(accountId, remoteFilePath)
.then(() => {
logger.log(`Deleted file ${remoteFilePath}`);
notifyOfThemePreview(filePath, accountId);
})
.catch(error => {
logger.error(`Deleting file ${remoteFilePath} failed`);
Expand Down
14 changes: 14 additions & 0 deletions packages/cli/commands/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,23 @@ const {
const { logDebugInfo } = require('../lib/debugInfo');
const { validateAccount, validateMode } = require('../lib/validation');
const { trackCommandUsage } = require('../lib/usageTracking');
const { getThemePreviewUrl } = require('@hubspot/cli-lib/lib/files');

exports.command = 'upload <src> <dest>';
exports.describe =
'Upload a folder or file from your computer to the HubSpot CMS';

const logThemePreview = (filePath, accountId) => {
const previewUrl = getThemePreviewUrl(filePath, accountId);
// Only log if we are actually in a theme
if (previewUrl) {
logger.log(`
To preview this theme, visit:
${previewUrl}
`);
}
};

exports.handler = async options => {
const { src, dest, config: configPath } = options;
setLogLevel(options);
Expand Down Expand Up @@ -115,6 +127,7 @@ exports.handler = async options => {
normalizedDest,
accountId
);
logThemePreview(src, accountId);
})
.catch(error => {
logger.error('Uploading file "%s" to "%s" failed', src, normalizedDest);
Expand All @@ -138,6 +151,7 @@ exports.handler = async options => {
logger.success(
`Uploading files to "${dest}" in the Design Manager is complete`
);
logThemePreview(src, accountId);
})
.catch(error => {
logger.error('Uploading failed');
Expand Down