Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: default node version to .nvmrc when available, fixes #6071 #6108

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/content/users/extend/customization-extendibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ If you need to create a service configuration for your project, see [Defining Ad
There are many ways to deploy Node.js in any project, so DDEV tries to let you set up any possibility you can come up with.

* You can choose any Node.js version you want (including minor and older versions) in `.ddev/config.yaml` with [`nodejs_version`](../configuration/config.md#nodejs_version).
* If you have a `.nvmrc` file in the root of your project, DDEV will use this as the default node version if you don't include `nodejs_version` in your `config.yaml` file.
* [`ddev nvm`](../usage/commands.md#nvm) gives you the full capabilities of [Node Version Manager](https://github.com/nvm-sh/nvm).
* [`ddev npm`](../usage/commands.md#npm) and [`ddev yarn`](../usage/commands.md#yarn) provide shortcuts to the `npm` and `yarn` commands inside the container, and their caches are persistent.
* You can run Node.js daemons using [`web_extra_daemons`](#running-extra-daemons-in-the-web-container).
Expand Down
2 changes: 2 additions & 0 deletions docs/content/users/usage/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ Type `ddev` or `ddev -h` in a terminal window to see the available DDEV [command

`node`, `nodejs`, `npm`, `nvm` and `yarn` are preinstalled in the web container. You can configure the default value of the installed Node.js version with the [`nodejs_version`](../configuration/config.md#nodejs_version) option in `.ddev/config.yaml` or with `ddev config --nodejs_version`. You can also override that with any value using the built-in `nvm` in the web container or with [`ddev nvm`](../usage/commands.md#nvm), for example `ddev nvm install 6`. There is also a [`ddev yarn`](../usage/commands.md#yarn) command. (Note that since `nodejs_version` configuration can now specify any `node` version, including patch versions, it's preferred to using the less robust `ddev nvm` way of specifying the `node` version.)

If you have a `.nvmrc` file in the root of your project, DDEV will use this as the default node version if you don't include `nodejs_version` in your `config.yaml` file.

## More Bundled Tools

In addition to the [*commands*](../usage/commands.md) listed above, there are lots of tools included inside the containers:
Expand Down
33 changes: 30 additions & 3 deletions pkg/ddevapp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import (
// Regexp pattern to determine if a hostname is valid per RFC 1123.
var hostRegex = regexp.MustCompile(`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$`)

// Default NodeJS version, either from .nvmrc of the constant value defined by DDEV itself.
var nodeJsDefault string

// init() is for testing situations only, allowing us to override the default webserver type
// or caching behavior
func init() {
Expand Down Expand Up @@ -84,7 +87,7 @@ func NewApp(appRoot string, includeOverrides bool) (*DdevApp, error) {
app.Type = nodeps.AppTypeNone
app.PHPVersion = nodeps.PHPDefault
app.ComposerVersion = nodeps.ComposerDefault
app.NodeJSVersion = nodeps.NodeJSDefault
app.NodeJSVersion = app.getNodeJSDefault()
app.WebserverType = nodeps.WebserverDefault
app.SetPerformanceMode(nodeps.PerformanceModeDefault)

Expand Down Expand Up @@ -209,7 +212,7 @@ func (app *DdevApp) WriteConfig() error {
appcopy.DefaultContainerTimeout = ""
}

if appcopy.NodeJSVersion == nodeps.NodeJSDefault {
if appcopy.NodeJSVersion == app.getNodeJSDefault() {
appcopy.NodeJSVersion = ""
}

Expand Down Expand Up @@ -949,7 +952,7 @@ func (app *DdevApp) RenderComposeYAML() (string, error) {

extraWebContent := "\nRUN mkdir -p /home/$username && chown $username /home/$username && chmod 600 /home/$username/.pgpass"
extraWebContent = extraWebContent + "\nENV NVM_DIR=/home/$username/.nvm"
if app.NodeJSVersion != nodeps.NodeJSDefault {
if app.NodeJSVersion != app.getNodeJSDefault() {
extraWebContent = extraWebContent + "\nRUN npm install -g n"
extraWebContent = extraWebContent + fmt.Sprintf("\nRUN n install %s && ln -sf /usr/local/bin/node /usr/local/bin/nodejs", app.NodeJSVersion)
}
Expand Down Expand Up @@ -1443,3 +1446,27 @@ func validateHookYAML(source []byte) error {

return nil
}

func (app *DdevApp) getNodeJSDefault() string {
if nodeJsDefault != "" {
return nodeJsDefault
}
nvmrcPath := filepath.Join(app.GetAppRoot(), ".nvmrc")
if fileutil.FileExists(nvmrcPath) && fileutil.FileIsReadable(nvmrcPath) {
versionRaw, err := fileutil.ReadFileIntoString(nvmrcPath)
if err == nil {
version := strings.TrimSpace(versionRaw)
if ok, err := regexp.MatchString(`^[0-9]+(\.[0-9]+(\.[0-9]+)?)?$`, version); ok && err == nil {
nodeJsDefault = version
return version
}
// emit a warning and fall back to the const default.
util.Warning("Problem getting node version from .nvmrc file, falling back to default.")
} else {
// emit a warning and fall back to the const default.
util.Warning("Error reading .nvmrc file, falling back to default. Error: %v", err)
}
}
nodeJsDefault = nodeps.NodeJSDefault
return nodeps.NodeJSDefault
}
3 changes: 2 additions & 1 deletion pkg/nodeps/values.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package nodeps

import (
"github.com/maruel/natural"
"sort"

"github.com/maruel/natural"

"github.com/ddev/ddev/pkg/config/types"
)

Expand Down