Repository: railwayapp/nixpacks
Pull request #159 (2022-05-31 20:49:58)

Provider assets
This pull request adds static assets support for providers. It uses a new `static_assets` method in `Provider` that returns a `HashMap` with filenames as keys and file contents as values. It puts files into `/assets` in the Docker container, and you can get the path to an asset by calling `app.asset_path(name: &str)`.

See #158


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 98b0a48..dd67e2f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -260,7 +260,7 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
 
 [[package]]
 name = "nixpacks"
-version = "0.0.19"
+version = "0.0.18"
 dependencies = [
  "anyhow",
  "clap",
diff --git a/Cargo.toml b/Cargo.toml
index fcee5fb..8cd9e08 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "nixpacks"
-version = "0.0.19"
+version = "0.0.18"
 edition = "2021"
 license = "MIT"
 authors = ["Railway <contact@railway.app>"]
diff --git a/examples/go-custom-version/go.mod b/examples/go-custom-version/go.mod
deleted file mode 100644
index c7db24b..0000000
--- a/examples/go-custom-version/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module versiontest
-
-go 1.18
diff --git a/examples/go-custom-version/main.go b/examples/go-custom-version/main.go
deleted file mode 100644
index 9774657..0000000
--- a/examples/go-custom-version/main.go
+++ /dev/null
@@ -1,10 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func main() {
-	fmt.Printf("Hello from %s!\n", runtime.Version())
-}
diff --git a/examples/go-mod/go.mod b/examples/go-mod/go.mod
index 4ec7e2e..b63c81c 100644
--- a/examples/go-mod/go.mod
+++ b/examples/go-mod/go.mod
@@ -1,6 +1,6 @@
 module gin
 
-go 1.17
+go 1.14
 
 require (
 	github.com/gin-gonic/gin v1.7.7
diff --git a/examples/python-poetry/main.py b/examples/python-poetry/main.py
deleted file mode 100644
index f765fc2..0000000
--- a/examples/python-poetry/main.py
+++ /dev/null
@@ -1,1 +0,0 @@
-print("Hello from Python-Poetry")
diff --git a/examples/python-poetry/poetry.lock b/examples/python-poetry/poetry.lock
deleted file mode 100644
index 2a84233..0000000
--- a/examples/python-poetry/poetry.lock
+++ /dev/null
@@ -1,287 +0,0 @@
-[[package]]
-name = "atomicwrites"
-version = "1.4.0"
-description = "Atomic file writes."
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "attrs"
-version = "21.4.0"
-description = "Classes Without Boilerplate"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[package.extras]
-dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
-docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
-tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
-tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
-
-[[package]]
-name = "click"
-version = "8.1.3"
-description = "Composable command line interface toolkit"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[[package]]
-name = "colorama"
-version = "0.4.4"
-description = "Cross-platform colored terminal text."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "flask"
-version = "2.1.2"
-description = "A simple framework for building complex web applications."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-click = ">=8.0"
-itsdangerous = ">=2.0"
-Jinja2 = ">=3.0"
-Werkzeug = ">=2.0"
-
-[package.extras]
-async = ["asgiref (>=3.2)"]
-dotenv = ["python-dotenv"]
-
-[[package]]
-name = "itsdangerous"
-version = "2.1.2"
-description = "Safely pass data to untrusted environments and back."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[[package]]
-name = "jinja2"
-version = "3.1.2"
-description = "A very fast and expressive template engine."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "markupsafe"
-version = "2.1.1"
-description = "Safely add untrusted strings to HTML/XML markup."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[[package]]
-name = "more-itertools"
-version = "8.13.0"
-description = "More routines for operating on iterables, beyond itertools"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "packaging"
-version = "21.3"
-description = "Core utilities for Python packages"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
-
-[[package]]
-name = "pluggy"
-version = "0.13.1"
-description = "plugin and hook calling mechanisms for python"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-
-[[package]]
-name = "py"
-version = "1.11.0"
-description = "library with cross-python path, ini-parsing, io, code, log facilities"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "pyparsing"
-version = "3.0.9"
-description = "pyparsing module - Classes and methods to define and execute parsing grammars"
-category = "dev"
-optional = false
-python-versions = ">=3.6.8"
-
-[package.extras]
-diagrams = ["railroad-diagrams", "jinja2"]
-
-[[package]]
-name = "pytest"
-version = "5.4.3"
-description = "pytest: simple powerful testing with Python"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
-attrs = ">=17.4.0"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-more-itertools = ">=4.0.0"
-packaging = "*"
-pluggy = ">=0.12,<1.0"
-py = ">=1.5.0"
-wcwidth = "*"
-
-[package.extras]
-checkqa-mypy = ["mypy (==v0.761)"]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
-
-[[package]]
-name = "wcwidth"
-version = "0.2.5"
-description = "Measures the displayed width of unicode strings in a terminal"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "werkzeug"
-version = "2.1.2"
-description = "The comprehensive WSGI web application library."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-watchdog = ["watchdog"]
-
-[metadata]
-lock-version = "1.1"
-python-versions = "^3.10"
-content-hash = "7af4a2e7efe4e260c66af12870eb8dfb684e7b9c80386bbb1aeb0f3a3f98f848"
-
-[metadata.files]
-atomicwrites = [
-    {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
-    {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
-]
-attrs = [
-    {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
-    {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
-]
-click = [
-    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
-    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
-]
-colorama = [
-    {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
-    {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
-]
-flask = [
-    {file = "Flask-2.1.2-py3-none-any.whl", hash = "sha256:fad5b446feb0d6db6aec0c3184d16a8c1f6c3e464b511649c8918a9be100b4fe"},
-    {file = "Flask-2.1.2.tar.gz", hash = "sha256:315ded2ddf8a6281567edb27393010fe3406188bafbfe65a3339d5787d89e477"},
-]
-itsdangerous = [
-    {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"},
-    {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"},
-]
-jinja2 = [
-    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
-    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
-]
-markupsafe = [
-    {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
-    {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
-]
-more-itertools = [
-    {file = "more-itertools-8.13.0.tar.gz", hash = "sha256:a42901a0a5b169d925f6f217cd5a190e32ef54360905b9c39ee7db5313bfec0f"},
-    {file = "more_itertools-8.13.0-py3-none-any.whl", hash = "sha256:c5122bffc5f104d37c1626b8615b511f3427aa5389b94d61e5ef8236bfbc3ddb"},
-]
-packaging = [
-    {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
-    {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
-]
-pluggy = [
-    {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
-    {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
-]
-py = [
-    {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
-    {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
-]
-pyparsing = [
-    {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
-    {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
-]
-pytest = [
-    {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
-    {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
-]
-wcwidth = [
-    {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
-    {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
-]
-werkzeug = [
-    {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"},
-    {file = "Werkzeug-2.1.2.tar.gz", hash = "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6"},
-]
diff --git a/examples/python-poetry/pyproject.toml b/examples/python-poetry/pyproject.toml
deleted file mode 100644
index 8a7d0b7..0000000
--- a/examples/python-poetry/pyproject.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[tool.poetry]
-name = "python-poetry"
-version = "0.1.0"
-description = ""
-authors = ["wyzlle"]
-
-[tool.poetry.dependencies]
-python = "^3.10"
-Flask = "^2.1.2"
-
-[tool.poetry.dev-dependencies]
-pytest = "^5.2"
-
-[build-system]
-requires = ["poetry-core>=1.0.0"]
-build-backend = "poetry.core.masonry.api"
diff --git a/src/nixpacks/app.rs b/src/nixpacks/app.rs
index 424b81d..2df7a59 100644
--- a/src/nixpacks/app.rs
+++ b/src/nixpacks/app.rs
@@ -1,4 +1,5 @@
 use anyhow::anyhow;
+use std::collections::HashMap;
 use std::path::Path;
 use std::{env, fs, path::PathBuf};
 
@@ -8,6 +9,9 @@ use regex::Regex;
 use serde::de::DeserializeOwned;
 use walkdir::WalkDir;
 
+pub static ASSETS_DIR: &str = "/assets/";
+pub type StaticAssets = HashMap<String, String>;
+
 #[derive(Debug, Clone)]
 pub struct App {
     pub source: PathBuf,
@@ -136,6 +140,11 @@ impl App {
         // Convert path to PathBuf
         Ok(stripped.to_owned())
     }
+
+    /// Get the path in the container to an asset defined in `static_assets`.
+    pub fn asset_path(&self, name: &str) -> String {
+        format!("{ASSETS_DIR}{name}")
+    }
 }
 
 #[cfg(test)]
@@ -251,4 +260,11 @@ mod tests {
         );
         Ok(())
     }
+
+    #[test]
+    fn test_static_asset_path() -> Result<()> {
+        let app = App::new("./examples/npm")?;
+        assert_eq!(&app.asset_path("hi.txt"), "/assets/hi.txt");
+        Ok(())
+    }
 }
diff --git a/src/nixpacks/mod.rs b/src/nixpacks/mod.rs
index fdbe958..92b965d 100644
--- a/src/nixpacks/mod.rs
+++ b/src/nixpacks/mod.rs
@@ -20,7 +20,7 @@ pub mod plan;
 use crate::providers::Provider;
 
 use self::{
-    app::App,
+    app::{App, StaticAssets},
     environment::{Environment, EnvironmentVariables},
     logger::Logger,
     nix::Pkg,
@@ -100,6 +100,9 @@ impl<'a> AppBuilder<'a> {
         let build_phase = self.get_build_phase().context("Generating build phase")?;
         let start_phase = self.get_start_phase().context("Generating start phase")?;
         let variables = self.get_variables().context("Getting plan variables")?;
+        let static_assets = self
+            .get_static_assets()
+            .context("Getting provider assets")?;
 
         let plan = BuildPlan {
             version: Some(NIX_PACKS_VERSION.to_string()),
@@ -108,6 +111,7 @@ impl<'a> AppBuilder<'a> {
             build: Some(build_phase),
             start: Some(start_phase),
             variables: Some(variables),
+            static_assets: Some(static_assets),
         };
 
         Ok(plan)
@@ -340,6 +344,17 @@ impl<'a> AppBuilder<'a> {
         Ok(new_variables)
     }
 
+    fn get_static_assets(&self) -> Result<StaticAssets> {
+        let static_assets = match self.provider {
+            Some(provider) => provider
+                .static_assets(self.app, self.environment)?
+                .unwrap_or_default(),
+            None => StaticAssets::new(),
+        };
+
+        Ok(static_assets)
+    }
+
     fn detect(&mut self, providers: Vec<&'a dyn Provider>) -> Result<()> {
         for provider in providers {
             let matches = provider.detect(self.app, self.environment)?;
@@ -381,6 +396,24 @@ impl<'a> AppBuilder<'a> {
         File::create(dockerfile_path.clone()).context("Creating Dockerfile file")?;
         fs::write(dockerfile_path, dockerfile).context("Writing Dockerfile")?;
 
+        if let Some(assets) = &plan.static_assets {
+            if !assets.is_empty() {
+                let static_assets_path = PathBuf::from(dest).join(PathBuf::from("assets"));
+                fs::create_dir_all(&static_assets_path).context("Creating static assets folder")?;
+
+                for (name, content) in assets {
+                    let path = Path::new(&static_assets_path).join(name);
+                    let parent = path.parent().unwrap();
+                    fs::create_dir_all(parent)
+                        .context(format!("Creating parent directory for {}", name))?;
+                    let mut file =
+                        File::create(path).context(format!("Creating asset file for {name}"))?;
+                    file.write_all(content.as_bytes())
+                        .context(format!("Writing asset {name}"))?;
+                }
+            }
+        }
+
         Ok(())
     }
 
@@ -441,12 +474,14 @@ impl<'a> AppBuilder<'a> {
 
     pub fn gen_dockerfile(plan: &BuildPlan) -> Result<String> {
         let app_dir = "/app/";
+        let assets_dir = app::ASSETS_DIR;
 
         let setup_phase = plan.setup.clone().unwrap_or_default();
         let install_phase = plan.install.clone().unwrap_or_default();
         let build_phase = plan.build.clone().unwrap_or_default();
         let start_phase = plan.start.clone().unwrap_or_default();
         let variables = plan.variables.clone().unwrap_or_default();
+        let static_assets = plan.static_assets.clone().unwrap_or_default();
 
         // -- Variables
         let args_string = if !variables.is_empty() {
@@ -476,6 +511,18 @@ impl<'a> AppBuilder<'a> {
         }
         let setup_copy_cmd = format!("COPY {} {}", setup_files.join(" "), app_dir);
 
+        // -- Static Assets
+        let assets_copy_cmd = if !static_assets.is_empty() {
+            static_assets
+                .clone()
+                .into_keys()
+                .map(|name| format!("COPY assets/{} {}{}", name, assets_dir, name))
+                .collect::<Vec<String>>()
+                .join("\n")
+        } else {
+            "".to_string()
+        };
+
         // -- Install
         let install_cmd = install_phase
             .cmd
@@ -533,7 +580,7 @@ impl<'a> AppBuilder<'a> {
             ",
                     run_image=run_image,
                     app_dir=app_dir,
-                    copy_cmd=get_copy_from_command("0", &start_files.unwrap_or_default(), app_dir)
+                    copy_cmd=get_copy_from_command("0", &start_files.unwrap_or_default(), app_dir, !static_assets.is_empty())
                 }
             }
             None => get_copy_command(
@@ -550,6 +597,7 @@ impl<'a> AppBuilder<'a> {
 
           # Setup
           {setup_copy_cmd}
+          {assets_copy_cmd}
           RUN nix-env -if environment.nix
 
           # Load environment variables
@@ -591,19 +639,39 @@ fn get_copy_command(files: &[String], app_dir: &str) -> String {
     }
 }
 
-fn get_copy_from_command(from: &str, files: &[String], app_dir: &str) -> String {
+fn get_copy_from_command(from: &str, files: &[String], app_dir: &str, has_assets: bool) -> String {
     if files.is_empty() {
-        format!("COPY --from=0 {} {}", app_dir, app_dir)
+        format!(
+            "
+COPY --from=0 {} {}
+RUN true
+{}
+",
+            app_dir,
+            app_dir,
+            if has_assets {
+                "COPY --from=0 /assets /assets"
+            } else {
+                ""
+            }
+        )
     } else {
         format!(
-            "COPY --from={} {} {}",
+            "COPY --from={} {} {}
+            RUN true
+            {}",
             from,
             files
                 .iter()
                 .map(|f| f.replace("./", app_dir))
                 .collect::<Vec<_>>()
                 .join(" "),
-            app_dir
+            app_dir,
+            if has_assets {
+                format!("COPY --from={} /assets /assets", from)
+            } else {
+                "".to_string()
+            }
         )
     }
 }
diff --git a/src/nixpacks/plan.rs b/src/nixpacks/plan.rs
index 7c2734e..c7d857e 100644
--- a/src/nixpacks/plan.rs
+++ b/src/nixpacks/plan.rs
@@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
 use super::{
     environment::EnvironmentVariables,
     phase::{BuildPhase, InstallPhase, SetupPhase, StartPhase},
+    StaticAssets,
 };
 
 #[serde_with::skip_serializing_none]
@@ -15,6 +16,7 @@ pub struct BuildPlan {
     pub build: Option<BuildPhase>,
     pub start: Option<StartPhase>,
     pub variables: Option<EnvironmentVariables>,
+    pub static_assets: Option<StaticAssets>,
 }
 
 impl BuildPlan {
diff --git a/src/providers/go.rs b/src/providers/go.rs
index 5caa611..29bfd44 100644
--- a/src/providers/go.rs
+++ b/src/providers/go.rs
@@ -5,13 +5,11 @@ use crate::nixpacks::{
     nix::Pkg,
     phase::{BuildPhase, InstallPhase, SetupPhase, StartPhase},
 };
-use anyhow::{bail, Result};
+use anyhow::Result;
 
 pub struct GolangProvider {}
 
 pub const BINARY_NAME: &'static &str = &"out";
-const AVAILABLE_GO_VERSIONS: &[(&str, &str)] = &[("1.17", "go"), ("1.18", "go_1_18")];
-pub const DEFAULT_GO_PKG_NAME: &'static &str = &"go";
 
 impl Provider for GolangProvider {
     fn name(&self) -> &str {
@@ -23,10 +21,7 @@ impl Provider for GolangProvider {
     }
 
     fn setup(&self, _app: &App, _env: &Environment) -> Result<Option<SetupPhase>> {
-        let go_mod = self.read_go_mod_if_exists(_app)?;
-        let nix_pkg = GolangProvider::get_nix_golang_pkg(go_mod)?;
-
-        Ok(Some(SetupPhase::new(vec![Pkg::new(&nix_pkg)])))
+        Ok(Some(SetupPhase::new(vec![Pkg::new("go")])))
     }
 
     fn install(&self, app: &App, _env: &Environment) -> Result<Option<InstallPhase>> {
@@ -77,79 +72,3 @@ impl Provider for GolangProvider {
         )])))
     }
 }
-
-impl GolangProvider {
-    pub fn read_go_mod_if_exists(&self, app: &App) -> Result<Option<String>> {
-        if app.includes_file("go.mod") {
-            Ok(Some(app.read_file("go.mod")?))
-        } else {
-            Ok(None)
-        }
-    }
-
-    pub fn get_nix_golang_pkg(go_mod_contents: Option<String>) -> Result<String> {
-        if go_mod_contents.is_some() {
-            let mut lines = go_mod_contents.as_ref().unwrap().lines();
-            let go_version_line = lines.find(|line| line.trim().starts_with("go"));
-
-            if let Some(go_version_line) = go_version_line {
-                let go_version = go_version_line.trim().split_whitespace().nth(1).unwrap();
-
-                if let Some(nix_pkg) = version_number_to_pkg(go_version)? {
-                    return Ok(nix_pkg);
-                }
-            }
-        }
-
-        Ok(DEFAULT_GO_PKG_NAME.to_string())
-    }
-}
-
-fn version_number_to_pkg(version: &str) -> Result<Option<String>> {
-    let matched_version = AVAILABLE_GO_VERSIONS.iter().find(|(v, _)| v == &version);
-
-    match matched_version {
-        Some((_, pkg)) => Ok(Some(pkg.to_string())),
-        None => bail!("Go version {} is not available", version),
-    }
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-
-    #[test]
-    fn test_no_go_mod() -> Result<()> {
-        assert_eq!(
-            GolangProvider::get_nix_golang_pkg(None)?,
-            DEFAULT_GO_PKG_NAME.to_string()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_with_go_mod() -> Result<()> {
-        let go_mod_contents = r#"
-            go 1.18
-        "#;
-
-        assert_eq!(
-            GolangProvider::get_nix_golang_pkg(Some(go_mod_contents.to_string()))?,
-            "go_1_18".to_string()
-        );
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_invalid_version() -> Result<()> {
-        let go_mod_contents = r#"
-            go 1.8
-        "#;
-
-        assert!(GolangProvider::get_nix_golang_pkg(Some(go_mod_contents.to_string())).is_err());
-
-        Ok(())
-    }
-}
diff --git a/src/providers/mod.rs b/src/providers/mod.rs
index 43b49bc..6b2aeec 100644
--- a/src/providers/mod.rs
+++ b/src/providers/mod.rs
@@ -1,5 +1,5 @@
 use crate::nixpacks::{
-    app::App,
+    app::{App, StaticAssets},
     environment::{Environment, EnvironmentVariables},
     phase::{BuildPhase, InstallPhase, SetupPhase, StartPhase},
 };
@@ -28,6 +28,9 @@ pub trait Provider {
     fn start(&self, _app: &App, _env: &Environment) -> Result<Option<StartPhase>> {
         Ok(None)
     }
+    fn static_assets(&self, _app: &App, _env: &Environment) -> Result<Option<StaticAssets>> {
+        Ok(None)
+    }
     fn environment_variables(
         &self,
         _app: &App,
diff --git a/src/providers/python.rs b/src/providers/python.rs
index 93b11b7..dcf0e80 100644
--- a/src/providers/python.rs
+++ b/src/providers/python.rs
@@ -8,7 +8,7 @@ use crate::{
     chain,
     nixpacks::{
         app::App,
-        environment::{Environment, EnvironmentVariables},
+        environment::Environment,
         phase::{InstallPhase, SetupPhase, StartPhase},
     },
     Pkg,
@@ -18,7 +18,6 @@ use super::Provider;
 
 pub const DEFAULT_PYTHON_PKG_NAME: &'static &str = &"python38";
 
-const POETRY_VERSION: &'static &str = &"1.1.13";
 pub struct PythonProvider {}
 
 impl Provider for PythonProvider {
@@ -51,17 +50,6 @@ impl Provider for PythonProvider {
             install_phase.add_path(format!("{}/bin", env_loc));
             return Ok(Some(install_phase));
         } else if app.includes_file("pyproject.toml") {
-            if app.includes_file("poetry.lock") {
-                let install_poetry = "pip install poetry==$NIXPACKS_POETRY_VERSION".to_string();
-                let mut install_phase = InstallPhase::new(format!(
-                    "{} && {} && {} && poetry install --no-dev --no-interaction --no-ansi",
-                    create_env, activate_env, install_poetry
-                ));
-                install_phase.add_file_dependency("poetry.lock".to_string());
-                install_phase.add_file_dependency("pyproject.toml".to_string());
-                install_phase.add_path(format!("{}/bin", env_loc));
-                return Ok(Some(install_phase));
-            }
             let mut install_phase = InstallPhase::new(format!(
                 "{} && {} && pip install --upgrade build setuptools && pip install .",
                 create_env, activate_env
@@ -92,19 +80,6 @@ impl Provider for PythonProvider {
 
         Ok(None)
     }
-    fn environment_variables(
-        &self,
-        app: &App,
-        _env: &Environment,
-    ) -> Result<Option<EnvironmentVariables>> {
-        if app.includes_file("poetry.lock") {
-            return Ok(Some(EnvironmentVariables::from([(
-                "NIXPACKS_POETRY_VERSION".to_string(),
-                POETRY_VERSION.to_string(),
-            )])));
-        }
-        Ok(None)
-    }
 }
 
 #[derive(Debug, Deserialize, Clone)]


Test patch:
diff --git a/tests/docker_run_tests.rs b/tests/docker_run_tests.rs
index 095b453..6fd13e3 100644
--- a/tests/docker_run_tests.rs
+++ b/tests/docker_run_tests.rs
@@ -177,13 +177,6 @@ fn test_python_2() {
     assert!(output.contains("Hello from Python 2"));
 }
 
-#[test]
-fn test_python_poetry() {
-    let name = simple_build("./examples/python-poetry");
-    let output = run_image(name);
-    assert!(output.contains("Hello from Python-Poetry"));
-}
-
 #[test]
 fn test_rust_custom_version() {
     let name = Uuid::new_v4().to_string();
@@ -214,13 +207,6 @@ fn test_go() {
     assert!(output.contains("Hello from Go"));
 }
 
-#[test]
-fn test_go_custom_version() {
-    let name = simple_build("./examples/go-custom-version");
-    let output = run_image(name);
-    assert!(output.contains("Hello from go1.18"));
-}
-
 #[test]
 fn test_haskell_stack() {
     let name = simple_build("./examples/haskell-stack");
diff --git a/tests/generate_plan_tests.rs b/tests/generate_plan_tests.rs
index 364ab12..a13ce91 100644
--- a/tests/generate_plan_tests.rs
+++ b/tests/generate_plan_tests.rs
@@ -218,21 +218,6 @@ fn test_go_mod() -> Result<()> {
     Ok(())
 }
 
-#[test]
-fn test_go_custom_version() -> Result<()> {
-    let plan = gen_plan(
-        "./examples/go-custom-version",
-        Vec::new(),
-        None,
-        None,
-        Vec::new(),
-        false,
-    )?;
-    assert_eq!(plan.setup.unwrap().pkgs, vec![Pkg::new("go_1_18")]);
-
-    Ok(())
-}
-
 #[test]
 fn test_deno() -> Result<()> {
     let plan = gen_plan("./examples/deno", Vec::new(), None, None, Vec::new(), false)?;
@@ -388,26 +373,6 @@ pub fn test_python() -> Result<()> {
     Ok(())
 }
 
-#[test]
-pub fn test_python_poetry() -> Result<()> {
-    let plan = gen_plan(
-        "./examples/python-poetry",
-        Vec::new(),
-        None,
-        None,
-        Vec::new(),
-        true,
-    )?;
-    assert_eq!(plan.build.unwrap().cmd, None);
-    assert_eq!(
-        plan.install.unwrap().cmd,
-        Some("python -m venv /opt/venv && . /opt/venv/bin/activate && pip install poetry==$NIXPACKS_POETRY_VERSION && poetry install --no-dev --no-interaction --no-ansi".to_string())
-    );
-    assert_eq!(plan.start.unwrap().cmd, Some("python main.py".to_string()));
-
-    Ok(())
-}
-
 #[test]
 fn test_node_main_file() -> Result<()> {
     let plan = gen_plan(