Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion defaults/options.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"STACK":"trusty","LIBDIR":"lib","WEBDIR":"htdocs","WEB_SERVER":"httpd","PHP_VM":"php","ADMIN_EMAIL":"admin@localhost","HTTPD_STRIP":false,"HTTPD_MODULES_STRIP":true,"NGINX_STRIP":false,"PHP_STRIP":false,"PHP_MODULES_STRIP":true,"PHP_MODULES":[],"PHP_EXTENSIONS":["bz2","zlib","curl"],"ZEND_EXTENSIONS":[],"PHP_DEFAULT":"8.1.32","PHP_81_LATEST":"8.1.32","PHP_82_LATEST":"8.2.28","PHP_83_LATEST":"8.3.19"}
{"STACK":"trusty","LIBDIR":"lib","WEBDIR":"htdocs","WEB_SERVER":"httpd","PHP_VM":"php","ADMIN_EMAIL":"admin@localhost","HTTPD_STRIP":false,"HTTPD_MODULES_STRIP":true,"NGINX_STRIP":false,"PHP_STRIP":false,"PHP_MODULES_STRIP":true,"PHP_MODULES":[],"PHP_EXTENSIONS":["bz2","zlib","curl"],"ZEND_EXTENSIONS":[]}
37 changes: 34 additions & 3 deletions lib/build_pack_utils/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import shutil
import re
import logging

from collections import defaultdict
from io import StringIO
from subprocess import Popen
Expand Down Expand Up @@ -45,15 +46,45 @@ def __init__(self, builder):
self.builder = builder

def default_config(self):
self._merge(
CloudFoundryUtil.load_json_config_file_from(
opts = CloudFoundryUtil.load_json_config_file_from(
self.builder._ctx['BP_DIR'],
'defaults/options.json'))
'defaults/options.json')
# imported here instead of at the top of the file to prevent ImportError,
# because build_pack_utils is also loaded at launch-time when the
# vendored lib yaml is unavailable.
import yaml
with open(os.path.join(self.builder._ctx['BP_DIR'], 'manifest.yml'), 'r') as f:
manifest = yaml.safe_load(f)

default_versions = manifest.get('default_versions', [])
php_default = next(
(d['version'] for d in default_versions if d.get('name') == 'php'),
None
)

if not php_default:
raise Exception('ERROR: Buildpack could not read default PHP version.')
opts['PHP_DEFAULT'] = php_default

deps = manifest.get('dependencies', [])
php_versions = [d['version'] for d in deps if d.get('name') == 'php']
lines = defaultdict(list)
for v in php_versions:
maj, mino, _ = v.split('.', 2)
# Construct keys. e.g. "PHP_83_LATEST" corresponding to PHP 8.3.X
lines[f'PHP_{maj}{mino}_LATEST'].append(v)
for key, vs in lines.items():
# sort and find the highest patch version for each key
vs.sort(key=lambda s: tuple(map(int, s.split('.'))))
opts[key] = vs[-1]

self._merge(opts)
return self

def stack_config(self):
stack = os.environ.get('CF_STACK', None)
if stack:
# we haven't used this config since cflinuxfs2
self._merge(
CloudFoundryUtil.load_json_config_file_from(
self.builder._ctx['BP_DIR'],
Expand Down
47 changes: 0 additions & 47 deletions src/php/unit/available_versions_test.go

This file was deleted.

60 changes: 60 additions & 0 deletions tests/test_builder_default_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import unittest
import tempfile
import shutil
import os
import json
from build_pack_utils import utils
from unittest.mock import MagicMock
from lib.build_pack_utils import builder
from nose.tools import eq_, assert_not_in


class TestBuilderDefaultConfig(unittest.TestCase):
def setUp(self):
self.bp_dir = tempfile.mkdtemp()
self.manifest_path = os.path.join(self.bp_dir, 'manifest.yml')
self.manifest_content = """---
default_versions:
- name: php
version: 8.2.7
dependencies:
- name: php
version: 8.2.7
- name: php
version: 8.2.9
- name: php
version: 8.1.20
- name: php
version: 8.1.15
- name: php
version: 8.0.30
- name: nginx
version: 1.21.1
"""

with open(self.manifest_path, 'w') as f:
f.write(self.manifest_content)

ctx = utils.FormattedDict({
'BP_DIR': self.bp_dir
})
self.builder = MagicMock(_ctx=ctx)
self.configurer = builder.Configurer(self.builder)

def tearDown(self):
shutil.rmtree(self.bp_dir)

def test_default_config_sets_php_default_and_stream_latest(self):
self.configurer.default_config()
injected = self.builder._ctx

eq_(injected.get('PHP_DEFAULT'), '8.2.7')
eq_(injected.get('PHP_82_LATEST'), '8.2.9')
eq_(injected.get('PHP_81_LATEST'), '8.1.20')
eq_(injected.get('PHP_80_LATEST'), '8.0.30')

assert_not_in('PHP_83_LATEST', injected)

def test_default_config_ignores_non_php_dependencies(self):
self.configurer.default_config()
assert_not_in('NGINX_LATEST', self.builder._ctx)
Loading