Skip to content

Commit 28ba48f

Browse files
committed
wip
0 parents  commit 28ba48f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1431
-0
lines changed

.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ENVIRONMENT=production
2+
DISCOVERY_CACHE=false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: tempest/app QA trigger from tempest/framework
2+
3+
on: [push, workflow_dispatch]
4+
5+
jobs:
6+
run-qa:
7+
name: Run QA
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout code
11+
uses: actions/checkout@v4
12+
13+
- name: Setup PHP
14+
uses: shivammathur/setup-php@v2
15+
with:
16+
php-version: ${{ matrix.php }}
17+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
18+
coverage: pcov
19+
20+
- name: Install dependencies
21+
run: |
22+
composer update
23+
npm i
24+
npm run dev
25+
- name: List Installed Dependencies
26+
run: composer show -D
27+
28+
- name: Setup .env
29+
run: cp .env.example .env
30+
31+
- name: Run Tempest console
32+
run: php ./tempest
33+
34+
- name: Run Tempest Server in the background
35+
run: php ./tempest serve &
36+
37+
- name: Try GET request
38+
run: curl http://localhost:8000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: tempest/clean QA trigger from tempest/framework
2+
3+
on: [push, workflow_dispatch]
4+
5+
jobs:
6+
run-qa:
7+
name: Run QA
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Setup PHP
11+
uses: shivammathur/setup-php@v2
12+
with:
13+
php-version: ${{ matrix.php }}
14+
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo
15+
coverage: pcov
16+
17+
- name: Require Tempest
18+
run: composer require tempest/framework:dev-main
19+
20+
- name: List Installed Dependencies
21+
run: composer show -D
22+
23+
- name: Install Tempest
24+
run: php vendor/bin/tempest install --force
25+
26+
- name: Run Tempest console
27+
run: php ./tempest
28+
29+
- name: Run Tempest Server in the background
30+
run: php ./tempest serve &
31+
32+
- name: Try GET request
33+
run: curl http://localhost:8000

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
composer.lock
2+
node_modules/
3+
vendor/
4+
/public/main.css
5+
/package-lock.json
6+
/.php-cs-fixer.cache
7+
.env

.php-cs-fixer.dist.php

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
$finder = Symfony\Component\Finder\Finder::create()
4+
->in([
5+
__DIR__ . '/app',
6+
__DIR__ . '/tests',
7+
])
8+
->name('*.php')
9+
->ignoreDotFiles(true)
10+
->ignoreVCS(true);
11+
12+
return (new PhpCsFixer\Config())
13+
->setRules([
14+
'@PSR12' => true,
15+
'array_syntax' => ['syntax' => 'short'],
16+
'ordered_imports' => ['sort_algorithm' => 'alpha'],
17+
'no_unused_imports' => true,
18+
'not_operator_with_successor_space' => true,
19+
'trailing_comma_in_multiline' => true,
20+
'phpdoc_scalar' => true,
21+
'unary_operator_spaces' => true,
22+
'binary_operator_spaces' => true,
23+
'blank_line_before_statement' => [
24+
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'],
25+
],
26+
'phpdoc_single_line_var_spacing' => true,
27+
'phpdoc_var_without_name' => true,
28+
'class_attributes_separation' => [
29+
'elements' => [
30+
'method' => 'one',
31+
],
32+
],
33+
'method_argument_space' => [
34+
'on_multiline' => 'ensure_fully_multiline',
35+
'keep_multiple_spaces_after_comma' => true,
36+
],
37+
'single_trait_insert_per_statement' => true,
38+
'declare_strict_types' => true,
39+
])
40+
->setFinder($finder);

LICENCE.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2024 Brent Roose [email protected]
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6+
7+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Project scaffold for [Tempest](https://github.com/tempestphp), an MVC micro framework that gets out of your way.
2+
3+
```php
4+
composer create-project tempest/app <project-name>
5+
cd <project-name>
6+
npm run dev
7+
```
8+
9+
Read all about Tempest in [the docs](https://github.com/tempestphp/tempest-docs/blob/master/01-getting-started.md).

app/Chapters/Chapter.php

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace App\Chapters;
4+
5+
use App\Front\DocsController;
6+
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
7+
use League\CommonMark\Output\RenderedContentInterface;
8+
use function Tempest\uri;
9+
10+
final readonly class Chapter
11+
{
12+
public function __construct(
13+
public string $slug,
14+
public string $body,
15+
public string $title,
16+
) {
17+
}
18+
19+
public static function fromMarkdown(string $slug, RenderedContentInterface|RenderedContentWithFrontMatter $markdown): self
20+
{
21+
$frontMatter = $markdown instanceof RenderedContentWithFrontMatter ? $markdown->getFrontMatter() : [
22+
'title' => 'Unknown',
23+
];
24+
25+
return new self(...[
26+
...[
27+
'slug' => $slug,
28+
'body' => $markdown->getContent()
29+
],
30+
...$frontMatter,
31+
]);
32+
}
33+
34+
public function getUri(): string
35+
{
36+
return uri([DocsController::class, 'show'], slug: $this->slug);
37+
}
38+
}

app/Chapters/ChapterRepository.php

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace App\Chapters;
4+
5+
use League\CommonMark\MarkdownConverter;
6+
7+
readonly class ChapterRepository
8+
{
9+
public function __construct(
10+
private MarkdownConverter $markdown,
11+
) {}
12+
13+
public function find(string $slug): Chapter
14+
{
15+
$path = glob(__DIR__ . "/../Content/{$slug}*.md")[0] ?? __DIR__ . "/../Content/{$slug}.md";
16+
17+
$content = file_get_contents($path);
18+
19+
return Chapter::fromMarkdown($slug, $this->markdown->convert($content));
20+
}
21+
22+
/**
23+
* @return \App\Chapters\Chapter[]
24+
*/
25+
public function all(): array
26+
{
27+
return array_map(
28+
function (string $content) {
29+
$slug = pathinfo($content, PATHINFO_FILENAME);
30+
31+
return $this->find($slug);
32+
},
33+
glob(__DIR__ . "/../Content/*.md"),
34+
);
35+
}
36+
}

app/Content/01-getting-started.md

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
title: Getting Started
3+
---
4+
5+
Tempest is a PHP MVC framework that gets out of your way. Its design philosophy is that developers should write as little framework-related code as possible, so that they can focus on application code instead.
6+
7+
## Installation
8+
9+
You can install Tempest in two ways: as a web app with a basic frontend bootstrap, or by requiring the framework as a package in any project you'd like.
10+
11+
### Tempest App
12+
13+
If you want to start a new Tempest project, you can use `tempest/app` as the starting point. Use `composer create-project` to start:
14+
15+
```txt
16+
composer create-project tempest/app my-app
17+
cd my-app
18+
```
19+
20+
This project scaffold includes a basic frontend setup including tailwind:
21+
22+
```txt
23+
npm run dev
24+
```
25+
26+
You can access your app by using PHP's built-in server.
27+
28+
```text
29+
./tempest serve
30+
<hljs comment>PHP 8.3.3 Development Server (http://localhost:8000) started</hljs>
31+
```
32+
33+
### Tempest as a package
34+
35+
If you don't need an app scaffold, you can opt to install `tempest/framework` as a standalone package. You could do this in any project; it could already contain code, or it could be an empty project.
36+
37+
```txt
38+
composer require tempest/framework
39+
```
40+
41+
Installing Tempest this way will give you access to the tempest console as a composer binary:
42+
43+
```txt
44+
./vendor/bin/tempest
45+
```
46+
47+
Optionally, you can choose to install Tempest's entry points in your project:
48+
49+
```txt
50+
./vendor/bin/tempest install
51+
```
52+
53+
Installing Tempest into a project means copying one or more of these files into that project:
54+
55+
- `public/index.php` — the web application entry point
56+
- `tempest` – the console application entry point
57+
- `.env.example` – a clean example of a `.env` file
58+
- `.env` – the real environment file for your local installation
59+
60+
You can choose which files you want to install, and you can always rerun the `install` command at a later point in time.
61+
62+
63+
## A basic Tempest project
64+
65+
Tempest won't impose any fixed file structure on you: one of the core principles of Tempest is that it will scan you project code for you, and it will automatically discover any files it needs to. For example: Tempest is able to differentiate between a controller method and a console command by looking at the code, instead of relying on naming conventions. This is what's called **discovery**, and it's one of Tempest's most powerful features.
66+
67+
You can make a project that looks like this:
68+
69+
```txt
70+
app
71+
├── Console
72+
│   └── RssSyncCommand.php
73+
├── Controllers
74+
│   ├── BlogPostController.php
75+
│   └── HomeController.php
76+
└── Views
77+
├── blog.view.php
78+
└── home.view.php
79+
```
80+
81+
Or a project that looks like this:
82+
83+
```txt
84+
app
85+
├── Blog
86+
│   ├── BlogPostController.php
87+
│   ├── RssSyncCommand.php
88+
│   └── blog.view.php
89+
└── Home
90+
├── HomeController.php
91+
└── home.view.php
92+
```
93+
94+
From Tempest's perspective, it's all the same.
95+
96+
Discovery works by scanning you project code, and looking at each file and method individually to determine what that code does. For production apps, Tempest will cache these results as PHP code, so there's absolutely no performance overhead to doing so.
97+
98+
As an example, Tempest is able to determine which methods are controller methods based on their route attributes:
99+
100+
```php
101+
final <hljs keyword>readonly</hljs> class BlogPostController
102+
{
103+
#[<hljs type>Get</hljs>(<hljs value>'/blog'</hljs>)]
104+
public function index(): <hljs type>View</hljs>
105+
{ /* … */ }
106+
107+
#[<hljs type>Get</hljs>(<hljs value>'/blog/{post}'</hljs>)]
108+
public function show(<hljs type>Post</hljs> $post): <hljs type>Response</hljs>
109+
{ /* … */ }
110+
}
111+
```
112+
113+
And likewise, it's able to detect console commands based on their console command attribute:
114+
115+
```php
116+
final <hljs keyword>readonly</hljs> class RssSyncCommand
117+
{
118+
public function __construct(<hljs keyword>private</hljs> <hljs type>Console</hljs> $console) {}
119+
120+
#[<hljs type>ConsoleCommand</hljs>('<hljs value>rss:sync</hljs>')]
121+
public function __invoke(<hljs type>bool</hljs> $force = <hljs keyword>false</hljs>): <hljs type>void</hljs>
122+
{ /* … */ }
123+
}
124+
```
125+
126+
We'll cover controllers and console commands in depth in future chapters.

0 commit comments

Comments
 (0)