diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc1a4d9b..01d1fc02c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v0.8.0 May 20, 2016 +- Switch to .NET CLI from DNX +- Add support for RC2 apps +- Remove support for RC1 and lower apps using DNX +- detect now looks for project.json files or *.runtimeconfig.json files from publish output +- global.json is no longer used to specify runtime version +- Remove support for lucid64 stack + ## v0.7.0 Sep 30, 2015 - Make NuGet.Config optional, detect only looks for project.json files - Support published apps for offline mode and faster staging diff --git a/Dockerfile.gettext b/Dockerfile.gettext new file mode 100644 index 000000000..239b2646e --- /dev/null +++ b/Dockerfile.gettext @@ -0,0 +1,14 @@ +# To build gettext and extract the files from the Docker container: +# export CF_STACK=cflinuxfs2 +# export GETTEXT_VERSION=0.19.7 +# cat Dockerfile.gettext | envsubst | docker build -t gettext-${CF_STACK}-${GETTEXT_VERSION} - +# docker run -v /somehostdir:/built --rm gettext-${CF_STACK}-${GETTEXT_VERSION} /bin/bash -c "cd /usr/local && tar czf /built/gettext-${CF_STACK}-${GETTEXT_VERSION}.tar.gz ./lib/**" + +FROM cloudfoundry/$CF_STACK + +RUN curl -sSL http://ftpmirror.gnu.org/gettext/gettext-${GETTEXT_VERSION}.tar.gz | tar zxfv - -C /usr/local/src \ + && cd /usr/local/src/gettext-${GETTEXT_VERSION} \ + && ./configure \ + && make \ + && make install \ + && rm -rf /usr/local/src/gettext-${GETTEXT_VERSION} diff --git a/Dockerfile.libunwind b/Dockerfile.libunwind index 4b0eb2ed2..3825346b5 100644 --- a/Dockerfile.libunwind +++ b/Dockerfile.libunwind @@ -6,9 +6,9 @@ FROM cloudfoundry/$CF_STACK -RUN curl -SSL wget http://download.savannah.gnu.org/releases/libunwind/libunwind-${LIBUNWIND_VERSION}.tar.gz | tar zxfv - -C /usr/local/src \ +RUN curl -sSL http://download.savannah.gnu.org/releases/libunwind/libunwind-${LIBUNWIND_VERSION}.tar.gz | tar zxfv - -C /usr/local/src \ && cd /usr/local/src/libunwind-${LIBUNWIND_VERSION} \ && ./configure \ && make \ - && make install + && make install \ && rm -rf /usr/local/src/libunwind-${LIBUNWIND_VERSION} diff --git a/Dockerfile.libuv b/Dockerfile.libuv deleted file mode 100644 index c270c7009..000000000 --- a/Dockerfile.libuv +++ /dev/null @@ -1,21 +0,0 @@ -# To build libuv and extract the files from the Docker container: -# export CF_STACK=cflinuxfs2 -# export LIBUV_VERSION=1.4.2 -# cat Dockerfile.libuv | envsubst | docker build -t libuv-${CF_STACK}-${LIBUV_VERSION} - -# docker run -v /somehostdir:/built --rm libuv-${CF_STACK}-${LIBUV_VERSION} /bin/bash -c "cd /usr/local && tar czf /built/libuv-${CF_STACK}-${LIBUV_VERSION}.tar.gz ./include/uv* ./lib/libuv*" - -FROM cloudfoundry/$CF_STACK - -RUN apt-get -qq update && apt-get -qqy install curl \ - autoconf \ - automake \ - build-essential \ - libtool - -RUN curl -sSL https://github.com/libuv/libuv/archive/v${LIBUV_VERSION}.tar.gz | tar zxfv - -C /usr/local/src \ - && cd /usr/local/src/libuv-$LIBUV_VERSION \ - && sh autogen.sh \ - && ./configure \ - && make \ - && make install \ - && rm -rf /usr/local/src/libuv-$LIBUV_VERSION diff --git a/README.md b/README.md index 728931e03..dc83cde23 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Cloud Foundry buildpack: ASP.NET 5 -A Cloud Foundry buildpack for ASP.NET 5 web applications. Tested with [beta8][] applications that target .NET Core. +A Cloud Foundry buildpack for ASP.NET 5 web applications. Tested with [RC2][] applications that target .NET Core. For more information about ASP.NET 5 see: @@ -13,18 +13,27 @@ For more information about ASP.NET 5 see: cf push my_app -b https://github.com/cloudfoundry-community/asp.net5-buildpack.git ``` -This buildpack will be used if there are one or more `project.json` files in the pushed application. +This buildpack will be used if there are one or more `project.json` files in the pushed application, or if the application is pushed from the output directory of the `dotnet publish` command. -Also make sure the application includes a `kestrel` or a `web` command and the corresponding Microsoft.AspNet.Server.Kestrel dependency because the buildpack will use [Kestrel][] to run the application. - -Use a `global.json` file to specify the desired DNX version if different than the latest stable beta release. Use a `NuGet.Config` file to specify non-default package sources. +Use a `NuGet.Config` file to specify non-default package sources. For a basic example see this [Hello World sample][]. +## Legacy DNX support (used for RC1 apps) + +With the introduction of support for the Dotnet CLI in buildpack version 0.8, apps which relied on the older DNX toolchain will no longer work with the current buildpack. If you need to keep your app running on DNX for now until you can update it to use the Dotnet CLI, use the following command: + +```bash +cf push my_app -b https://github.com/cloudfoundry-community/asp.net5-buildpack.git#dnx +``` + +Keep in mind that this support provided to allow users time to update their apps to use the Dotnet CLI, and you should switch to using the main branch of the buildpack (using the command further above) as soon as possible. + ## Disconnected environments + The binaries in `manifest.yml` can be cached with the buildpack. -Applications can be pushed with their other dependencies after "publishing" the application like `dnu publish` or `dnu publish --runtime ~/.dnx/runtimes/dnx-coreclr-linux-x64.1.0.0-beta7`. Then push from the `bin/output` director. +Applications can be pushed with their other dependencies after "publishing" the application like `dotnet publish`. Then push from the `bin///publish` directory. ## Building @@ -57,11 +66,11 @@ These steps only apply to admins who wish to install the buildpack into their Cl 5. Use in Cloud Foundry Upload the buildpack to your Cloud Foundry and optionally specify it by name - + ```bash cf create-buildpack custom_aspnet5_buildpack aspnet5_buildpack-cached-custom.zip 1 cf push my_app -b custom_aspnet5_buildpack - ``` + ``` ## Contributing @@ -73,5 +82,5 @@ Open an issue on this project. [Hello World sample]: https://github.com/IBM-Bluemix/asp.net5-helloworld -[beta8]: https://github.com/aspnet/Home/releases/tag/v1.0.0-beta8 +[RC2]: https://github.com/aspnet/Home/releases/tag/v1.0.0-rc2-final [Kestrel]: https://github.com/aspnet/KestrelHttpServer diff --git a/VERSION b/VERSION index faef31a43..a3df0a695 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.0 +0.8.0 diff --git a/compile-extensions b/compile-extensions index 8d4d16790..4a0e48afc 160000 --- a/compile-extensions +++ b/compile-extensions @@ -1 +1 @@ -Subproject commit 8d4d16790032fc1ac34eb831478d96087ad659ad +Subproject commit 4a0e48afc46c1d467b7c75a8ae5e6f3a044d3d64 diff --git a/lib/buildpack.rb b/lib/buildpack.rb index 1a2f6c9b6..bd625e6ee 100644 --- a/lib/buildpack.rb +++ b/lib/buildpack.rb @@ -34,11 +34,10 @@ def self.compiler(build_dir, cache_dir) Compiler.new( build_dir, cache_dir, - LibuvInstaller.new(build_dir, shell), LibunwindInstaller.new(build_dir, shell), - DnvmInstaller.new(shell), - DnxInstaller.new(shell), - DNU.new(shell), + GetTextInstaller.new(build_dir, shell), + DotnetInstaller.new(shell), + Dotnet.new(shell), Copier.new, out) end diff --git a/lib/buildpack/app_dir.rb b/lib/buildpack/app_dir.rb index b0525f42f..9854451e0 100644 --- a/lib/buildpack/app_dir.rb +++ b/lib/buildpack/app_dir.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. +# Copyright 2015-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -48,13 +48,29 @@ def deployment_file_project paths = with_project_json deployment_file = File.expand_path(File.join(@dir, DEPLOYMENT_FILE_NAME)) File.foreach(deployment_file, encoding: 'utf-8') do |line| - m = /project = (.*)/.match(line) + m = /project[ \t]*=[ \t]*(.*)/i.match(line) if m - path = Pathname.new(m[1]) + n = /.*([.](xproj|csproj))/i.match(m[1]) + path = n ? Pathname.new(File.dirname(m[1])) : Pathname.new(m[1]) return path if paths.include?(path) end end if File.exist?(deployment_file) nil end + + def main_project_path + path = deployment_file_project + project_paths = with_project_json + multiple_paths = project_paths.any? && !project_paths.one? + fail 'Multiple paths contain a project.json file, but no .deployment file was used' if multiple_paths unless path + path = project_paths.first unless path + path if path + end + + def published_project + config_files = Dir.glob(File.join(@dir, '*.runtimeconfig.json')) + m = /(.*)[.]runtimeconfig[.]json/i.match(Pathname.new(config_files.first).basename.to_s) if config_files.one? + m[1].to_s unless m.nil? + end end end diff --git a/lib/buildpack/compile/compiler.rb b/lib/buildpack/compile/compiler.rb index 747ef3597..cc94fd1b2 100644 --- a/lib/buildpack/compile/compiler.rb +++ b/lib/buildpack/compile/compiler.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,11 +14,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -require_relative 'libuv_installer.rb' require_relative 'libunwind_installer.rb' -require_relative 'dnvm_installer.rb' -require_relative 'dnx_installer.rb' -require_relative 'dnu.rb' +require_relative 'gettext_installer.rb' +require_relative 'dotnet_installer.rb' +require_relative 'dotnet.rb' require_relative '../bp_version.rb' require 'json' @@ -26,14 +25,13 @@ module AspNet5Buildpack class Compiler - def initialize(build_dir, cache_dir, libuv_binary, libunwind_binary, dnvm_installer, dnx_installer, dnu, copier, out) + def initialize(build_dir, cache_dir, libunwind_binary, gettext_binary, dotnet_installer, dotnet, copier, out) @build_dir = build_dir @cache_dir = cache_dir - @libuv_binary = libuv_binary @libunwind_binary = libunwind_binary - @dnvm_installer = dnvm_installer - @dnx_installer = dnx_installer - @dnu = dnu + @gettext_binary = gettext_binary + @dotnet_installer = dotnet_installer + @dotnet = dotnet @copier = copier @out = out end @@ -42,11 +40,10 @@ def compile puts "ASP.NET 5 buildpack version: #{BuildpackVersion.new.version}\n" puts "ASP.NET 5 buildpack starting compile\n" step('Restoring files from buildpack cache', method(:restore_cache)) - step('Extracting libuv', method(:extract_libuv)) step('Extracting libunwind', method(:extract_libunwind)) - step('Installing DNVM', method(:install_dnvm)) - step('Installing DNX with DNVM', method(:install_dnx)) - step('Restoring dependencies with DNU', method(:restore_dependencies)) + step('Extracting gettext', method(:extract_gettext)) + step('Installing Dotnet CLI', method(:install_dotnet)) + step('Restoring dependencies with Dotnet CLI', method(:restore_dependencies)) step('Saving to buildpack cache', method(:save_cache)) puts "ASP.NET 5 buildpack is done creating the droplet\n" return true @@ -57,36 +54,32 @@ def compile private - def extract_libuv(out) - libuv_binary.extract(File.join(build_dir, 'libuv'), out) unless File.exist? File.join(build_dir, 'libuv') - end - def extract_libunwind(out) libunwind_binary.extract(File.join(build_dir, 'libunwind'), out) unless File.exist? File.join(build_dir, 'libunwind') end - def restore_cache(out) - copier.cp(File.join(cache_dir, '.dnx'), build_dir, out) if File.exist? File.join(cache_dir, '.dnx') - copier.cp(File.join(cache_dir, 'libuv'), build_dir, out) if File.exist? File.join(cache_dir, 'libuv') - copier.cp(File.join(cache_dir, 'libunwind'), build_dir, out) if File.exist? File.join(cache_dir, 'libunwind') + def extract_gettext(out) + gettext_binary.extract(File.join(build_dir, 'gettext'), out) unless File.exist? File.join(build_dir, 'gettext') end - def install_dnvm(out) - dnvm_installer.install(build_dir, out) unless File.exist? File.join(build_dir, 'approot', 'runtimes') + def restore_cache(out) + copier.cp(File.join(cache_dir, '.nuget'), build_dir, out) if File.exist? File.join(cache_dir, '.nuget') + copier.cp(File.join(cache_dir, 'libunwind'), build_dir, out) if File.exist? File.join(cache_dir, 'libunwind') + copier.cp(File.join(cache_dir, 'gettext'), build_dir, out) if File.exist? File.join(cache_dir, 'gettext') end - def install_dnx(out) - dnx_installer.install(build_dir, out) unless File.exist? File.join(build_dir, 'approot', 'runtimes') + def install_dotnet(out) + dotnet_installer.install(build_dir, out) unless File.exist? File.join(build_dir, 'approot', 'runtimes') end def restore_dependencies(out) - dnu.restore(build_dir, out) unless File.exist? File.join(build_dir, 'approot', 'packages') + dotnet.restore(build_dir, out) unless File.exist? File.join(build_dir, 'approot', 'packages') end def save_cache(out) - copier.cp(File.join(build_dir, '.dnx'), cache_dir, out) if File.exist? File.join(build_dir, '.dnx') - copier.cp(File.join(build_dir, 'libuv'), cache_dir, out) unless File.exist? File.join(cache_dir, 'libuv') + copier.cp(File.join(build_dir, '.nuget'), cache_dir, out) if File.exist? File.join(build_dir, '.nuget') copier.cp(File.join(build_dir, 'libunwind'), cache_dir, out) unless File.exist? File.join(cache_dir, 'libunwind') + copier.cp(File.join(build_dir, 'gettext'), cache_dir, out) unless File.exist? File.join(cache_dir, 'gettext') end def step(description, method) @@ -103,12 +96,11 @@ def step(description, method) attr_reader :build_dir attr_reader :cache_dir - attr_reader :libuv_binary attr_reader :libunwind_binary - attr_reader :dnvm_installer - attr_reader :dnx_installer + attr_reader :gettext_binary + attr_reader :dotnet_installer attr_reader :mozroots - attr_reader :dnu + attr_reader :dotnet attr_reader :copier attr_reader :out end diff --git a/lib/buildpack/compile/dnx_installer.rb b/lib/buildpack/compile/dnx_installer.rb deleted file mode 100644 index 7e9a062be..000000000 --- a/lib/buildpack/compile/dnx_installer.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Encoding: utf-8 -# ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require_relative 'dnx_version' - -module AspNet5Buildpack - class DnxInstaller - def initialize(shell) - @shell = shell - end - - def install(dir, out) - @shell.env['HOME'] = dir - version = DnxVersion.new.version(dir, out) - @shell.exec("bash -c 'source #{dir}/.dnx/dnvm/dnvm.sh; dnvm install #{version} -p -r coreclr'", out) - end - end -end diff --git a/lib/buildpack/compile/dnx_version.rb b/lib/buildpack/compile/dnx_version.rb deleted file mode 100644 index 588bd844c..000000000 --- a/lib/buildpack/compile/dnx_version.rb +++ /dev/null @@ -1,41 +0,0 @@ -# Encoding: utf-8 -# ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'json' - -module AspNet5Buildpack - class DnxVersion - DNX_VERSION_FILE_NAME = 'global.json'.freeze - DEFAULT_DNX_VERSION = 'latest'.freeze - - def version(dir, out) - dnx_version = DEFAULT_DNX_VERSION - version_file = File.expand_path(File.join(dir, DNX_VERSION_FILE_NAME)) - if File.exist?(version_file) - begin - global_props = JSON.parse(File.read(version_file, encoding: 'bom|utf-8')) - if global_props.key?('sdk') - sdk = global_props['sdk'] - dnx_version = sdk['version'] if sdk.key?('version') - end - rescue - out.warn("File #{version_file} is not valid JSON") - end - end - dnx_version - end - end -end diff --git a/lib/buildpack/compile/dnu.rb b/lib/buildpack/compile/dotnet.rb similarity index 80% rename from lib/buildpack/compile/dnu.rb rename to lib/buildpack/compile/dotnet.rb index 0a869dc56..e40fed548 100644 --- a/lib/buildpack/compile/dnu.rb +++ b/lib/buildpack/compile/dotnet.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. +# Copyright 2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,16 +17,17 @@ require_relative '../app_dir' module AspNet5Buildpack - class DNU + class Dotnet def initialize(shell) @shell = shell end def restore(dir, out) @shell.env['HOME'] = dir - @shell.env['LD_LIBRARY_PATH'] = "$LD_LIBRARY_PATH:#{dir}/libunwind/lib" + @shell.env['LD_LIBRARY_PATH'] = "$LD_LIBRARY_PATH:#{dir}/libunwind/lib:#{dir}/gettext/lib" + @shell.env['PATH'] = "$PATH:#{dir}/.dotnet" project_list = AppDir.new(dir).with_project_json.join(' ') - cmd = "bash -c 'source #{dir}/.dnx/dnvm/dnvm.sh; dnvm use default; cd #{dir}; dnu restore --quiet #{project_list}'" + cmd = "bash -c 'cd #{dir}; dotnet restore --quiet #{project_list}'" @shell.exec(cmd, out) end end diff --git a/lib/buildpack/compile/dnvm_installer.rb b/lib/buildpack/compile/dotnet_installer.rb similarity index 71% rename from lib/buildpack/compile/dnvm_installer.rb rename to lib/buildpack/compile/dotnet_installer.rb index a7e27a59e..c5ff4baf8 100644 --- a/lib/buildpack/compile/dnvm_installer.rb +++ b/lib/buildpack/compile/dotnet_installer.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. +# Copyright 2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,14 +15,15 @@ # limitations under the License. module AspNet5Buildpack - class DnvmInstaller + class DotnetInstaller def initialize(shell) @shell = shell end def install(dir, out) @shell.env['HOME'] = dir - cmd = 'touch ~/.bashrc; curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh; rm -rf ~/.bashrc' + wrapper = File.join(File.dirname(__FILE__), 'ldconfig_wrapper.sh') + cmd = "bash -c 'source #{wrapper}; source <(curl -sSL https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0-preview1/scripts/obtain/dotnet-install.sh)'" @shell.exec(cmd, out) end end diff --git a/lib/buildpack/compile/libuv_installer.rb b/lib/buildpack/compile/gettext_installer.rb similarity index 87% rename from lib/buildpack/compile/libuv_installer.rb rename to lib/buildpack/compile/gettext_installer.rb index 11633a5f5..c1799cfdb 100644 --- a/lib/buildpack/compile/libuv_installer.rb +++ b/lib/buildpack/compile/gettext_installer.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. +# Copyright 2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,8 +15,8 @@ # limitations under the License. module AspNet5Buildpack - class LibuvInstaller - VERSION = '1.4.2'.freeze + class GetTextInstaller + VERSION = '0.19.7'.freeze def initialize(app_dir, shell) @app_dir = app_dir @@ -24,12 +24,12 @@ def initialize(app_dir, shell) end def extract(dest_dir, out) - out.print("libuv version: #{version}") + out.print("gettext version: #{version}") cmd = "mkdir -p #{dest_dir}; curl -L `translate_dependency_url #{dependency_name}` -s | tar zxv -C #{dest_dir} &> /dev/null" run_common_cmd(cmd, out) end - def libuv_tar_gz(out) + def gettext_tar_gz(out) run_common_cmd("translate_dependency_url #{dependency_name}", out) end @@ -50,7 +50,7 @@ def buildpack_root end def dependency_name - "libuv-x-#{version}.tar.gz" + "gettext-x-#{version}.tar.gz" end end end diff --git a/lib/buildpack/compile/ldconfig_wrapper.sh b/lib/buildpack/compile/ldconfig_wrapper.sh new file mode 100755 index 000000000..8d6685c41 --- /dev/null +++ b/lib/buildpack/compile/ldconfig_wrapper.sh @@ -0,0 +1,19 @@ +if ! [ -x "$(command -v ldconfig)" ]; then + LDCONFIG_COMMAND="/sbin/ldconfig" +else + LDCONFIG_COMMAND="$(command -v ldconfig)" +fi + +LDCONFIG_DIR=~/ldconfig +LDCONFIG_SCRIPT=$LDCONFIG_DIR/ldconfig + +mkdir -p $LDCONFIG_DIR +echo "#!/bin/bash" > $LDCONFIG_SCRIPT +echo "$LDCONFIG_COMMAND -C $LDCONFIG_DIR/ld.so.cache \$@" >> $LDCONFIG_SCRIPT +chmod 755 $LDCONFIG_SCRIPT +export PATH=$LDCONFIG_DIR:$PATH + +cp /etc/ld.so.conf $LDCONFIG_DIR +echo "$HOME/libunwind/lib/">> $LDCONFIG_DIR/ld.so.conf +echo "$HOME/gettext/lib/">> $LDCONFIG_DIR/ld.so.conf +ldconfig -f $LDCONFIG_DIR/ld.so.conf \ No newline at end of file diff --git a/lib/buildpack/compile/libunwind_installer.rb b/lib/buildpack/compile/libunwind_installer.rb index 0da75616a..e1e83f18f 100644 --- a/lib/buildpack/compile/libunwind_installer.rb +++ b/lib/buildpack/compile/libunwind_installer.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. +# Copyright 2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/lib/buildpack/detect/detecter.rb b/lib/buildpack/detect/detecter.rb index b743208ca..6262a7649 100644 --- a/lib/buildpack/detect/detecter.rb +++ b/lib/buildpack/detect/detecter.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,7 +17,9 @@ module AspNet5Buildpack class Detecter def detect(dir) - !Dir.glob(File.join(dir, '**', 'project.json')).empty? + fromsource = !Dir.glob(File.join(dir, '**', 'project.json')).empty? + frompublish = !Dir.glob(File.join(dir, '*.runtimeconfig.json')).empty? + fromsource || frompublish end end end diff --git a/lib/buildpack/release/releaser.rb b/lib/buildpack/release/releaser.rb index 824c53f99..ecec0f53d 100644 --- a/lib/buildpack/release/releaser.rb +++ b/lib/buildpack/release/releaser.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,16 +18,12 @@ module AspNet5Buildpack class Releaser - KESTREL_CMD = 'kestrel'.freeze - WEB_CMD = 'web'.freeze - def release(build_dir) app = AppDir.new(build_dir) - path = main_project_path(app) - raise "No #{KESTREL_CMD} or #{WEB_CMD} command found" unless path - cfweb_cmd = get_cfweb_cmd(app, path) + start_cmd = get_start_cmd(app) + write_startup_script(startup_script_path(build_dir)) - generate_yml(cfweb_cmd, build_dir, path) + generate_yml(start_cmd) end private @@ -36,13 +32,12 @@ def write_startup_script(startup_script) FileUtils.mkdir_p(File.dirname(startup_script)) File.open(startup_script, 'w') do |f| f.write 'export HOME=/app;' - f.write 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/libuv/lib:$HOME/libunwind/lib;' - f.write '[ -f $HOME/.dnx/dnvm/dnvm.sh ] && { source $HOME/.dnx/dnvm/dnvm.sh; dnvm use default; }' + f.write 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/gettext/lib:$HOME/libunwind/lib;' + f.write 'export PATH=$PATH:$HOME/.dotnet;' end end - def generate_yml(cfweb_cmd, base_dir, web_dir) - start_cmd = File.exist?(File.join(base_dir, 'approot', cfweb_cmd)) ? "approot/#{cfweb_cmd}" : "dnx --project #{web_dir} #{cfweb_cmd}" + def generate_yml(start_cmd) yml = <<-EOT --- default_process_types: @@ -51,24 +46,18 @@ def generate_yml(cfweb_cmd, base_dir, web_dir) yml end - def main_project_path(app) - path = app.deployment_file_project - return path if path - kestrel_paths = app.with_project_json.select { |p| cfweb_path_exists(app, p) } - kestrel_paths.first - end + def get_start_cmd(app) + project = app.main_project_path + return "dotnet run --project #{project}" unless project.nil? - def startup_script_path(dir) - File.join(dir, '.profile.d', 'startup.sh') - end + project = app.published_project + return "dotnet #{project}.dll" unless project.nil? - def get_cfweb_cmd(app, path) - return KESTREL_CMD if app.commands(path)[KESTREL_CMD] - WEB_CMD + fail 'No project could be identified to run' unless !project.nil? end - def cfweb_path_exists(app, path) - app.commands(path)[KESTREL_CMD] || app.commands(path)[WEB_CMD] + def startup_script_path(dir) + File.join(dir, '.profile.d', 'startup.sh') end end end diff --git a/lib/buildpack/shell.rb b/lib/buildpack/shell.rb index b321af504..e5be15583 100644 --- a/lib/buildpack/shell.rb +++ b/lib/buildpack/shell.rb @@ -24,7 +24,7 @@ def exec(cmd, out) out.print line.chomp end - raise "command failed, exit status #{t.value.exitstatus}" unless t.value.success? + fail "command failed, exit status #{t.value.exitstatus}" unless t.value.success? end end diff --git a/manifest.yml b/manifest.yml index e5914b3b6..dd10b2ae1 100644 --- a/manifest.yml +++ b/manifest.yml @@ -2,35 +2,14 @@ language: aspnet5 url_to_dependency_map: - - match: libuv-(.*)-(\d+\.\d+\.\d+) - name: libuv - version: $2 - match: libunwind-(.*)-(\d+\.\d+) name: libunwind version: $2 + - match: gettext-(.*)-(\d+\.\d+(\.\d+)?) + name: gettext + version: $2 dependencies: - - name: libuv - version: 1.4.2 - cf_stacks: - - lucid64 - uri: https://github.com/cloudfoundry-community/asp.net5-buildpack/releases/download/v0.5/libuv-lucid64-1.4.2.tar.gz - md5: bec8ea66006c89abb0c7314d62b82a57 - - - name: libuv - version: 1.4.2 - cf_stacks: - - cflinuxfs2 - uri: https://github.com/cloudfoundry-community/asp.net5-buildpack/releases/download/v0.5/libuv-cflinuxfs2-1.4.2.tar.gz - md5: 72ad380dbab354bbc3d0f41825c22bd0 - - - name: libunwind - version: 1.1 - cf_stacks: - - lucid64 - uri: https://github.com/cloudfoundry-community/asp.net5-buildpack/releases/download/v0.7/libunwind-lucid64-1.1.tar.gz - md5: c49405a4565f3ca8838983edca697df6 - - name: libunwind version: 1.1 cf_stacks: @@ -38,6 +17,13 @@ dependencies: uri: https://github.com/cloudfoundry-community/asp.net5-buildpack/releases/download/v0.7/libunwind-cflinuxfs2-1.1.tar.gz md5: b76452a8a2400f3cfdf189761e8be97e + - name: gettext + version: 0.19.7 + cf_stacks: + - cflinuxfs2 + uri: https://github.com/cloudfoundry-community/asp.net5-buildpack/releases/download/v0.8/gettext-cflinuxfs2-0.19.7.tar.gz + md5: 59b73b2fab0b966717109feb662eb460 + exclude_files: - .git/ - .gitignore diff --git a/spec/buildpack/app_dir_spec.rb b/spec/buildpack/app_dir_spec.rb index 3046129b8..cd8c11636 100644 --- a/spec/buildpack/app_dir_spec.rb +++ b/spec/buildpack/app_dir_spec.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ context 'with multiple projects' do let(:proj1) { File.join(dir, 'src', 'proj1').tap { |f| FileUtils.mkdir_p(f) } } let(:proj2) { File.join(dir, 'src', 'föö').tap { |f| FileUtils.mkdir_p(f) } } - let(:dnx) { File.join(dir, '.dnx', 'dep').tap { |f| FileUtils.mkdir_p(f) } } + let(:nuget) { File.join(dir, '.nuget', 'dep').tap { |f| FileUtils.mkdir_p(f) } } before do File.open(File.join(proj1, 'project.json'), 'w') do |f| @@ -36,7 +36,7 @@ f.write "\uFEFF" f.write '{ "commands": { "web": "whatever" } }' end - File.open(File.join(dnx, 'project.json'), 'w') do |f| + File.open(File.join(nuget, 'project.json'), 'w') do |f| f.write '{ "commands": { "web": "whatever" } }' end end @@ -45,31 +45,56 @@ expect(appdir.with_project_json).to match_array([Pathname.new('src/proj1'), Pathname.new('src/föö')]) end - it 'finds project paths where project.json files have specific commands' do - expect(appdir.with_command('web')).to match_array([Pathname.new('src/föö')]) - end - - it 'does not find project paths where no project.json files have specific command' do - expect(appdir.with_command('fakecmd')).to match_array([]) - end + context '.deployment file exists' do + context 'and specifies an existing project' do + before do + File.open(File.join(dir, '.deployment'), 'w') do |f| + f.write("project = src/föö\n") + end + end - it 'reads commands from project.json files' do - expect(appdir.commands('src/proj1')).to eq('web1' => 'whatever', 'web2' => 'whatever') - end + it 'finds specified project' do + expect(appdir.deployment_file_project).to eq(Pathname.new('src/föö')) + end + end - it 'reads commands from project.json files with byte-order marks' do - expect(appdir.commands('src/föö')).to eq('web' => 'whatever') - end + context 'and specifies a non-existent project' do + before do + File.open(File.join(dir, '.deployment'), 'w') do |f| + f.write("project = dne\n") + end + end - context '.deployment file specifies an existing project' do - before do - File.open(File.join(dir, '.deployment'), 'w') do |f| - f.write("project = src/föö\n") + it 'does not find a project' do + expect(appdir.deployment_file_project).to be_nil end end - it 'finds specified project' do - expect(appdir.deployment_file_project).to eq(Pathname.new('src/föö')) + context 'contains a byte order mark' do + before do + File.open(File.join(dir, '.deployment'), 'w') do |f| + f.write("\uFEFF") + f.write("[config]\n") + end + end + + context 'but does not specify a project' do + it 'does not find a project' do + expect(appdir.deployment_file_project).to be_nil + end + end + + context 'and specifies an existing project' do + before do + File.open(File.join(dir, '.deployment'), 'a') do |f| + f.write("project = src/proj1") + end + end + + it 'finds specified project' do + expect(appdir.deployment_file_project).to eq(Pathname.new('src/proj1')) + end + end end end @@ -77,29 +102,20 @@ it 'does not find a project' do expect(appdir.deployment_file_project).to be_nil end - end - - context '.deployment file specifies a non-existent project' do - before do - File.open(File.join(dir, '.deployment'), 'w') do |f| - f.write("project = dne\n") - end - end - it 'does not find a project' do - expect(appdir.deployment_file_project).to be_nil + it 'raises an error to tell the user that they need a .deployment file' do + error_message = "Multiple paths contain a project.json file, but no .deployment file was used" + expect { appdir.main_project_path }.to raise_error(error_message) end end - context '.deployment file exists but does not specify a project' do + context '*.runtimeconfig.json file exists in published app' do before do - File.open(File.join(dir, '.deployment'), 'w') do |f| - f.write("[config]\n") - end + File.open(File.join(dir, 'proj1.runtimeconfig.json'), 'w') { |f| f.write 'x' } end - it 'does not find a project' do - expect(appdir.deployment_file_project).to be_nil + it 'determines app name based on runtimeconfig.json file name' do + expect(appdir.published_project).to match('proj1') end end end diff --git a/spec/buildpack/compile/compile_spec.rb b/spec/buildpack/compile/compile_spec.rb index ba6c40d24..dffac6e75 100644 --- a/spec/buildpack/compile/compile_spec.rb +++ b/spec/buildpack/compile/compile_spec.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,19 +21,18 @@ describe AspNet5Buildpack::Compiler do subject(:compiler) do - AspNet5Buildpack::Compiler.new(build_dir, cache_dir, libuv_binary, libunwind_binary, dnvm_installer, dnx_installer, dnu, copier, out) + AspNet5Buildpack::Compiler.new(build_dir, cache_dir, libunwind_binary, gettext_binary, dotnet_installer, dotnet, copier, out) end before do allow($stdout).to receive(:write) end - let(:libuv_binary) { double(:libuv_binary, extract: nil) } let(:libunwind_binary) { double(:libunwind_binary, extract: nil) } + let(:gettext_binary) { double(:gettext_binary, extract: nil) } let(:copier) { double(:copier, cp: nil) } - let(:dnvm_installer) { double(:dnvm_installer, install: nil) } - let(:dnx_installer) { double(:dnx_installer, install: nil) } - let(:dnu) { double(:dnu, restore: nil) } + let(:dotnet_installer) { double(:dotnet_installer, install: nil) } + let(:dotnet) { double(:dotnet, restore: nil) } let(:build_dir) { Dir.mktmpdir } let(:cache_dir) { Dir.mktmpdir } @@ -84,7 +83,7 @@ end it 'binary files extracted' do - expect(libuv_binary).to receive(:extract) + expect(gettext_binary).to receive(:extract) expect(libunwind_binary).to receive(:extract) compiler.compile end @@ -92,33 +91,33 @@ context 'cache exists' do before(:each) do - Dir.mkdir(File.join(cache_dir, '.dnx')) - Dir.mkdir(File.join(cache_dir, 'libuv')) + Dir.mkdir(File.join(cache_dir, '.nuget')) + Dir.mkdir(File.join(cache_dir, 'gettext')) Dir.mkdir(File.join(cache_dir, 'libunwind')) - Dir.mkdir(File.join(build_dir, 'libuv')) Dir.mkdir(File.join(build_dir, 'libunwind')) + Dir.mkdir(File.join(build_dir, 'gettext')) end it 'copies files from cache to build dir' do - expect(copier).to receive(:cp).with(File.join(cache_dir, '.dnx'), build_dir, anything) - expect(copier).to receive(:cp).with(File.join(cache_dir, 'libuv'), build_dir, anything) + expect(copier).to receive(:cp).with(File.join(cache_dir, '.nuget'), build_dir, anything) + expect(copier).to receive(:cp).with(File.join(cache_dir, 'gettext'), build_dir, anything) expect(copier).to receive(:cp).with(File.join(cache_dir, 'libunwind'), build_dir, anything) compiler.compile end it 'binary files not extracted' do - expect(libuv_binary).not_to receive(:extract) expect(libunwind_binary).not_to receive(:extract) + expect(gettext_binary).not_to receive(:extract) compiler.compile end end end - describe 'Installing DNVM' do - it_behaves_like 'step', 'Installing DNVM', :install_dnvm + describe 'Installing Dotnet CLI' do + it_behaves_like 'step', 'Installing Dotnet CLI', :install_dotnet - it 'installs dnvm' do - expect(dnvm_installer).to receive(:install).with(build_dir, anything) + it 'installs dotnet cli' do + expect(dotnet_installer).to receive(:install).with(build_dir, anything) compiler.compile end @@ -128,37 +127,17 @@ end it 'skips installing DNVM' do - expect(dnvm_installer).not_to receive(:install) + expect(dotnet_installer).not_to receive(:install) compiler.compile end end end - describe 'Installing DNX with DNVM' do - it_behaves_like 'step', 'Installing DNX with DNVM', :install_dnx + describe 'Restoring dependencies with Dotnet CLI' do + it_behaves_like 'step', 'Restoring dependencies with Dotnet CLI', :restore_dependencies - it 'installs dnx' do - expect(dnx_installer).to receive(:install).with(build_dir, anything) - compiler.compile - end - - context 'when the app was published with DNX' do - before do - FileUtils.mkdir_p(File.join(build_dir, 'approot', 'runtimes')) - end - - it 'skips installing DNX' do - expect(dnx_installer).not_to receive(:install) - compiler.compile - end - end - end - - describe 'Restoring dependencies with DNU' do - it_behaves_like 'step', 'Restoring dependencies with DNU', :restore_dependencies - - it 'runs dnu restore' do - expect(dnu).to receive(:restore).with(build_dir, anything) + it 'runs dotnet restore' do + expect(dotnet).to receive(:restore).with(build_dir, anything) compiler.compile end @@ -167,8 +146,8 @@ FileUtils.mkdir_p(File.join(build_dir, 'approot', 'packages')) end - it 'skips running dnu restore' do - expect(dnu).not_to receive(:restore) + it 'skips running dotnet restore' do + expect(dotnet).not_to receive(:restore) compiler.compile end end @@ -178,21 +157,20 @@ it_behaves_like 'step', 'Saving to buildpack cache', :save_cache it 'copies files to cache dir' do - expect(copier).to receive(:cp).with("#{build_dir}/libuv", cache_dir, anything) + expect(copier).to receive(:cp).with("#{build_dir}/gettext", cache_dir, anything) expect(copier).to receive(:cp).with("#{build_dir}/libunwind", cache_dir, anything) compiler.compile end context 'when the cache already exists' do before(:each) do - Dir.mkdir(File.join(build_dir, '.dnx')) - Dir.mkdir(File.join(cache_dir, '.dnx')) - Dir.mkdir(File.join(cache_dir, 'libuv')) + Dir.mkdir(File.join(build_dir, '.nuget')) + Dir.mkdir(File.join(cache_dir, 'gettext')) Dir.mkdir(File.join(cache_dir, 'libunwind')) end - it 'copies only .dnx to cache dir' do - expect(copier).to receive(:cp).with("#{build_dir}/.dnx", cache_dir, anything) + it 'copies only .nuget to cache dir' do + expect(copier).to receive(:cp).with("#{build_dir}/.nuget", cache_dir, anything) compiler.compile end end diff --git a/spec/buildpack/compile/dnu_spec.rb b/spec/buildpack/compile/dnu_spec.rb deleted file mode 100644 index 47cf23b14..000000000 --- a/spec/buildpack/compile/dnu_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# Encoding: utf-8 -# ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'rspec' -require_relative '../../../lib/buildpack.rb' - -describe AspNet5Buildpack::DNU do - let(:shell) { double(:shell, env: {}, path: []) } - let(:out) { double(:out) } - subject(:dnu) { AspNet5Buildpack::DNU.new(shell) } - - describe '#restore' do - it 'sets HOME env variable' do - allow(shell).to receive(:exec) - dnu.restore('app-dir', out) - expect(shell.env).to include('HOME' => 'app-dir') - end - - it 'sets LD_LIBRARY_PATH' do - allow(shell).to receive(:exec) - dnu.restore('app-dir', out) - expect(shell.env).to include('LD_LIBRARY_PATH' => '$LD_LIBRARY_PATH:app-dir/libunwind/lib') - end - - it 'adds DNX to the PATH' do - allow(shell).to receive(:exec) - expect(shell).to receive(:exec).with(match('dnvm use default'), out) - dnu.restore('app-dir', out) - end - - it 'sources dnvm.sh script' do - allow(shell).to receive(:exec) - expect(shell).to receive(:exec).with(match('source app-dir/.dnx/dnvm/dnvm.sh'), out) - dnu.restore('app-dir', out) - end - - it 'restores dependencies' do - allow(shell).to receive(:exec) - expect(shell).to receive(:exec).with(match('dnu restore'), out) - dnu.restore('app-dir', out) - end - end -end diff --git a/spec/buildpack/compile/dnx_install_spec.rb b/spec/buildpack/compile/dnx_install_spec.rb deleted file mode 100644 index 5dc16c094..000000000 --- a/spec/buildpack/compile/dnx_install_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -# Encoding: utf-8 -# ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'rspec' -require 'tmpdir' -require_relative '../../../lib/buildpack.rb' - -describe AspNet5Buildpack::DnxInstaller do - let(:shell) { double(:shell, env: {}, path: []) } - let(:out) { double(:out) } - let(:dir) { Dir.mktmpdir } - subject(:installer) { AspNet5Buildpack::DnxInstaller.new(shell) } - - describe '#install' do - it 'sets HOME env variable' do - allow(shell).to receive(:exec) - installer.install(dir, out) - expect(shell.env).to include('HOME' => dir) - end - - it 'sources the dnvm.sh script' do - allow(shell).to receive(:exec) - expect(shell).to receive(:exec).with(match("source #{dir}/.dnx/dnvm/dnvm.sh"), out) - installer.install(dir, out) - end - - it 'installs DNX' do - allow(shell).to receive(:exec) - expect(shell).to receive(:exec).with(match('dnvm install latest -p -r coreclr'), out) - installer.install(dir, out) - end - end -end diff --git a/spec/buildpack/compile/dnx_version_spec.rb b/spec/buildpack/compile/dnx_version_spec.rb deleted file mode 100644 index 4455fad84..000000000 --- a/spec/buildpack/compile/dnx_version_spec.rb +++ /dev/null @@ -1,77 +0,0 @@ -# Encoding: utf-8 -# ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -require 'rspec' -require 'tmpdir' -require_relative '../../../lib/buildpack.rb' - -describe AspNet5Buildpack::DnxVersion do - let(:out) { double(:out) } - let(:dir) { Dir.mktmpdir } - - describe '#version' do - context 'global.json does not exist' do - it 'resolves to the latest version' do - expect(subject.version(dir, out)).to eq('latest') - end - end - - context 'global.json exists' do - before do - json = '{ "sdk": { "version": "1.0.0-beta1" } }' - IO.write(File.join(dir, 'global.json'), json) - end - - it 'resolves to the specified version' do - expect(subject.version(dir, out)).to eq('1.0.0-beta1') - end - end - - context 'global.json exists with a BOM from Visual Studio in it' do - before do - json = "\uFEFF{ \"sdk\": { \"version\": \"1.0.0-beta1\" } }" - IO.write(File.join(dir, 'global.json'), json) - end - - it 'resolves to the specified version' do - expect(subject.version(dir, out)).to eq('1.0.0-beta1') - end - end - - context 'invalid global.json exists' do - before do - json = '"version": "1.0.0-beta1"' - IO.write(File.join(dir, 'global.json'), json) - end - - it 'warns and resolves to the latest version' do - expect(out).to receive(:warn).with("File #{dir}/global.json is not valid JSON") - expect(subject.version(dir, out)).to eq('latest') - end - end - - context 'global.json exists but does not include a version' do - before do - json = '{ "projects": [ "src", "test" ] }' - IO.write(File.join(dir, 'global.json'), json) - end - - it 'resolves to the latest version' do - expect(subject.version(dir, out)).to eq('latest') - end - end - end -end diff --git a/spec/buildpack/compile/dnvm_installer_spec.rb b/spec/buildpack/compile/dotnet_installer_spec.rb similarity index 63% rename from spec/buildpack/compile/dnvm_installer_spec.rb rename to spec/buildpack/compile/dotnet_installer_spec.rb index 81510db61..546f94982 100644 --- a/spec/buildpack/compile/dnvm_installer_spec.rb +++ b/spec/buildpack/compile/dotnet_installer_spec.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,28 +17,23 @@ require 'rspec' require_relative '../../../lib/buildpack.rb' -describe AspNet5Buildpack::DnvmInstaller do +describe AspNet5Buildpack::DotnetInstaller do let(:shell) { double(:shell, env: {}) } let(:out) { double(:out) } - subject(:installer) { AspNet5Buildpack::DnvmInstaller.new(shell) } + subject(:installer) { AspNet5Buildpack::DotnetInstaller.new(shell) } describe '#install' do - it 'creates .bashrc so dnvminstall.sh does not complain' do - expect(shell).to receive(:exec).with(match('touch ~/.bashrc'), out) + it 'wraps calls to ldconfig so dotnet-install.sh does not complain' do + expect(shell).to receive(:exec).with(match(/source .*ldconfig_wrapper[.]sh; (.*)/), out) installer.install('passed-directory', out) end - it 'installs DNVM' do - cmd = 'curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh' + it 'installs Dotnet CLI' do + cmd = %r{(bash -c 'source .*; source <\(curl -sSL https:\/\/.*\/dotnet-install.sh\)')} expect(shell).to receive(:exec).with(match(cmd), out) installer.install('passed-directory', out) end - it 'deletes .bashrc because dnvminstall.sh updated it with temporary paths' do - expect(shell).to receive(:exec).with(match('rm -rf ~/.bashrc'), out) - installer.install('passed-directory', out) - end - it 'sets HOME env variable' do allow(shell).to receive(:exec) installer.install('passed-directory', out) diff --git a/spec/buildpack/compile/libuv_installer_spec.rb b/spec/buildpack/compile/gettext_installer_spec.rb similarity index 81% rename from spec/buildpack/compile/libuv_installer_spec.rb rename to spec/buildpack/compile/gettext_installer_spec.rb index b3afdcb1f..48fdf6137 100644 --- a/spec/buildpack/compile/libuv_installer_spec.rb +++ b/spec/buildpack/compile/gettext_installer_spec.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2015 the original author or authors. +# Copyright 2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -20,26 +20,26 @@ require_relative '../../../lib/buildpack.rb' require_relative '../../../lib/buildpack/shell.rb' -describe AspNet5Buildpack::LibuvInstaller do +describe AspNet5Buildpack::GetTextInstaller do let(:dir) { Dir.mktmpdir } let(:shell) { AspNet5Buildpack::Shell.new } let(:out) { double(:out) } - subject(:libuv_installer) { described_class.new(dir, shell) } + subject(:gettext_installer) { described_class.new(dir, shell) } describe '#version' do it 'has a default version' do - expect(subject.version).to eq('1.4.2') + expect(subject.version).to eq('0.19.7') end end - describe '#libuv_tar_gz' do + describe '#gettext_tar_gz' do context 'when binary present in dependencies dir' do it 'uses local binary' do begin dependencies = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'dependencies')) FileUtils.mkdir_p dependencies expect(out).to receive(:print).with(%r{file:///}) - subject.libuv_tar_gz(out) + subject.gettext_tar_gz(out) ensure FileUtils.rm_rf(dependencies) if File.exist? dependencies end @@ -49,13 +49,13 @@ context 'when binary not present in dependencies dir' do it 'uses remote binary' do expect(out).to receive(:print).with(%r{https://}) - subject.libuv_tar_gz(out) + subject.gettext_tar_gz(out) end end end describe '#extract' do - it 'uses downloads file with compile-extensions' do + it 'downloads file with compile-extensions' do allow(shell).to receive(:exec).and_return(0) expect(shell).to receive(:exec) do |*args| cmd = args.first @@ -63,7 +63,7 @@ expect(cmd).to match(/translate_dependency_url/) expect(cmd).to match(/tar/) end - expect(out).to receive(:print).with(/libuv version/) + expect(out).to receive(:print).with(/gettext version/) subject.extract(dir, out) end end diff --git a/spec/buildpack/detect/detect_spec.rb b/spec/buildpack/detect/detect_spec.rb index 33b4afe50..22e73050c 100644 --- a/spec/buildpack/detect/detect_spec.rb +++ b/spec/buildpack/detect/detect_spec.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,12 +22,22 @@ let(:dir) { Dir.mktmpdir } describe '#detect' do - context 'when no project.json' do + context 'when no project.json and no **.runtimeconfig.json' do it 'returns false' do expect(subject.detect(dir)).to be_falsey end end + context 'when **.runtimeconfig.json exists in root directory' do + before do + File.open(File.join(dir, 'proj1.runtimeconfig.json'), 'w') { |f| f.write('a') } + end + + it 'returns true' do + expect(subject.detect(dir)).to be_truthy + end + end + context 'when project.json exists in root directory' do before do File.open(File.join(dir, 'project.json'), 'w') { |f| f.write('a') } diff --git a/spec/buildpack/release/releaser_spec.rb b/spec/buildpack/release/releaser_spec.rb index 633decd9a..cadb9dd56 100644 --- a/spec/buildpack/release/releaser_spec.rb +++ b/spec/buildpack/release/releaser_spec.rb @@ -1,6 +1,6 @@ # Encoding: utf-8 # ASP.NET 5 Buildpack -# Copyright 2014-2015 the original author or authors. +# Copyright 2014-2016 the original author or authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,9 +24,28 @@ let(:build_dir) { Dir.mktmpdir } describe '#release' do - context 'project.json does not exist' do - it 'raises an error because dnu/dnx commands will not work' do - expect { subject.release(build_dir) }.to raise_error(/No kestrel or web command found/) + context 'project.json does not exist in source code project' do + it 'raises an error because dotnet restore command will not work' do + expect { subject.release(build_dir) }.to raise_error(/No project could be identified to run/) + end + end + + context 'project.json does not exist in published project' do + let(:web_process) do + yml = YAML.load(subject.release(build_dir)) + yml.fetch('default_process_types').fetch('web') + end + + before do + File.open(File.join(build_dir, 'proj1.runtimeconfig.json'), 'w') { |f| f.write('a') } + end + + it 'does not raise an error because project.json is not required' do + expect { subject.release(build_dir) }.not_to raise_error + end + + it 'runs dotnet for the project which has a runtimeconfig.json file' do + expect(web_process).to match('dotnet proj1.dll') end end @@ -55,79 +74,52 @@ end it 'set LD_LIBRARY_PATH in profile.d' do - expect(profile_d_script).to include('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/libuv/lib') + expect(profile_d_script).to include('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/gettext/lib') end - it 'source dnvm.sh script in profile.d' do - expect(profile_d_script).to include('source $HOME/.dnx/dnvm/dnvm.sh') - end - - it 'add DNX to the PATH in profile.d' do - expect(profile_d_script).to include('dnvm use default') + it 'add Dotnet CLI to the PATH in profile.d' do + expect(profile_d_script).to include('$HOME/.dotnet') end it 'start command does not contain any exports' do expect(web_process).not_to include('export') end - it "runs 'dnx kestrel' for project" do - expect(web_process).to match('dnx --project foo kestrel') + it "runs 'dotnet run' for project" do + expect(web_process).to match('dotnet run --project foo') end + end - context 'project.json does not contain a kestrel or web command' do - let(:project_json) { '{"commands": {"notkestrelorweb": "whatever"}}' } + context 'multiple directories contain project.json files but no .deployment file exists' do + let(:proj1) { File.join(build_dir, 'src', 'foo').tap { |f| FileUtils.mkdir_p(f) } } + let(:proj2) { File.join(build_dir, 'src', 'proj2').tap { |f| FileUtils.mkdir_p(f) } } + let(:proj3) { File.join(build_dir, 'src', 'proj3').tap { |f| FileUtils.mkdir_p(f) } } - it 'raises an error because start command will not work' do - expect { subject.release(build_dir) }.to raise_error(/No kestrel or web command found/) + before do + File.open(File.join(proj1, 'project.json'), 'w') do |f| + f.write '{"dependencies": {"dep1": "whatever"}}' end - end - - context 'project.json contains a kestrel command' do - it "runs 'dnx kestrel' for project" do - expect(web_process).to match('dnx --project foo kestrel') + File.open(File.join(proj2, 'project.json'), 'w') do |f| + f.write '{"dependencies": {"dep1": "whatever"}}' end - end - - context 'project.json contains a web command' do - let(:project_json) { '{"commands": {"web": "whatever"}}' } - - it "runs 'dnx web' for project" do - expect(web_process).to match('dnx --project foo web') + File.open(File.join(proj3, 'project.json'), 'w') do |f| + f.write '{"dependencies": {"dep1": "whatever"}}' end end - context 'multiple directories contain project.json files' do - let(:proj2) { File.join(build_dir, 'src', 'proj2').tap { |f| FileUtils.mkdir_p(f) } } - let(:proj3) { File.join(build_dir, 'src', 'proj3').tap { |f| FileUtils.mkdir_p(f) } } - + context '.deployment file exists' do before do - File.open(File.join(proj1, 'project.json'), 'w') do |f| - f.write '{"commands": {"migrate": "whatever"}}' - end - File.open(File.join(proj2, 'project.json'), 'w') do |f| - f.write '{"commands": {"kestrel": "whatever"}}' + File.open(File.join(build_dir, '.deployment'), 'w') do |f| + f.write "[config]\n" + f.write 'project=src/proj2' end - File.open(File.join(proj3, 'project.json'), 'w') do |f| - f.write '{"dependencies": {"dep1": "whatever"}}' - end - end - - it "runs 'dnx kestrel' for project with kestrel command" do - expect(web_process).to match('dnx --project src/proj2 kestrel') end - end - - context 'project.json is in a published app' do - before do - FileUtils.mkdir_p(File.join(build_dir, 'approot', 'packages')) - File.open(File.join(build_dir, 'approot', 'kestrel'), 'w') { |f| f.write 'x' } - File.open(File.join(build_dir, 'approot', 'project.json'), 'w') do |f| - f.write '{"commands": {"kestrel": "whatever"}}' - end + let(:web_process) do + yml = YAML.load(subject.release(build_dir)) + yml.fetch('default_process_types').fetch('web') end - - it 'runs kestrel script' do - expect(web_process).to match('approot/kestrel') + it "runs the project specified in the .deployment file" do + expect(web_process).to match('dotnet run --project src/proj2') end end end