Skip to content

Commit 9112d35

Browse files
committed
feat: Add init
1 parent 8e40bc2 commit 9112d35

20 files changed

+8539
-0
lines changed

.editorconfig

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
trim_trailing_whitespace = false
13+
14+
[*.yml]
15+
indent_size = 2

.gitattributes

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
* text=auto eol=lf
2+
/.github export-ignore
3+
.scrutinizer.yml export-ignore
4+
BACKERS.md export-ignore
5+
CONTRIBUTING.md export-ignore
6+
CHANGELOG.md export-ignore

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/vendor
2+
/.idea
3+
.php-cs-fixer.cache

.php-cs-fixer.php

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
/*
4+
* This file is part of james.xue/sms-bombing.
5+
*
6+
* (c) xiaoxuan6 <[email protected]>
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*
11+
*/
12+
13+
$header = <<<HEADER
14+
This file is part of james.xue/sms-bombing.
15+
16+
(c) xiaoxuan6 <[email protected]>
17+
18+
This source file is subject to the MIT license that is bundled
19+
with this source code in the file LICENSE.
20+
21+
HEADER;
22+
23+
$finder = PhpCsFixer\Finder::create()
24+
->in([
25+
__DIR__ . '/app',
26+
__DIR__ . '/bootstrap',
27+
__DIR__ . '/config',
28+
])
29+
->exclude([
30+
__DIR__ . '/vendor',
31+
])
32+
->name('*.php')
33+
->name('code-explain')
34+
->ignoreDotFiles(true)
35+
->ignoreVCS(true);
36+
37+
return (new PhpCsFixer\Config())
38+
->setRules([
39+
'@PSR12' => true,
40+
'header_comment' => ['header' => $header],
41+
'array_syntax' => ['syntax' => 'short'],
42+
'no_useless_else' => true,
43+
'not_operator_with_successor_space' => true,
44+
'phpdoc_scalar' => true,
45+
'unary_operator_spaces' => true,
46+
'binary_operator_spaces' => true,
47+
'blank_line_before_statement' => [
48+
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
49+
],
50+
'phpdoc_single_line_var_spacing' => true,
51+
'phpdoc_var_without_name' => true,
52+
'class_attributes_separation' => [
53+
'elements' => [
54+
'method' => 'one',
55+
],
56+
],
57+
'method_argument_space' => [
58+
'on_multiline' => 'ensure_fully_multiline',
59+
'keep_multiple_spaces_after_comma' => true,
60+
],
61+
'single_trait_insert_per_statement' => true,
62+
'trim_array_spaces' => true,
63+
'combine_consecutive_unsets' => true,
64+
'concat_space' => ['spacing' => 'one'],
65+
'new_with_braces' => true,
66+
'no_space_around_double_colon' => true,
67+
'object_operator_without_whitespace' => true,
68+
'ternary_operator_spaces' => true,
69+
'ternary_to_null_coalescing' => true,
70+
'align_multiline_comment' => true,
71+
'no_blank_lines_after_phpdoc' => true,
72+
'no_useless_return' => true,
73+
'return_assignment' => true,
74+
'blank_line_after_namespace' => true,
75+
'no_leading_namespace_whitespace' => true,
76+
// 'single_blank_line_before_namespace' => true,
77+
'fully_qualified_strict_types' => true,
78+
'global_namespace_import' => [
79+
'import_classes' => true,
80+
'import_constants' => true,
81+
'import_functions' => true
82+
],
83+
'group_import' => true,
84+
'single_import_per_statement' => false,
85+
'no_unused_imports' => true,
86+
'ordered_imports' => [
87+
'sort_algorithm' => 'length',
88+
'imports_order' => ['const', 'class', 'function']
89+
],
90+
'single_line_after_imports' => true,
91+
'blank_line_after_opening_tag' => true,
92+
'compact_nullable_typehint' => true,
93+
'declare_equal_normalize' => true,
94+
'lowercase_cast' => true,
95+
'lowercase_static_reference' => true,
96+
'no_blank_lines_after_class_opening' => true,
97+
'no_leading_import_slash' => true,
98+
'no_whitespace_in_blank_line' => true,
99+
'ordered_class_elements' => [
100+
'order' => [
101+
'use_trait',
102+
],
103+
],
104+
'return_type_declaration' => true,
105+
'short_scalar_cast' => true,
106+
'visibility_required' => [
107+
'elements' => [
108+
'const',
109+
'method',
110+
'property',
111+
],
112+
],
113+
])
114+
->setFinder($finder);

README.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# code explain
2+
3+
What does it mean to explain the code(解释代码是什么意思)
4+
5+
![code-explain](./docs/code-explain.gif)
6+
7+
# Requirements
8+
9+
* PHP >= 8.1
10+
11+
# Installation
12+
13+
## Composer
14+
15+
```bash
16+
composer global require james.xue/code-explain
17+
```
18+
19+
## 直接下载 [code-explain](./builds/code-explain) 可执行文件
20+
21+
```shell
22+
curl 'https://mirror.ghproxy.com/https://raw.githubusercontent.com/xiaoxuan6/code-explain/main/builds/code-explain' -o code-explain --progress-bar
23+
chmod +x code-explain
24+
```
25+
26+
## Help
27+
28+
```bash
29+
$ ./code-explain -h
30+
Description:
31+
What does it mean to explain the code.
32+
33+
Usage:
34+
explain [options] [--] [<code>]
35+
36+
Arguments:
37+
code The code to explain
38+
39+
Options:
40+
-C, --is-use-clipboard Use clipboard to get the code to explain
41+
-h, --help Display help for the given command. When no command is given display help for the explain command
42+
-q, --quiet Do not output any message
43+
-V, --version Display this application version
44+
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
45+
-n, --no-interaction Do not ask any interactive question
46+
--env[=ENV] The environment the command should run under
47+
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
48+
```

app/Commands/ExplainCommand.php

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
<?php
2+
3+
/*
4+
* This file is part of james.xue/sms-bombing.
5+
*
6+
* (c) xiaoxuan6 <[email protected]>
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*
11+
*/
12+
13+
namespace App\Commands;
14+
15+
use Exception;
16+
use App\Services\DeepLTranslator;
17+
use TitasGailius\Terminal\Terminal;
18+
use Illuminate\Support\Facades\Http;
19+
use LaravelZero\Framework\Commands\Command;
20+
use Illuminate\Http\Client\RequestException;
21+
22+
use function Laravel\Prompts\text;
23+
24+
class ExplainCommand extends Command
25+
{
26+
/**
27+
* The signature of the command.
28+
*
29+
* @var string
30+
*/
31+
protected $signature = 'explain
32+
{code? : The code to explain}
33+
{--C|is-use-clipboard : Use clipboard to get the code to explain}
34+
';
35+
36+
/**
37+
* The description of the command.
38+
*
39+
* @var string
40+
*/
41+
protected $description = 'What does it mean to explain the code.';
42+
43+
/**
44+
* Execute the console command.
45+
* @return int
46+
* @throws RequestException
47+
*/
48+
public function handle(): int
49+
{
50+
return collect()
51+
->tap(
52+
function () use (&$code): void {
53+
$code = str(
54+
value(function () {
55+
if ($this->option('is-use-clipboard')) {
56+
return str(
57+
match (PHP_OS_FAMILY) {
58+
'Windows' => Terminal::builder()->run('powershell -sta "add-type -as System.Windows.Forms; [windows.forms.clipboard]::GetText()"')->output(),
59+
'Linux' => Terminal::builder()->run('xclip -out -selection primary')->output(),
60+
'Darwin' => Terminal::builder()->run('pbpaste')->output(),
61+
default => '',
62+
}
63+
)->trim()->whenEmpty($this->textCallable());
64+
}
65+
66+
return $this->argument('code') ?? $this->textCallable()();
67+
})
68+
)->trim()->toString();
69+
}
70+
)
71+
->tap(function () use ($code, &$result): void {
72+
$this->info('code:');
73+
$this->warn(sprintf("%s" . PHP_EOL, $code));
74+
75+
$this->task(
76+
' 1. code <fg=yellow>explain</>',
77+
function () use ($code, &$result): bool {
78+
$response = Http::timeout(10)
79+
->withoutVerifying()
80+
->withHeader('Content-Type', 'application/json')
81+
->retry(3, 1000, throw: false)
82+
->post('https://whatdoesthiscodedo.com/api/stream-text', [
83+
'code' => str($code)->replace("\r\n", "\n")
84+
])
85+
->throw(fn ($response, $e) => $this->error($e->getMessage()));
86+
87+
if ($response->successful()) {
88+
$body = str($response->body())->trim()->toString();
89+
90+
$arr = preg_split('/\R/', $body);
91+
$result = current($arr);
92+
93+
return true;
94+
}
95+
96+
$this->error(sprintf("explain: \n%s", $response->reason()));
97+
$this->output->newLine();
98+
99+
return false;
100+
}
101+
);
102+
$this->output->newLine();
103+
})
104+
->tap(function () use ($result): void {
105+
if (strlen($result) > 0) {
106+
$response = $this->task(
107+
' 2. code explain <fg=yellow>result translate</>',
108+
function () use ($result, &$message): bool {
109+
try {
110+
$collect = collect(DeepLTranslator::withoutVerifying()->en2zh($result));
111+
112+
if ($collect->get('code') == 1000) {
113+
$message = sprintf("explain: \n%s", $collect->get('data'));
114+
115+
return true;
116+
}
117+
$message = sprintf("explain: \n%s", $collect->get('message'));
118+
119+
return false;
120+
} catch (Exception $exception) {
121+
$message = sprintf("explain: \n%s", $exception->getMessage());
122+
123+
return false;
124+
}
125+
}
126+
);
127+
$this->output->newLine();
128+
$response == true ? $this->info($message) : $this->error($message);
129+
} else {
130+
$this->error('explain: result is empty');
131+
}
132+
})
133+
->pipe(static fn (): int => self::SUCCESS);
134+
}
135+
136+
public function textCallable(): callable
137+
{
138+
return fn (): string => text(
139+
'What does it mean to explain the code?',
140+
placeholder: 'Enter code here',
141+
required: true,
142+
validate: fn ($value): ?string => $value ? null : 'Code is required'
143+
);
144+
}
145+
}

app/Providers/AppServiceProvider.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of james.xue/sms-bombing.
5+
*
6+
* (c) xiaoxuan6 <[email protected]>
7+
*
8+
* This source file is subject to the MIT license that is bundled
9+
* with this source code in the file LICENSE.
10+
*
11+
*/
12+
13+
namespace App\Providers;
14+
15+
use Illuminate\Support\ServiceProvider;
16+
17+
class AppServiceProvider extends ServiceProvider
18+
{
19+
/**
20+
* Bootstrap any application services.
21+
*/
22+
public function boot(): void
23+
{
24+
}
25+
26+
/**
27+
* Register any application services.
28+
*/
29+
public function register(): void
30+
{
31+
//
32+
}
33+
}

0 commit comments

Comments
 (0)