+
Skip to content
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Find out in seconds whether the setup is right, all in your local.

Local CI requires a [license key](https://getlocalci.com/pricing/?utm_medium=extension&utm_source=readme) for $15 per month.

But first you'll get a free 15-day preview, no sign-up or credit card needed.
But first you'll get a free 15-day preview, no credit card needed.

## Requirements

Expand Down
9 changes: 9 additions & 0 deletions src/classes/IconCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as vscode from 'vscode';
import Command from './Command';

export default class IconCommand extends Command {
constructor(public readonly label: string, command: string, icon: string) {
super(label, command);
this.iconPath = new vscode.ThemeIcon(icon);
}
}
30 changes: 25 additions & 5 deletions src/classes/JobProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ import getDockerError from '../utils/getDockerError';
import prepareConfig from '../utils/prepareConfig';
import {
CREATE_CONFIG_FILE_COMMAND,
DAY_IN_MILLISECONDS,
ENTER_LICENSE_COMMAND,
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
GET_LICENSE_COMMAND,
JOB_TREE_VIEW_ID,
PROCESS_TRY_AGAIN_COMMAND,
TAKE_SURVEY_COMMAND,
TRIAL_STARTED_TIMESTAMP,
TRIAL_LENGTH_IN_MILLISECONDS,
} from '../constants';
import shouldOfferSurvey from '../utils/shouldOfferSurvey';
import IconCommand from './IconCommand';

enum JobError {
DockerNotRunning,
Expand Down Expand Up @@ -221,6 +227,11 @@ export default class JobProvider

getErrorTreeItems(): Array<vscode.TreeItem | Command | Warning> {
const errorMessage = this.getJobErrorMessage();
const licenseKeyTreeItems = [
new Warning('Please enter a Local CI license key.'),
new Command('Get License', GET_LICENSE_COMMAND),
new Command('Enter License', ENTER_LICENSE_COMMAND),
];

switch (this.jobErrorType) {
case JobError.DockerNotRunning:
Expand All @@ -230,11 +241,20 @@ export default class JobProvider
new Command('Try Again', `${JOB_TREE_VIEW_ID}.refresh`),
];
case JobError.LicenseKey:
return [
new Warning('Please enter a Local CI license key.'),
new Command('Get License', GET_LICENSE_COMMAND),
new Command('Enter License', ENTER_LICENSE_COMMAND),
];
return shouldOfferSurvey(this.context)
? [
...licenseKeyTreeItems,
new IconCommand(
`Get ${
(TRIAL_LENGTH_IN_MILLISECONDS +
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS) /
DAY_IN_MILLISECONDS
} more free days by taking a 2-minute survey`,
TAKE_SURVEY_COMMAND,
'rocket'
),
]
: licenseKeyTreeItems;
case JobError.NoConfigFilePathInWorkspace:
return [
new Warning('Error: No .circleci/config.yml found'),
Expand Down
31 changes: 6 additions & 25 deletions src/classes/LicenseProvider.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
import * as vscode from 'vscode';
import {
EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS,
HAS_EXTENDED_TRIAL,
LICENSE_ERROR,
SURVEY_URL,
TRIAL_LENGTH_IN_MILLISECONDS,
TRIAL_STARTED_TIMESTAMP,
} from '../constants';
import { LICENSE_ERROR } from '../constants';
import getLicenseErrorMessage from '../utils/getLicenseErrorMessage';
import getLicenseInformation from '../utils/getLicenseInformation';
import getPrettyPrintedTimeRemaining from '../utils/getPrettyPrintedTimeRemaining';
import isLicenseValid from '../utils/isLicenseValid';
import onClickTakeSurvey from '../utils/onClickTakeSurvey';
import showLicenseInput from '../utils/showLicenseInput';

function getNonce() {
Expand Down Expand Up @@ -76,22 +69,10 @@ export default class LicenseProvider implements vscode.WebviewViewProvider {
}

if (data.type === 'takeSurvey') {
if (this.context.globalState.get(HAS_EXTENDED_TRIAL)) {
return;
}

this.load();
this.context.globalState.update(HAS_EXTENDED_TRIAL, true);
this.context.globalState.update(
TRIAL_STARTED_TIMESTAMP,
new Date().getTime()
);
vscode.env.openExternal(vscode.Uri.parse(SURVEY_URL));
vscode.window.showInformationMessage(
`Thanks, your free preview is now ${getPrettyPrintedTimeRemaining(
TRIAL_LENGTH_IN_MILLISECONDS + EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS
)} longer`
);
onClickTakeSurvey(this.context, () => {
this.load();
this.licenseSuccessCallback();
});
}
});
}
Expand Down
8 changes: 5 additions & 3 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const SELECTED_CONFIG_PATH = 'local-ci.config.path';
export const LICENSE_ERROR = 'localCiLicenseKeyError';
export const GET_LICENSE_COMMAND = 'local-ci.license.get';
export const ENTER_LICENSE_COMMAND = 'local-ci.license.enter';
export const SURVEY_URL = 'https://www.surveymonkey.com/r/J2HWF5S';
export const TAKE_SURVEY_COMMAND = 'local-ci.survey.take';
export const EXIT_JOB_COMMAND = 'local-ci.job.exit';
export const PROCESS_TRY_AGAIN_COMMAND = 'local-ci.process-error.try-again';

Expand Down Expand Up @@ -42,8 +44,9 @@ export const LICENSE_KEY = 'local-ci.license.key';
export const LICENSE_VALIDITY = 'local-ci.license.validity';
export const LICENSE_VALIDITY_CACHE_EXPIRATION =
'local-ci.license.cache.expiration';
export const TRIAL_LENGTH_IN_MILLISECONDS = 1296000000; // 15 days.
export const EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS = 1296000000; // 15 days.
export const DAY_IN_MILLISECONDS = 86400000;
export const TRIAL_LENGTH_IN_MILLISECONDS = 15 * DAY_IN_MILLISECONDS;
export const EXTENDED_TRIAL_LENGTH_IN_MILLISECONDS = 15 * DAY_IN_MILLISECONDS;
export const HAS_EXTENDED_TRIAL = 'local-ci.license.trial-extended.survey';
export const TRIAL_STARTED_TIMESTAMP =
'local-ci.license.trial-started.timestamp';
Expand All @@ -65,5 +68,4 @@ export const SCHEDULE_INTERVIEW_URL =
'https://tidycal.com/localci/30-minute-meeting';
export const SUPPRESS_UNCOMMITTED_FILE_WARNING =
'local-ci.suppress-warning.uncommitted';
export const SURVEY_URL = 'https://www.surveymonkey.com/r/J2HWF5S';
export const TELEMETRY_KEY = '90189d4e-b560-4a92-aa2c-5a9df190b66a'; // Microsoft.AppInsights Instrumentation Key.
8 changes: 8 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
RUN_JOB_COMMAND,
SELECTED_CONFIG_PATH,
SHOW_LOG_FILE_COMMAND,
TAKE_SURVEY_COMMAND,
TELEMETRY_KEY,
TRIAL_STARTED_TIMESTAMP,
} from './constants';
Expand All @@ -38,6 +39,7 @@ import getDynamicConfigPath from './utils/getDynamicConfigPath';
import getFinalTerminalName from './utils/getFinalTerminalName';
import getRepoBasename from './utils/getRepoBasename';
import getStarterConfig from './utils/getStarterConfig';
import onClickTakeSurvey from './utils/onClickTakeSurvey';
import prepareConfig from './utils/prepareConfig';
import runJob from './utils/runJob';
import showLicenseInput from './utils/showLicenseInput';
Expand Down Expand Up @@ -86,6 +88,12 @@ export function activate(context: vscode.ExtensionContext): void {

context.subscriptions.push(
reporter,
vscode.commands.registerCommand(TAKE_SURVEY_COMMAND, () => {
onClickTakeSurvey(context, () => {
licenseProvider.load();
jobProvider.hardRefresh();
});
}),
vscode.commands.registerCommand(`${JOB_TREE_VIEW_ID}.refresh`, () =>
jobProvider.hardRefresh()
),
Expand Down
12 changes: 7 additions & 5 deletions src/test/suite/utils/getMillisecondsRemainingInTrial.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import * as assert from 'assert';
import { TRIAL_LENGTH_IN_MILLISECONDS } from '../../../constants';
import {
DAY_IN_MILLISECONDS,
TRIAL_LENGTH_IN_MILLISECONDS,
} from '../../../constants';
import getMillisecondsRemainingInTrial from '../../../utils/getMillisecondsRemainingInTrial';

const hourInMilliseconds = 3600000;
const dayInMilliseconds = 86400000;

suite('getMillisecondsRemainingInTrial', () => {
test('entire trial remaining', () => {
Expand All @@ -22,7 +24,7 @@ suite('getMillisecondsRemainingInTrial', () => {
time - 24 * hourInMilliseconds,
TRIAL_LENGTH_IN_MILLISECONDS
),
14 * dayInMilliseconds
14 * DAY_IN_MILLISECONDS
);
});

Expand All @@ -31,7 +33,7 @@ suite('getMillisecondsRemainingInTrial', () => {
assert.strictEqual(
getMillisecondsRemainingInTrial(
time,
time - (14 * dayInMilliseconds + 23 * hourInMilliseconds),
time - (14 * DAY_IN_MILLISECONDS + 23 * hourInMilliseconds),
TRIAL_LENGTH_IN_MILLISECONDS
),
hourInMilliseconds
Expand All @@ -43,7 +45,7 @@ suite('getMillisecondsRemainingInTrial', () => {
assert.strictEqual(
getMillisecondsRemainingInTrial(
time,
time - 15 * dayInMilliseconds,
time - 15 * DAY_IN_MILLISECONDS,
TRIAL_LENGTH_IN_MILLISECONDS
),
0
Expand Down
30 changes: 16 additions & 14 deletions src/test/suite/utils/getTimeRemainingInTrial.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as assert from 'assert';
import { TRIAL_LENGTH_IN_MILLISECONDS } from '../../../constants';
import {
DAY_IN_MILLISECONDS,
TRIAL_LENGTH_IN_MILLISECONDS,
} from '../../../constants';
import getTimeRemainingInTrial from '../../../utils/getTimeRemainingInTrial';

const minuteInMilliseconds = 60000;
const hourInMilliseconds = 3600000;
const dayInMilliseconds = 86400000;

suite('getTimeRemainingInTrial', () => {
const time = new Date().getTime();
Expand All @@ -20,7 +22,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time,
14 * dayInMilliseconds + 13 * hourInMilliseconds
14 * DAY_IN_MILLISECONDS + 13 * hourInMilliseconds
),
'15 days'
);
Expand All @@ -31,22 +33,22 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time,
14 * dayInMilliseconds + 11 * hourInMilliseconds
14 * DAY_IN_MILLISECONDS + 11 * hourInMilliseconds
),
'14 days, 11 hours'
);
});

test('14 days remaining', () => {
assert.strictEqual(
getTimeRemainingInTrial(time, time, 14 * dayInMilliseconds),
getTimeRemainingInTrial(time, time, 14 * DAY_IN_MILLISECONDS),
'14 days'
);
});

test('2 hours remaining', () => {
assert.strictEqual(
getTimeRemainingInTrial(time, time, dayInMilliseconds * 2),
getTimeRemainingInTrial(time, time, DAY_IN_MILLISECONDS * 2),
'2 days'
);
});
Expand All @@ -56,7 +58,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 10 * hourInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'2 days'
);
Expand All @@ -67,7 +69,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 24 * hourInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'1 day'
);
Expand All @@ -78,7 +80,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 43 * hourInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'5 hours'
);
Expand All @@ -89,7 +91,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'1 hour'
);
Expand All @@ -100,7 +102,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds - 37 * minuteInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'23 minutes'
);
Expand All @@ -111,7 +113,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds - 59 * minuteInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'1 minute'
);
Expand All @@ -122,7 +124,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 47 * hourInMilliseconds - 59 * minuteInMilliseconds - 30000,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'No time'
);
Expand All @@ -133,7 +135,7 @@ suite('getTimeRemainingInTrial', () => {
getTimeRemainingInTrial(
time,
time - 48 * hourInMilliseconds,
dayInMilliseconds * 2
DAY_IN_MILLISECONDS * 2
),
'No time'
);
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载