-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathinit.ts
115 lines (94 loc) · 4.05 KB
/
init.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { basename } from 'node:path';
import process from 'node:process';
import { Args, Flags } from '@oclif/core';
import inquirer from 'inquirer';
import { ApifyCommand } from '../lib/apify_command.js';
import {
CommandExitCodes,
DEFAULT_LOCAL_STORAGE_DIR,
EMPTY_LOCAL_CONFIG,
LOCAL_CONFIG_PATH,
PROJECT_TYPES,
} from '../lib/consts.js';
import { useActorConfig } from '../lib/hooks/useActorConfig.js';
import { ProjectLanguage, useCwdProject } from '../lib/hooks/useCwdProject.js';
import { createPrefilledInputFileFromInputSchema } from '../lib/input_schema.js';
import { error, info, success, warning } from '../lib/outputs.js';
import { wrapScrapyProject } from '../lib/projects/scrapy/wrapScrapyProject.js';
import { setLocalConfig, setLocalEnv, validateActorName } from '../lib/utils.js';
export class InitCommand extends ApifyCommand<typeof InitCommand> {
static override description =
`Sets up an Actor project in your current directory by creating actor.json and storage files.\n` +
`If the directory contains a Scrapy project in Python, the command automatically creates wrappers so that you can run your scrapers without changes.\n` +
`Creates the '${LOCAL_CONFIG_PATH}' file and the '${DEFAULT_LOCAL_STORAGE_DIR}' directory in the current directory, but does not touch any other existing files or directories.\n\n` +
`WARNING: Overwrites existing '${DEFAULT_LOCAL_STORAGE_DIR}' directory.`;
static override args = {
actorName: Args.string({
required: false,
description: 'Name of the Actor. If not provided, you will be prompted for it.',
}),
};
static override flags = {
yes: Flags.boolean({
char: 'y',
description:
'Automatic yes to prompts; assume "yes" as answer to all prompts. Note that in some cases, the command may still ask for confirmation.',
required: false,
}),
};
async run() {
let { actorName } = this.args;
const cwd = process.cwd();
const projectResult = await useCwdProject();
// TODO: use direct .unwrap() once we migrate to yargs
if (projectResult.isErr()) {
error({ message: projectResult.unwrapErr().message });
process.exit(1);
}
const project = projectResult.unwrap();
if (project.type === ProjectLanguage.Scrapy) {
info({ message: 'The current directory looks like a Scrapy project. Using automatic project wrapping.' });
this.telemetryData.actorWrapper = PROJECT_TYPES.SCRAPY;
return wrapScrapyProject({ projectPath: cwd });
}
if (!this.flags.yes && project.type === ProjectLanguage.Unknown) {
warning({ message: 'The current directory does not look like a Node.js or Python project.' });
const { c } = await inquirer.prompt([{ name: 'c', message: 'Do you want to continue?', type: 'confirm' }]);
if (!c) return;
}
const actorConfig = await useActorConfig({ cwd });
if (actorConfig.isOkAnd((cfg) => cfg.exists && !cfg.migrated)) {
warning({
message: `Skipping creation of '${LOCAL_CONFIG_PATH}', the file already exists in the current directory.`,
});
} else {
if (actorConfig.isErr()) {
error({ message: actorConfig.unwrapErr().message });
process.exitCode = CommandExitCodes.InvalidActorJson;
return;
}
if (!actorName) {
let response = actorConfig.isOk() ? { actName: actorConfig.unwrap().config.name as string } : null;
while (!response) {
try {
const answer = await inquirer.prompt([
{ name: 'actName', message: 'Actor name:', default: basename(cwd), type: 'input' },
]);
validateActorName(answer.actName);
response = answer;
} catch (err) {
error({ message: (err as Error).message });
}
}
({ actName: actorName } = response);
}
// Migrate apify.json to .actor/actor.json
const localConfig = { ...EMPTY_LOCAL_CONFIG, ...actorConfig.unwrap().config };
await setLocalConfig(Object.assign(localConfig, { name: actorName }), cwd);
}
await setLocalEnv(cwd);
// Create prefilled INPUT.json file from the input schema prefills
await createPrefilledInputFileFromInputSchema(cwd);
success({ message: 'The Actor has been initialized in the current directory.' });
}
}