diff --git a/app/Coding/Iteration.php b/app/Coding/Iteration.php index a51ca34..e315698 100644 --- a/app/Coding/Iteration.php +++ b/app/Coding/Iteration.php @@ -2,6 +2,8 @@ namespace App\Coding; +use Carbon\Carbon; + class Iteration extends Base { public function create($token, $projectName, $data) @@ -20,4 +22,10 @@ public function create($token, $projectName, $data) $result = json_decode($response->getBody(), true); return $result['Response']['Iteration']; } + + public static function generateName(Carbon $startAt, Carbon $endAt): string + { + $endFormat = $startAt->year == $endAt->year ? 'm/d' : 'Y/m/d'; + return $startAt->format('Y/m/d') . '-' . $endAt->format($endFormat) . ' 迭代'; + } } diff --git a/app/Commands/IterationCreateCommand.php b/app/Commands/IterationCreateCommand.php new file mode 100644 index 0000000..80d79ed --- /dev/null +++ b/app/Commands/IterationCreateCommand.php @@ -0,0 +1,64 @@ +setCodingApi(); + + $data = []; + $startAt = Carbon::parse($this->option('start_at') ?? $this->ask('开始时间:', Carbon::today()->toDateString())); + $data['StartAt'] = $startAt->toDateString(); + $endAt = Carbon::parse($this->option('end_at') ?? $this->ask( + '结束时间:', + Carbon::today()->addDays(14)->toDateString() + )); + $data['EndAt'] = $endAt->toDateString(); + $data['Name'] = $this->option('name') ?? $this->ask('标题:', Iteration::generateName($startAt, $endAt)); + $data['Goal'] = $this->option('goal'); + $data['Assignee'] = $this->option('assignee'); + + $result = $iteration->create($this->codingToken, $this->codingProjectUri, $data); + + $this->info('创建成功'); + $this->info("https://{$this->codingTeamDomain}.coding.net/p/{$this->codingProjectUri}" . + "/iterations/${result['Code']}/issues"); + + return 0; + } +} diff --git a/composer.json b/composer.json index 02ffd15..e886ce7 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ "laravel-fans/confluence": "^0.1.1", "laravel-zero/framework": "^8.8", "league/html-to-markdown": "^5.0", + "nesbot/carbon": "^2.53", "sinkcup/laravel-filesystem-cos-updated": "^4.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 48a5dda..383dc9c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b78aa1fa10887f82b88b1e7290803200", + "content-hash": "dd8f6ba7fb2903f0485d7037e87d122a", "packages": [ { "name": "brick/math", @@ -2185,27 +2185,28 @@ }, { "name": "nesbot/carbon", - "version": "2.50.0", + "version": "2.53.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "f47f17d17602b2243414a44ad53d9f8b9ada5fdb" + "reference": "f4655858a784988f880c1b8c7feabbf02dfdf045" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f47f17d17602b2243414a44ad53d9f8b9ada5fdb", - "reference": "f47f17d17602b2243414a44ad53d9f8b9ada5fdb", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f4655858a784988f880c1b8c7feabbf02dfdf045", + "reference": "f4655858a784988f880c1b8c7feabbf02dfdf045", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.1.8 || ^8.0", "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", "symfony/translation": "^3.4 || ^4.0 || ^5.0" }, "require-dev": { "doctrine/orm": "^2.7", - "friendsofphp/php-cs-fixer": "^2.14 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.0", "kylekatarnls/multi-tester": "^2.0", "phpmd/phpmd": "^2.9", "phpstan/extension-installer": "^1.0", @@ -2219,8 +2220,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev", - "dev-3.x": "3.x-dev" + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" }, "laravel": { "providers": [ @@ -2274,7 +2275,7 @@ "type": "tidelift" } ], - "time": "2021-06-28T22:38:45+00:00" + "time": "2021-09-06T09:29:23+00:00" }, { "name": "nunomaduro/collision", diff --git a/tests/Feature/IterationCreateCommandTest.php b/tests/Feature/IterationCreateCommandTest.php new file mode 100755 index 0000000..b7746e6 --- /dev/null +++ b/tests/Feature/IterationCreateCommandTest.php @@ -0,0 +1,48 @@ +faker->md5; + config(['coding.token' => $codingToken]); + $this->teamDomain = $this->faker->domainWord; + config(['coding.team_domain' => $this->teamDomain]); + $this->projectUri = $this->faker->slug; + config(['coding.project_uri' => $this->projectUri]); + } + + public function testCreateSuccess() + { + $mock = \Mockery::mock(Iteration::class, [])->makePartial(); + $this->instance(Iteration::class, $mock); + + $mock->shouldReceive('create')->times(1)->andReturn(json_decode( + file_get_contents($this->dataDir . 'coding/' . 'CreateIterationResponse.json'), + true + )['Response']['Iteration']); + + $startAt = $this->faker->date(); + $endAt = Carbon::parse($startAt)->addDays($this->faker->randomNumber())->toDateString(); + $this->artisan('iteration:create', [ + '--goal' => $this->faker->text(), + '--assignee' => $this->faker->randomNumber(), + ]) + ->expectsQuestion('开始时间:', $startAt) + ->expectsQuestion('结束时间:', $endAt) + ->expectsQuestion('标题:', $startAt . '~' . $endAt . ' 迭代') + ->expectsOutput('创建成功') + ->expectsOutput("https://$this->teamDomain.coding.net/p/$this->projectUri/iterations/2746/issues") + ->assertExitCode(0); + } +} diff --git a/tests/Unit/CodingIterationTest.php b/tests/Unit/CodingIterationTest.php index fd0786a..b0cdb5b 100644 --- a/tests/Unit/CodingIterationTest.php +++ b/tests/Unit/CodingIterationTest.php @@ -4,6 +4,7 @@ use App\Coding\Issue; use App\Coding\Iteration; +use Carbon\Carbon; use GuzzleHttp\Client; use GuzzleHttp\Psr7\Response; use Tests\TestCase; @@ -42,4 +43,17 @@ public function testCreateSuccess() $result = $coding->create($codingToken, $codingProjectUri, $data); $this->assertEquals(json_decode($responseBody, true)['Response']['Iteration'], $result); } + + public function testGenerateName() + { + $startAt = Carbon::parse('2021-10-20'); + $endAt = Carbon::parse('2021-10-30'); + $result = Iteration::generateName($startAt, $endAt); + $this->assertEquals("2021/10/20-10/30 迭代", $result); + + $startAt = Carbon::parse('2021-12-27'); + $endAt = Carbon::parse('2022-01-07'); + $result = Iteration::generateName($startAt, $endAt); + $this->assertEquals("2021/12/27-2022/01/07 迭代", $result); + } }