Skip to content

Commit b6773e2

Browse files
committed
🎉 First version for PHP Representer
- Adapt CI - Adapt Dockerfile - Setup symfony consle application - Setup PHPUnit tests (100% coverage) - Implement various normalization: - spacing - class name - array syntax - Logging
1 parent e931eed commit b6773e2

File tree

82 files changed

+4252
-159
lines changed

Some content is hidden

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

82 files changed

+4252
-159
lines changed

.dockerignore

+2
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
bin/run-in-docker.sh
44
bin/run-tests-in-docker.sh
55
tests/
6+
vendor/
7+
phpunit-tests/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: continuous integration
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
continuous-integration:
7+
runs-on: ubuntu-20.04
8+
steps:
9+
- uses: actions/checkout@v3
10+
11+
- name: Setup PHP
12+
uses: shivammathur/setup-php@v2
13+
with:
14+
php-version: '8.1'
15+
tools: composer
16+
coverage: pcov
17+
18+
- name: Get Composer Cache Directory
19+
id: composer-cache
20+
run: |
21+
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
22+
- uses: actions/cache@v3
23+
with:
24+
path: ${{ steps.composer-cache.outputs.dir }}
25+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
26+
restore-keys: |
27+
${{ runner.os }}-composer-
28+
29+
- run: composer install
30+
- run: composer lint
31+
- run: composer phpstan
32+
- run: composer test

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
1+
.idea/
2+
build/
3+
vendor/
4+
.phpcs-cache
5+
.phpunit.result.cache
6+
tests/*/representation.json
17
tests/*/representation.txt
28
tests/*/mapping.json

Dockerfile

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
FROM alpine:3.10
2-
3-
# TODO: install packages required to run the representer
4-
RUN apk add --no-cache bash jq
1+
FROM composer:latest AS builder
52

63
WORKDIR /opt/representer
7-
COPY . .
4+
COPY . /opt/representer
5+
6+
RUN /usr/bin/composer install --no-dev --no-interaction --no-progress --no-scripts --optimize-autoloader --working-dir=/opt/representer
7+
8+
FROM php:8.1-cli-alpine
9+
10+
COPY --from=builder /opt/representer /opt/representer
11+
812
ENTRYPOINT ["/opt/representer/bin/run.sh"]

README.md

+2-34
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,6 @@
1-
# Exercism Representer Template
1+
# Exercism PHP Representer
22

3-
This repository is a [template repository](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository) for creating [representers][representers] for [Exercism][exercism] tracks.
4-
5-
## Using the Representer Template
6-
7-
1. Ensure that your track has not already implemented a representer. If there is, there will be a `https://github.com/exercism/<track>-representer` repository (i.e. if your track's slug is `python`, the representer repo would be `https://github.com/exercism/python-representer`)
8-
2. Follow [GitHub's documentation](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template) for creating a repository from a template repository
9-
- Name your new repository based on your language track's slug (i.e. if your track is for Python, your representer repo name is `python-representer`)
10-
3. Remove this [Exercism Representer Template](#exercism-representer-template) section from the `README.md` file
11-
4. Replace `TRACK_NAME_HERE` with your track's name in the `README.md` file
12-
5. Build the representer, conforming to the [Representer interface specification](https://github.com/exercism/docs/blob/main/building/tooling/representers/interface.md).
13-
- Update the files to match your track's needs. At the very least, you'll need to update `bin/run.sh`, `Dockerfile` and the test solutions in the `tests` directory
14-
- Tip: look for `TODO:` comments to point you towards code that need updating
15-
- Tip: look for `OPTIONAL:` comments to point you towards code that _could_ be useful
16-
17-
Once you're happy with your representer, [open an issue on the exercism/exercism repo](https://github.com/exercism/exercism/issues/new?title=%5BTRACK%5D+Request+Representer+Repository) to request an official representer repository for your track.
18-
19-
## Default Implementation
20-
21-
The default implementation works as follows:
22-
23-
- The `representation.txt` contains the concatenated solution files
24-
- Solution files are separated by an empty line
25-
- Solution files are identified via the the `.files.solution[]` property in the `.meta/config.json` file
26-
- The `mapping.json` contains an empty JSON object (`{}`)
27-
28-
### Normalizations
29-
30-
- Blank files in the solution files are removed in the `representation.txt`
31-
- Line-based trailing whitespace in the solution files is removed in the `representation.txt`
32-
33-
# Exercism TRACK_NAME_HERE Representer
34-
35-
The Docker image to automatically create a representation for TRACK_NAME_HERE solutions submitted to [Exercism].
3+
The Docker image to automatically create a representation for PHP solutions submitted to [Exercism].
364

375
## Run the representer
386

bin/run-tests.sh

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ for test_dir in tests/*; do
2525
expect_error="${test_dir_path}/.expect-error"
2626

2727
bin/run.sh "${test_dir_name}" "${test_dir_path}" "${test_dir_path}"
28-
exit_code=$?
28+
test_exit_code=$?
2929

3030
if [[ -f "${expect_error}" ]]; then
31-
if [[ $exit_code -eq 0 ]]; then
31+
if [[ $test_exit_code -eq 0 ]]; then
3232
echo 'Expected non-zero exit code'
3333
exit_code=1
3434
fi

bin/run.sh

+2-42
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env bash
1+
#!/usr/bin/env sh
22

33
# Synopsis:
44
# Run the representer on a solution.
@@ -33,44 +33,4 @@ mkdir -p "${output_dir}"
3333

3434
echo "${slug}: creating representation..."
3535

36-
# TODO: build a representer to generate the representation and mapping files
37-
38-
# As we don't yet analyze the solution files, we'll just concatenate them with
39-
# leading and trailing empty lines removed
40-
41-
# Start with an empty representation file
42-
echo -n '' > "${representation_file}"
43-
44-
solution_files=$(jq -r '.files.solution[]' "${meta_config_json_file}")
45-
i=0
46-
47-
while read -r relative_solution_file; do
48-
solution_file="${input_dir}/${relative_solution_file}"
49-
50-
## Error when the solution file doesn't exist
51-
if [[ ! -f "${solution_file}" ]]; then
52-
>&2 echo "Could not find solution file '${relative_solution_file}'"
53-
exit 1
54-
fi
55-
56-
# Add an empty line to separate multiple files
57-
if [[ $i > 0 ]]; then
58-
echo '' >> "${representation_file}"
59-
fi
60-
61-
# Append the contents of the solution file to the representation file
62-
# with any blank lines removed
63-
sed -E -e 's/\s*$//' -e '/^$/d' "${solution_file}" >> "${representation_file}"
64-
65-
i=$((i+1))
66-
done <<< "${solution_files}"
67-
68-
# Exit if there an error occured while processing the solution files
69-
if [ $? -ne 0 ]; then
70-
exit $?
71-
fi
72-
73-
# As we don't yet map any identifiers, we'll just output an empty JSON array
74-
echo '{}' > ${mapping_file}
75-
76-
echo "${slug}: done"
36+
/usr/local/bin/php /opt/representer/main.php "$@"

composer.json

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "exercism/php-representer",
3+
"description": "A normalizing representer for Exercism's PHP track.",
4+
"version": "0.1.0",
5+
"type": "project",
6+
"license": "MIT",
7+
"require": {
8+
"php": "^8.1",
9+
"symfony/console": "^6.2",
10+
"nikic/php-parser": "^4.15",
11+
"psr/log": "^3.0"
12+
},
13+
"require-dev": {
14+
"phpstan/phpstan": "^1.9",
15+
"phpunit/phpunit": "^9.5",
16+
"squizlabs/php_codesniffer": "^3.7",
17+
"doctrine/coding-standard": "^11.1"
18+
},
19+
"autoload": {
20+
"psr-4": {
21+
"App\\": "src"
22+
}
23+
},
24+
"autoload-dev": {
25+
"psr-4": {
26+
"App\\Tests\\": "phpunit-tests"
27+
}
28+
},
29+
"scripts": {
30+
"phpstan": "phpstan analyse src tests --configuration phpstan.neon --memory-limit=2G",
31+
"test": "phpunit",
32+
"lint": "phpcs",
33+
"lint:fix": "phpcbf"
34+
},
35+
"config": {
36+
"allow-plugins": {
37+
"dealerdirect/phpcodesniffer-composer-installer": true
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)