2018-05-22 21:43:36 +02:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// 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.
|
2017-04-12 20:12:25 +02:00
|
|
|
|
|
|
|
package cmdutil
|
|
|
|
|
|
|
|
import (
|
2017-10-05 23:08:46 +02:00
|
|
|
"os"
|
|
|
|
|
2018-10-05 01:20:01 +02:00
|
|
|
"github.com/pkg/errors"
|
2017-09-22 04:18:21 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/diag"
|
2017-12-18 20:42:32 +01:00
|
|
|
"github.com/pulumi/pulumi/pkg/diag/colors"
|
2017-09-22 04:18:21 +02:00
|
|
|
"github.com/pulumi/pulumi/pkg/util/contract"
|
2017-04-12 20:12:25 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
var snk diag.Sink
|
|
|
|
|
2018-10-05 01:20:01 +02:00
|
|
|
// By default we'll attempt to figure out if we should have colors or not. This can be overridden
|
|
|
|
// for any command by passing --color=... at the command line.
|
|
|
|
var globalColorization = colors.Auto
|
2018-07-07 06:30:00 +02:00
|
|
|
|
|
|
|
// GetGlobalColorization gets the global setting for how things should be colored.
|
|
|
|
// This is helpful for the parts of our stack that do not take a DisplayOptions struct.
|
|
|
|
func GetGlobalColorization() colors.Colorization {
|
2018-10-05 01:20:01 +02:00
|
|
|
if globalColorization != colors.Auto {
|
|
|
|
// User has set an explicit colorization preference. We'll respect whatever they asked for,
|
|
|
|
// no matter what.
|
|
|
|
return globalColorization
|
|
|
|
}
|
|
|
|
|
|
|
|
// Colorization is set to 'auto' (either explicit set to that by the user, or not set at all).
|
|
|
|
// Figure out the best thing to do here.
|
|
|
|
|
|
|
|
// If the external environment has requested no colors, then turn off all colors when in 'auto' mode.
|
2018-07-07 06:30:00 +02:00
|
|
|
if _, ok := os.LookupEnv("NO_COLOR"); ok {
|
|
|
|
return colors.Never
|
|
|
|
}
|
|
|
|
|
2018-10-05 01:20:01 +02:00
|
|
|
// Disable colors if we're not in an interactive session (i.e. we're redirecting stdout). This
|
|
|
|
// will just inject color tags into the stream which are not desirable here.
|
|
|
|
if !InteractiveTerminal() {
|
2018-09-05 09:31:15 +02:00
|
|
|
return colors.Never
|
|
|
|
}
|
|
|
|
|
2018-10-05 01:20:01 +02:00
|
|
|
// Things otherwise look good. Turn on colors.
|
|
|
|
return colors.Always
|
2018-07-07 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetGlobalColorization sets the global setting for how things should be colored.
|
|
|
|
// This is helpful for the parts of our stack that do not take a DisplayOptions struct.
|
2018-10-05 01:20:01 +02:00
|
|
|
func SetGlobalColorization(value string) error {
|
|
|
|
switch value {
|
|
|
|
case "auto":
|
|
|
|
globalColorization = colors.Auto
|
|
|
|
case "always":
|
|
|
|
globalColorization = colors.Always
|
|
|
|
case "never":
|
|
|
|
globalColorization = colors.Never
|
|
|
|
case "raw":
|
|
|
|
globalColorization = colors.Raw
|
|
|
|
default:
|
|
|
|
return errors.Errorf("unsupported color option: '%s'. Supported values are: auto, always, never, raw", value)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2018-07-07 06:30:00 +02:00
|
|
|
}
|
|
|
|
|
Make more progress on the new deployment model
This change restructures a lot more pertaining to deployments, snapshots,
environments, and the like.
The most notable change is that the notion of a deploy.Source is introduced,
which splits the responsibility between the deploy.Plan -- which simply
understands how to compute and carry out deployment plans -- and the idea
of something that can produce new objects on-demand during deployment.
The primary such implementation is evalSource, which encapsulates an
interpreter and takes a package, args, and config map, and proceeds to run
the interpreter in a distinct goroutine. It synchronizes as needed to
poke and prod the interpreter along its path to create new resource objects.
There are two other sources, however. First, a nullSource, which simply
refuses to create new objects. This can be handy when writing isolated
tests but is also used to simulate the "empty" environment as necessary to
do a complete teardown of the target environment. Second, a fixedSource,
which takes a pre-computed array of objects, and hands those, in order, to
the planning engine; this is mostly useful as a testing technique.
Boatloads of code is now changed and updated in the various CLI commands.
This further chugs along towards pulumi/lumi#90. The end is in sight.
2017-06-10 20:50:47 +02:00
|
|
|
// Diag lazily allocates a sink to be used if we can't create a compiler.
|
|
|
|
func Diag() diag.Sink {
|
2017-04-12 20:12:25 +02:00
|
|
|
if snk == nil {
|
2017-10-05 23:08:46 +02:00
|
|
|
snk = diag.DefaultSink(os.Stdout, os.Stderr, diag.FormatOptions{
|
2018-07-07 06:30:00 +02:00
|
|
|
Color: GetGlobalColorization(),
|
2017-08-30 03:24:12 +02:00
|
|
|
})
|
2017-04-12 20:12:25 +02:00
|
|
|
}
|
|
|
|
return snk
|
|
|
|
}
|
2017-07-14 02:09:46 +02:00
|
|
|
|
|
|
|
// InitDiag forces initialization of the diagnostics sink with the given options.
|
|
|
|
func InitDiag(opts diag.FormatOptions) {
|
|
|
|
contract.Assertf(snk == nil, "Cannot initialize diagnostics sink more than once")
|
2017-10-05 23:08:46 +02:00
|
|
|
snk = diag.DefaultSink(os.Stdout, os.Stderr, opts)
|
2017-07-14 02:09:46 +02:00
|
|
|
}
|