grepsr-cli 0.7.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.1
2
+ Name: grepsr-cli
3
+ Version: 0.7.4
4
+ Summary: A Cli tool for Grepsr Developers
5
+ Home-page: https://bitbucket.org/grepsr/grepsr-cli/
6
+ Author: grepsr
7
+ Author-email: dev@grepsr.com
8
+ License: unlicensed
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE.md
11
+ Requires-Dist: cement (>=3.0.4)
12
+ Requires-Dist: Jinja2 (>=2.11.3)
13
+ Requires-Dist: PyYAML (==5.4.1)
14
+ Requires-Dist: colorlog (>=4.8.0)
15
+ Requires-Dist: semver (>=2.13.0)
16
+ Requires-Dist: terminaltables (>=3.1.0)
17
+ Requires-Dist: requests (>=2.25.1)
18
+ Requires-Dist: boto3 (<2.0.0,>=1.9.0)
19
+
20
+ # A Cli tool for Grepsr Developers
21
+
22
+ ## Installation
23
+ ```
24
+ $ pip install grepsr-cli
25
+ ```
26
+
27
+
28
+ ## Usage
29
+ ### passing parameters to `amazon_com` service.
30
+ ```bash
31
+ gcli crawler test -s amazon_com -p '{"urls":["https://amazon.com/VVUH4HJ","https://amazon.com/FV4434"]}'
32
+ ```
33
+
34
+ ### if JSON is complex, use file instead
35
+ ```
36
+ # contents of /tmp/amazon_params.json
37
+ {"urls": ["https://amazon.com/VV%20UH4HJ"], "strip": ["'", "\"", "\\"]}
38
+
39
+ gcli crawler test -s amazon_com --params-file '/tmp/amazon_params.json'
40
+ ```
41
+
42
+ #### Hacks Used.
43
+ > If the json parameter has a space, it might break parameter parsing.
44
+ > If the json parameter has a dash `-` and any character after it has a space, it will break parameter parsing.
45
+ Cause: no double quoting around $@ in `run_service.php:5:49` [here](https://bitbucket.org/grepsr/vortex-backend/src/09c263fb0bb538003db01e1d6742a43ae6ebc61a/deploy/vortex-backend/scripts/run_service.sh#lines-5)
46
+ > This is fixed hackily by replacing string with its unicode \u0020 sequence. This works beacause $@ does not split on \u0020.
47
+
48
+ ### inject custom command.
49
+ Say, for example you wanted to a inject a php function so that it could be called from inside you service_code when testing locally.
50
+ Note: All these files should only be created inside `~/.grepsr/tmp`. Creating it outside will not work.
51
+
52
+ 1. Create a file called `inject.php` inside `~/.grepsr/tmp/`
53
+ 2. Implement your function inside `~/.grepsr/tmp/inject.php`
54
+ ```php
55
+ function addRowLocal($arr) {
56
+ ...
57
+ ...
58
+ }
59
+ ```
60
+ 3. Create a file called `inject.sh` inside `~/.grepsr/tmp/`
61
+ 4. inside inject.sh add:
62
+ ```
63
+ alias php='php -d auto_prepend_file=/tmp/inject.php'
64
+ ```
65
+ Note: the file location is `/tmp/inject.php` instead of `~/.grepsr/tmp/inject.php`.
66
+ This is because, the local path `~/.grepsr/tmp` gets mapped to `/tmp` in the docker container.
67
+ And `inject.sh` runs inside docker, instead of the local filesystem.
68
+ 5. Add an entry in `~/.grepst/config.yml` like so:
69
+ ```yml
70
+ php:
71
+ ...
72
+ sdk_image: ...
73
+ pre_entry_run_file: inject.sh # relative and limited to the tmp/ dir
74
+ ```
75
+ 6. Now you can use `addRowLocal()` in your any of your files.
76
+ ```php
77
+ public function main($params) {
78
+ ...
79
+ $arr = $this->dataSet->getEmptyRow();
80
+ addRowLocal($arr); // won't throw error
81
+ ...
82
+ }
83
+ ```
84
+ ## Development
85
+ > Be sure to uninstall gcli first, with
86
+ `pip uninstall grepsr-cli`
87
+
88
+ ```bash
89
+ git clone git@bitbucket.org:zznixt07/gcli.git grepsrcli
90
+ cd grepsrcli
91
+ pip install -e .
92
+ ```
@@ -0,0 +1,35 @@
1
+ grepsrcli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ grepsrcli/main.py,sha256=u62FPNQZ7IK-icIirLCiJxH2TJ-eSajYn_iMHGlG_Iw,2169
3
+ grepsrcli/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ grepsrcli/controllers/base.py,sha256=oieX7zkGBAv6YSujy1lUb6dvGLoqtKJaxE50xpcjtX0,1549
5
+ grepsrcli/controllers/crawler.py,sha256=Mh1vHrTYWUcYThM_AyCVW0e5KAWZKrICcO5uEKD6_yg,18101
6
+ grepsrcli/controllers/generate.py,sha256=0QEjaU70HRqko8QKoC3cgu5MFWc4u-_gpR736bzVq5o,1018
7
+ grepsrcli/controllers/report.py,sha256=YDDarWk6OL5lODqAzws0cZMLNDcaocVxVRmd8uPrlkI,2106
8
+ grepsrcli/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ grepsrcli/core/aws_s3.py,sha256=WRpXqB1lwLJ1qxnwBBn9JLpzRlJ2R8P5Oi3SbqOxOBc,1185
10
+ grepsrcli/core/config.py,sha256=R5xNlwLowzH6vwZC4SjmIdwbgZKA7UpJ3Ix4jcpmYUQ,7454
11
+ grepsrcli/core/exc.py,sha256=bkhZoyJa83ppqutrF0faLlEaF8L3MnNAI5eeO9vFyAg,69
12
+ grepsrcli/core/input_prompts.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ grepsrcli/core/message_log.py,sha256=8MbAGfh2WM32jgMADaUbz1i9qSz2TLfjHUT45Zw7VnY,825
14
+ grepsrcli/core/multiproc_server.py,sha256=NfY7SpbNkGkcjlwQNUgoRYRM6pa7Xll36qlgtLOatNY,5244
15
+ grepsrcli/core/report_api.py,sha256=JDNAYfU13ViHviMa3siPKNYSRbaHw5KgG61a2aBl7hc,885
16
+ grepsrcli/core/sdk_setup.py,sha256=F86HC6c3U52vEfZXVveOxmeL0JuUw_o55XD1Wku3bOU,3221
17
+ grepsrcli/core/test_local.py,sha256=lpmU6-GpbLQmb2g9L6Oft6Ee_uzXNjwXsY2vYtkONdU,6178
18
+ grepsrcli/core/utils.py,sha256=cbOr9B4zzGfCGkl2F_idJ7WtC4UqgtCfbZxYVTmaWb4,11117
19
+ grepsrcli/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ grepsrcli/plugins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ grepsrcli/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ grepsrcli/templates/autocomplete.jinja2,sha256=BIoIXodloNikAPAcZkf0Vj2XH2mD6_iB7_6lbqI5DkI,296
23
+ grepsrcli/templates/autocomplete_zsh.jinja2,sha256=oRG_isrx9bL1hwItxcrdnzdYA08cfMU78ZXplHa5N7c,577
24
+ grepsrcli/templates/composer.jinja2,sha256=QMTKcz8ZeTEiaGsm75KtmBDg8RCi3TIEJntQuiPwLPY,488
25
+ grepsrcli/templates/node_boilerplate.jinja2,sha256=ednowfsqn7MkOu-6bWwG9sRdJoBJm89HaSZ5K9hAyK4,3049
26
+ grepsrcli/templates/php_boilerplate.jinja2,sha256=ThMzrkgCTQ918qJyYtuDumy4JiIH3io3Z8OlenEKEtU,1846
27
+ grepsrcli/templates/php_brp_boilerplate.jinja2,sha256=RFTYYmQceI93CbXVSXsje1ZZYmD_ffGAA4-jMhd7CkY,3087
28
+ grepsrcli/templates/php_vc_boilerplate.jinja2,sha256=8_h-BBnV2vI-JR1FGlODEmlKQgM8oNhzTzzlN0sUDg8,1904
29
+ grepsrcli/templates/py_boilerplate.jinja2,sha256=TFsnff_Vuq1iwZFmeJDW0uzsX6dDIxkBzifJOFbizDk,1753
30
+ grepsr_cli-0.7.4.dist-info/LICENSE.md,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
31
+ grepsr_cli-0.7.4.dist-info/METADATA,sha256=HN8Kui_hW1af_vLxyd7WUR9TEEd7SlrrmCXJ4SwfZRk,3006
32
+ grepsr_cli-0.7.4.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
33
+ grepsr_cli-0.7.4.dist-info/entry_points.txt,sha256=u-xyDCaDmX6R3h_bh3gehaQ4qUniDW29gOSerW4QjGw,45
34
+ grepsr_cli-0.7.4.dist-info/top_level.txt,sha256=jjRVZvVITG5pRVj8L_GTLIiQ_4yIuxk1suTKtTMiwow,10
35
+ grepsr_cli-0.7.4.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.40.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ gcli = grepsrcli.main:main
@@ -0,0 +1 @@
1
+ grepsrcli
grepsrcli/__init__.py ADDED
File without changes
File without changes
@@ -0,0 +1,55 @@
1
+ from os import system
2
+ from grepsrcli.core.message_log import Log
3
+ from cement import Controller, ex
4
+ import pkg_resources
5
+ from grepsrcli.core.sdk_setup import SDKSetup
6
+ from grepsrcli.core.config import save_config
7
+
8
+
9
+ version = pkg_resources.require("grepsr-cli")[0].version
10
+
11
+ VERSION_BANNER = """
12
+ gcli: cli tool for grepsr developers verion: %s
13
+ """ % (version)
14
+
15
+
16
+ class Base(Controller):
17
+
18
+ class Meta:
19
+ label = 'base'
20
+
21
+ arguments = [
22
+ (['-v', '--version'],
23
+ {'action': 'version',
24
+ 'version': VERSION_BANNER}),
25
+ ]
26
+
27
+ def _default(self):
28
+ self.app.args.print_help()
29
+
30
+ @ex(help="setup SDKs for crawling",
31
+ arguments=[
32
+ (['-t', '--type'], {'action': 'store', 'dest': 'type'}),
33
+ (['--dryrun'], {'action': 'store_true', 'dest': 'dryrun'}),
34
+ (['--sdk'], {'action': 'store', 'dest': 'sdk'}),
35
+ ]
36
+ )
37
+ def setup_sdk(self):
38
+
39
+ if self.app.pargs.type is not None:
40
+ SDKSetup(self.app.pargs.type,
41
+ self.app.pargs.dryrun, self.app.pargs.sdk)
42
+ else:
43
+ Log.error(
44
+ "Please select the platform to setup the sdk.\nExample: gcli setup-sdk -t php|php_next")
45
+
46
+ @ex(help="Update configuration for gcli",
47
+ arguments=[
48
+ (['--update'], {'action': 'store_true', 'dest': 'update'}),
49
+ ]
50
+ )
51
+ def configure(self):
52
+ if(self.app.pargs.update == True):
53
+ save_config(update=True)
54
+ else:
55
+ save_config(update=False)
@@ -0,0 +1,480 @@
1
+ from os import system, path
2
+ import os
3
+ import sys
4
+ import subprocess
5
+ import multiprocessing
6
+ import signal
7
+ import json
8
+ import pathlib
9
+ from semver import VersionInfo
10
+ from cement import Controller, ex
11
+ from ..core.config import load_config
12
+ from ..core.utils import (
13
+ create_boilerplate,
14
+ render_boilerplate,
15
+ get_plugin_info,
16
+ get_plugin_path,
17
+ show_schema,
18
+ user_input,
19
+ insert_all_chained_dependencies
20
+ )
21
+ from ..core.test_local import TestLocal
22
+ from ..core.message_log import Log
23
+ from ..core.aws_s3 import S3
24
+
25
+ class CrawlerBase(Controller):
26
+ class Meta:
27
+ label = 'crawler_base'
28
+
29
+
30
+ class Crawler(Controller):
31
+ config = load_config('config.yml')
32
+
33
+ class Meta:
34
+ label = 'crawler'
35
+ stacked_on = 'crawler_base'
36
+ stacked_type = 'nested'
37
+
38
+ @ex(
39
+ help="test a plugin locally",
40
+ aliases=['tst'],
41
+ arguments=[
42
+ (['-s'], {
43
+ 'action': 'store',
44
+ 'dest': 'plugin_name',
45
+ 'help': "The name of the service/plugin to run locally"
46
+ }),
47
+ (['-p'], {
48
+ 'action': 'store',
49
+ 'dest': 'params',
50
+ 'help': 'Parameters (as JSON) to pass to the arguments of the main function',
51
+ }),
52
+ (['-m'], {
53
+ 'action': 'store',
54
+ 'dest': 'multi_proc_mode',
55
+ 'help': 'Multiprocess mode',
56
+ }),
57
+ (['--params-file'], {
58
+ 'action': 'store',
59
+ 'dest': 'params_file',
60
+ 'help': 'JSON file location containing parameters to pass to the arguments of the main function'
61
+ }),
62
+
63
+ ]
64
+ )
65
+ def test(self):
66
+ plugin_name = self.app.pargs.plugin_name
67
+ main_fn_params = self.app.pargs.params
68
+ main_fn_params_file = self.app.pargs.params_file
69
+ is_multi_proc = self.app.pargs.multi_proc_mode
70
+
71
+ platforms = ['php', 'php_next']
72
+ proc = None
73
+ for platform in platforms:
74
+ if platform in self.config:
75
+ plugin_path = get_plugin_path(plugin_name, type=platform)
76
+ if plugin_path:
77
+ base_path = pathlib.Path(get_plugin_path(plugin_name, type=platform)).parent
78
+ if is_multi_proc == '1':
79
+ from ..core import multiproc_server
80
+ proc = multiprocessing.Process(target=multiproc_server.start, args=[])
81
+ proc.start()
82
+ try:
83
+ TestLocal(type=platform, base_path=base_path, plugin_name=plugin_name, params=main_fn_params, params_file=main_fn_params_file, is_multi_proc=is_multi_proc)
84
+ except json.JSONDecodeError as e:
85
+ self.app.log.error(f"Error decoding params as JSON. {e}")
86
+ self.app.exit_code = 10
87
+ except FileNotFoundError as e:
88
+ self.app.log.error(f"Params file: `{main_fn_params_file}` not found. {e}")
89
+ self.app.exit_code = 20
90
+ break
91
+ else:
92
+ self.app.log.error(f"path: {plugin_name} not found!")
93
+ self.app.exit_code = 127
94
+ if proc:
95
+ print('terminating server proc', flush=True)
96
+
97
+ '''these 2 methods cannot kill the currently running process on linux.
98
+ Although they will raise an Exception on the target server process,
99
+ the child process of that script cannot be terminated from it.
100
+ '''
101
+ # proc.terminate()
102
+ # proc.kill()
103
+
104
+ '''instead killing whole process group works on linux.
105
+ The OS handles this, killing all the processes at once.
106
+ '''
107
+ pgid = os.getpgid(os.getpid())
108
+ if pgid == 1:
109
+ os.kill(os.getpid(), signal.SIGINT)
110
+ else:
111
+ os.killpg(os.getpgid(os.getpid()), signal.SIGINT)
112
+
113
+
114
+ @ex(
115
+ help="performs git pull to update the codebase",
116
+ arguments=[
117
+ (['-t', '--type'], {
118
+ 'action': 'store',
119
+ 'dest': 'type',
120
+ 'help': "Platform type: php|node|python|php_next"
121
+ })
122
+ ]
123
+ )
124
+ def sync(self):
125
+ if(self.app.pargs.type):
126
+ type = self.app.pargs.type
127
+ crawler_paths = self.config[type]['paths']
128
+
129
+ for crawler_path in crawler_paths:
130
+ Log.info(f"Syncing: {crawler_path}")
131
+ system(
132
+ f"""cd {crawler_path} && git pull origin master""")
133
+ else:
134
+ Log.warn("Please enter a valid type")
135
+
136
+ @ex(
137
+ help="create basic boilerplate for plugins ",
138
+ arguments=[
139
+ (['-s'], {
140
+ "action": "store",
141
+ "dest": "plugin_name",
142
+ "help": "the name of the plugin to be created"
143
+ }), (['-pid'], {
144
+ "action": "store",
145
+ "dest": 'pid',
146
+ "help": "the project id of the plugin"
147
+ }), (
148
+ ['-t', '--template'], {
149
+ "action": "store",
150
+ "dest": 'template',
151
+ "help": "choose a template to boilerplate php|node|py|vc defaults to php"
152
+ }
153
+ ), (
154
+ ['--path'], {
155
+ 'action': "store",
156
+ 'dest': 'folder_path',
157
+ 'help': 'the path of the folder where the plugin will reside'
158
+ }
159
+ )
160
+ ]
161
+ )
162
+ def create(self):
163
+
164
+ template = self.app.pargs.template
165
+
166
+ if self.app.pargs.folder_path is not None:
167
+ folder_path = self.app.pargs.folder_path
168
+ folder_path = folder_path.rstrip('/')
169
+ folder_path = path.expanduser(folder_path)
170
+ else:
171
+ folder_path = pathlib.Path().resolve()
172
+ folder_path = str(folder_path)
173
+
174
+ if self.app.pargs.plugin_name is not None:
175
+ plugin_name = self.app.pargs.plugin_name
176
+ else:
177
+ self.app.log.error(
178
+ "cannot create boilerplate file without plugin's name")
179
+ return
180
+
181
+ if self.app.pargs.pid is not None:
182
+ pid = self.app.pargs.pid
183
+ else:
184
+ pid = '***'
185
+
186
+ data = {
187
+ 'plugin_name': plugin_name,
188
+ 'pid': pid
189
+ }
190
+ plugin_path = folder_path + '/' + plugin_name
191
+ if template == 'vc':
192
+ create_boilerplate(
193
+ plugin_path, "php_vc_boilerplate.jinja2", data, 'php')
194
+
195
+ elif template == 'py':
196
+ create_boilerplate(
197
+ plugin_path, "py_boilerplate.jinja2", data, 'py')
198
+
199
+ elif template == 'node':
200
+ create_boilerplate(
201
+ plugin_path, "node_boilerplate.jinja2", data, 'js')
202
+ elif template == 'brp':
203
+ create_boilerplate(
204
+ plugin_path, "php_brp_boilerplate.jinja2", data, 'php')
205
+ else:
206
+ create_boilerplate(
207
+ plugin_path, "php_boilerplate.jinja2", data, 'php')
208
+
209
+ @ex(
210
+ help="deploy a specific plugin to live with versioning",
211
+ arguments=[
212
+ (['-s'], {
213
+ "action": "store",
214
+ "dest": 'plugin_name'
215
+ }), (['-m'], {
216
+ "action": "store",
217
+ "dest": "message"
218
+ }), (['-st', '--stable'], {
219
+ "action": "store_true",
220
+ "dest": "stable_flag"
221
+ }), (['--patch'], {
222
+ "action": "store_true",
223
+ "dest": "patch_flag"
224
+ }), (['--minor'], {
225
+ "action": "store_true",
226
+ "dest": "minor_flag",
227
+ "help": "set major of a version"
228
+ }), (['--major'], {
229
+ "action": "store_true",
230
+ "dest": "major_flag"
231
+ }),
232
+ (['--verbose'], {
233
+ "action": 'store_true',
234
+ "dest": "verbose"
235
+ })
236
+ ]
237
+ )
238
+ def deploy(self):
239
+
240
+ toolbar_width = 50
241
+ verbose_mode = False
242
+
243
+ try:
244
+ if self.config['deploy']['verbose'] == True or self.app.pargs.verbose == True:
245
+ verbose_mode = True
246
+ except:
247
+ if self.app.pargs.verbose == True:
248
+ verbose_mode = True
249
+
250
+ input_plugin_name = self.app.pargs.plugin_name
251
+ deploy_message = self.app.pargs.message
252
+
253
+ if input_plugin_name is None:
254
+ self.app.log.error("cannot deploy without service code")
255
+ return False
256
+ if deploy_message is None:
257
+ self.app.log.error("cannot deploy without deploy message")
258
+ return False
259
+
260
+ if self.app.pargs.stable_flag:
261
+ deploy_type = "DEPLOY-STABLE"
262
+ else:
263
+ deploy_type = "DEPLOY"
264
+
265
+ major_flag = self.app.pargs.major_flag
266
+ minor_flag = self.app.pargs.minor_flag
267
+
268
+ plugin_names = False
269
+ if ',' in input_plugin_name:
270
+ plugin_names = input_plugin_name.split(',')
271
+
272
+ if plugin_names == False:
273
+ plugin_names = []
274
+ plugin_names.append(input_plugin_name)
275
+
276
+ for plugin_name in plugin_names:
277
+ plugin_name = plugin_name.strip()
278
+ plugin_dir_path = get_plugin_path(plugin_name, all_types=True)
279
+
280
+ if not plugin_dir_path:
281
+ self.app.log.error(f'Could not find plugin: {plugin_name}')
282
+ continue
283
+
284
+ plugin_info = get_plugin_info(plugin_dir_path)
285
+ if plugin_info:
286
+ base_class = plugin_info['base_class']
287
+ if base_class != 'Vtx_Service_Plugin':
288
+ if base_class not in plugin_info['dependencies']:
289
+ msg = f'Plugin extends {base_class} but does not declare it as a dependency.'
290
+ self.app.log.warning(msg)
291
+ if user_input(f'[Experimental] Do you want to automatically add dependencies?') == 'Y':
292
+ insert_all_chained_dependencies(plugin_name)
293
+ go_fwd = user_input(f'Do you want to continue?')
294
+ if go_fwd == 'N':
295
+ continue
296
+ # add .version or update .version
297
+ version_path = '{}/.version'.format(plugin_dir_path)
298
+ if path.exists(version_path):
299
+ with open(version_path, 'r') as f:
300
+ version_info = VersionInfo.parse(f.read())
301
+ if(major_flag):
302
+ version_info = version_info.next_version(
303
+ part='major')
304
+ elif(minor_flag):
305
+ version_info = version_info.next_version(
306
+ part='minor')
307
+ else:
308
+ version_info = version_info.bump_patch()
309
+
310
+ version_info = str(version_info)
311
+ with open(version_path, 'w') as w:
312
+ w.write(version_info)
313
+
314
+ self.app.log.info(
315
+ "[{}] [{}] {}".format(deploy_type, version_info, deploy_message))
316
+ else:
317
+ if plugin_info:
318
+ # if its already deployed then the service probabily works fine.
319
+ # if its the first deploy, we annoy the user.
320
+ if not plugin_info.get('pid_forced'):
321
+ # TODO: maybe read all files and check if any service already has pid in which case force ought to be required.
322
+ self.app.log.warning("PID was not forced. This may cause issues.")
323
+
324
+ with open(version_path, 'w') as f:
325
+ if major_flag:
326
+ version_info = "1.0.0"
327
+ elif minor_flag:
328
+ version_info = "0.1.0"
329
+ else:
330
+ version_info = "0.0.1"
331
+
332
+ f.write(version_info)
333
+
334
+ self.app.log.info(
335
+ "[{}] [{}] {}".format(deploy_type, version_info, deploy_message))
336
+
337
+ if verbose_mode is False:
338
+ sys.stdout.write(
339
+ "Deploying: [%s]" % (" " * toolbar_width))
340
+ sys.stdout.write("\b" * (toolbar_width + 1))
341
+ sys.stdout.flush()
342
+ try:
343
+ quiet_mode = "" if verbose_mode else "--quiet"
344
+ cd_to_repo_cmd = f"cd {plugin_dir_path} && cd .."
345
+ # dont pop stash. cuz if there is a merge conflict, good luck with that.
346
+ # instead apply stash and if and only if everything has passed, then drop the stash.
347
+ # TODO: only apply stash if git stash stashed > 0 files.
348
+ cmds = [
349
+ cd_to_repo_cmd,
350
+ f'git stash --include-untracked {quiet_mode}',
351
+ f'git pull origin master {quiet_mode}',
352
+ f'git stash apply {quiet_mode}',
353
+ f'git add {plugin_name}/',
354
+ f'git commit -m "[{deploy_type}] [{version_info}] {deploy_message}" {quiet_mode}',
355
+ f'git push origin master {quiet_mode}',
356
+ ]
357
+ post_deploy_cmds = [
358
+ cd_to_repo_cmd,
359
+ f'git stash drop {quiet_mode}'
360
+ ]
361
+ try:
362
+ multiplier = toolbar_width // len(cmds)
363
+ except ZeroDivisionError:
364
+ multiplier = 0
365
+ if verbose_mode:
366
+ multiplier = 0
367
+ # just echo some dashes after each command for progress. lol.
368
+ echoer = 'echo -n ' + '-' * multiplier
369
+ # .join() only does n-1 additions. Hence add a echoer at last. And then echo remaining to fill the bar (caused by floor division)
370
+ cmd = f' && {echoer} &&'.join(cmds) + f' && {echoer}' + f' && echo -n {"-" * (toolbar_width - (len(cmds) * multiplier))}'
371
+ try:
372
+ proc = subprocess.run(cmd, shell=True, check=True, timeout=300)
373
+ if proc.returncode == 0:
374
+ proc = subprocess.run(' && '.join(post_deploy_cmds), shell=True)
375
+ if proc.returncode != 0:
376
+ self.app.log.warning('Failed to drop the latest stash.')
377
+
378
+ except subprocess.TimeoutExpired:
379
+ self.app.log.error(f'Timeout occured when deploying {plugin_name}')
380
+
381
+ except subprocess.CalledProcessError as e:
382
+ self.app.log.error(f'There was a problem deploying {plugin_name}')
383
+
384
+ return
385
+
386
+ if verbose_mode is False:
387
+ sys.stdout.flush()
388
+ sys.stdout.write("\n")
389
+
390
+ show_schema(plugin_dir_path)
391
+
392
+ try:
393
+ app_url = f'https://platform.grepsr.com/projects/{plugin_info["pid"]}'
394
+ self.app.log.info(f"App Url: {app_url}")
395
+ except KeyError:
396
+ self.app.log.warning(f"Cannot find pid in plugin, please find the project's url manually")
397
+
398
+ self.app.log.info(
399
+ f"Plugin: {plugin_name} deployed successfully")
400
+
401
+ @ex(
402
+ help="use a base plugin from: https://bitbucket.org/grepsr/vortex-plugins-services-base",
403
+ arguments=[
404
+ (['-s'], {
405
+ "help": "name of the base crawler you want to use",
406
+ "action": "store",
407
+ "dest": "base_plugin_name"
408
+ }),
409
+ (['-t'], {
410
+ "help": "name of target crawler that you want to use",
411
+ "action": "store",
412
+ "dest": "plugin_name"
413
+ })
414
+ ]
415
+ )
416
+ def use_basecrawler(self):
417
+
418
+ s3 = S3(aws_id=self.config['aws_access_key_id'],
419
+ aws_sec_key=self.config['aws_secret_access_key'])
420
+
421
+ version = None
422
+ base_plugin_name = self.app.pargs.base_plugin_name
423
+ target_plugin_name = self.app.pargs.plugin_name
424
+
425
+ if(base_plugin_name is None or target_plugin_name is None):
426
+ Log.error(
427
+ "Please Enter base crawler and target cralwers.\nUse gcli crawler use-basecrawler -h for more information")
428
+ return
429
+
430
+ if('-' in base_plugin_name):
431
+ version = base_plugin_name.split('-')[1]
432
+ base_plugin_name = base_plugin_name.split('-')[0]
433
+
434
+ # to check if there is a base-plugin in thier gcli settings ...
435
+ base_plugin_dir_path = get_plugin_path(
436
+ base_plugin_name, type='php')
437
+
438
+ target_plugin_path = get_plugin_path(
439
+ target_plugin_name, type='php'
440
+ )
441
+
442
+ if(version is None and base_plugin_dir_path):
443
+ f = open(f"{base_plugin_dir_path}/.version", mode='r')
444
+ version = f.read()
445
+ f.close()
446
+
447
+ if(version is None):
448
+ Log.error(
449
+ "Please Specify the version of base crawler that you want to use")
450
+ return
451
+
452
+ if(target_plugin_path):
453
+ Log.info(
454
+ f'Getting Secure Url of target plugin: {base_plugin_name}, {version}')
455
+
456
+ presigned_url = s3.get_secure_url(bucket='crawler-plugins',
457
+ filename=f'php/vortex-plugins-services-base/{base_plugin_name}/{base_plugin_name}-{version}.tar.gz')
458
+
459
+ data = {
460
+ 'presigned_url': presigned_url,
461
+ 'plugin_name': base_plugin_name,
462
+ 'version': version
463
+ }
464
+
465
+ render_boilerplate(boilerplate='composer.jinja2', data=data,
466
+ destination_path=target_plugin_path + '/composer.json')
467
+ system(
468
+ f""" cd {target_plugin_path} && composer install""")
469
+ else:
470
+ Log.error(f"Target plugin: {target_plugin_name} not found")
471
+
472
+
473
+ @ex(
474
+ help="start multiprocess facilitation server",
475
+ arguments=[]
476
+ )
477
+ def multiprocess(self):
478
+ from ..core import multiproc_server
479
+ multiproc_server.start()
480
+