Skip to content

Commit

Permalink
Merge pull request #100 from zeabur/pan93412/zea-1202-add-official-su…
Browse files Browse the repository at this point in the history
…pport-for-acg-faka
  • Loading branch information
yuaanlin committed Jun 24, 2023
2 parents 529734f + a7cc4bd commit 94fc1e1
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 8 deletions.
2 changes: 2 additions & 0 deletions internal/php/identify.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ func (i *identify) PlanMeta(options plan.NewPlannerOptions) types.PlanMeta {
framework := DetermineProjectFramework(options.Source)
phpVersion := GetPHPVersion(options.Source)
deps := DetermineAptDependencies(options.Source)
app := DetermineApplication(options.Source)

return types.PlanMeta{
"framework": string(framework),
"phpVersion": phpVersion,
"deps": strings.Join(deps, " "),
"app": string(app),
}
}

Expand Down
36 changes: 36 additions & 0 deletions internal/php/nginx-conf/acg-faka.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
server {
listen 8080;
root /var/www/public;

add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";

index index.php index.html;
charset utf-8;

location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }

error_page 404 /index.php;

location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_buffering off;
}

location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.php?s=$1 last; break;
}
}

location ~ /\.(?!well-known).* {
deny all;
}
}
File renamed without changes.
48 changes: 48 additions & 0 deletions internal/php/nginx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package php

import (
"embed"
"fmt"
"io"
"strings"

"github.com/zeabur/zbpack/pkg/types"
)

//go:embed nginx-conf
var nginxConfFs embed.FS

// RetrieveNginxConf retrieves the nginx conf for the given app.
//
// The app should be an instance of types.PHPApplication; otherwise,
// an error will be returned.
func RetrieveNginxConf(app string) (string, error) {
appConfMap := map[string]string{
string(types.PHPApplicationDefault): "nginx-conf/default.conf",
string(types.PHPApplicationAcgFaka): "nginx-conf/acg-faka.conf",
}

filename, ok := appConfMap[app]
if !ok {
return "", fmt.Errorf("unknown app: %s", app)
}

f, err := nginxConfFs.Open(filename)
if err != nil {
return "", fmt.Errorf("open: %w", err)
}

nginxConfBytes, err := io.ReadAll(f)
if err != nil {
return "", fmt.Errorf("readall: %w", err)
}
nginxConf := string(nginxConfBytes)

return escape(nginxConf), nil
}

func escape(s string) string {
s = strings.ReplaceAll(s, "\n", "\\n")
s = strings.ReplaceAll(s, "$", "\\$")
return s
}
33 changes: 33 additions & 0 deletions internal/php/nginx_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package php

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/zeabur/zbpack/pkg/types"
)

func TestEscape(t *testing.T) {
assert.Equal(t, escape("a\nb"), "a\\nb")
assert.Equal(t, escape("a$b"), "a\\$b")
}

func TestRetrieveNginxConf_Default(t *testing.T) {
conf, err := RetrieveNginxConf(string(types.PHPApplicationDefault))

assert.NoError(t, err)
assert.Contains(t, conf, escape("try_files $uri $uri/ /index.php?$query_string;"))
}

func TestRetrieveNginxConf_AcgFaka(t *testing.T) {
conf, err := RetrieveNginxConf(string(types.PHPApplicationAcgFaka))

assert.NoError(t, err)
assert.Contains(t, conf, escape("rewrite ^(.*)$ /index.php?s=$1 last; break;"))
}

func TestRetrieveNginxConf_Unknown(t *testing.T) {
_, err := RetrieveNginxConf("unknown")

assert.Error(t, err)
}
13 changes: 5 additions & 8 deletions internal/php/php.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
package php

import (
_ "embed"
"fmt"
"strings"

"github.com/zeabur/zbpack/pkg/packer"
"github.com/zeabur/zbpack/pkg/types"
)

//go:embed nginx.conf
var nginxConf string

// GenerateDockerfile generates the Dockerfile for PHP projects.
func GenerateDockerfile(meta types.PlanMeta) (string, error) {
phpVersion := meta["phpVersion"]
getPhpImage := "FROM docker.io/library/php:" + phpVersion + "-fpm\n"

nginxConf, err := RetrieveNginxConf(meta["app"])
if err != nil {
return "", fmt.Errorf("retrieve nginx conf: %w", err)
}

installCMD := fmt.Sprintf(`
RUN apt-get update
RUN apt-get install -y %s
Expand All @@ -26,9 +26,6 @@ ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/do
RUN chmod +x /usr/local/bin/install-php-extensions && sync
`, meta["deps"])

nginxConf = strings.ReplaceAll(nginxConf, "\n", "\\n")
nginxConf = strings.ReplaceAll(nginxConf, "$", "\\$")

// copy source code to /var/www/public, which is Nginx root directory
copyCommand := `
COPY --chown=www-data:www-data . /var/www/public
Expand Down
15 changes: 15 additions & 0 deletions internal/php/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,18 @@ func DetermineAptDependencies(source afero.Fs) []string {

return dependencies
}

// DetermineApplication determines what application the project is using.
// Therefore, we can apply some custom fixes such as the nginx configuration.
func DetermineApplication(source afero.Fs) types.PHPApplication {
composerJSON, err := parseComposerJSON(source)
if err != nil {
return types.PHPApplicationDefault
}

if composerJSON.Name == "lizhipay/acg-faka" {
return types.PHPApplicationAcgFaka
}

return types.PHPApplicationDefault
}
27 changes: 27 additions & 0 deletions internal/php/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,30 @@ func TestDetermineProjectFramework_Unknown(t *testing.T) {
framework := php.DetermineProjectFramework(fs)
assert.Equal(t, framework, types.PHPFrameworkNone)
}

func TestDetermineApplication_NoComposer(t *testing.T) {
fs := afero.NewMemMapFs()

app := php.DetermineApplication(fs)
assert.Equal(t, app, types.PHPApplicationDefault)
}

func TestDetermineApplication_Unknown(t *testing.T) {
fs := afero.NewMemMapFs()
_ = afero.WriteFile(fs, "composer.json", []byte(`{
"name": "test"
}`), 0o644)

app := php.DetermineApplication(fs)
assert.Equal(t, app, types.PHPApplicationDefault)
}

func TestDetermineApplication_AcgFaka(t *testing.T) {
fs := afero.NewMemMapFs()
_ = afero.WriteFile(fs, "composer.json", []byte(`{
"name": "lizhipay/acg-faka"
}`), 0o644)

app := php.DetermineApplication(fs)
assert.Equal(t, app, types.PHPApplicationAcgFaka)
}
11 changes: 11 additions & 0 deletions pkg/types/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ const (

//revive:enable:exported

// PHPApplication represents the application type of a PHP project.
type PHPApplication string

//revive:disable:exported
const (
PHPApplicationDefault PHPApplication = "default"
PHPApplicationAcgFaka PHPApplication = "acg-faka"
)

//revive:enable:exported

// RubyFramework represents the framework of a Ruby project.
type RubyFramework string

Expand Down

0 comments on commit 94fc1e1

Please sign in to comment.