diff options
author | Radek Simko <radek.simko@gmail.com> | 2017-08-10 14:38:14 +0200 |
---|---|---|
committer | Radek Simko <radek.simko@gmail.com> | 2017-08-10 14:38:14 +0200 |
commit | c680a8e1622ed0f18751d9d167c836ee24f5e897 (patch) | |
tree | 864f925049d422033dd25a73bafce32b361c8827 /vendor/github.com/hashicorp/terraform/helper | |
parent | 38f8880ac81bfabc6d7f82e4dc89661f20fc559e (diff) | |
download | terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.tar.gz terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.tar.zst terraform-provider-statuscake-c680a8e1622ed0f18751d9d167c836ee24f5e897.zip |
vendor: github.com/hashicorp/terraform/...@v0.10.0
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/helper')
8 files changed, 147 insertions, 65 deletions
diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/id.go b/vendor/github.com/hashicorp/terraform/helper/resource/id.go index 629582b..1cde67c 100644 --- a/vendor/github.com/hashicorp/terraform/helper/resource/id.go +++ b/vendor/github.com/hashicorp/terraform/helper/resource/id.go | |||
@@ -1,21 +1,17 @@ | |||
1 | package resource | 1 | package resource |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "crypto/rand" | ||
5 | "fmt" | 4 | "fmt" |
6 | "math/big" | 5 | "strings" |
7 | "sync" | 6 | "sync" |
7 | "time" | ||
8 | ) | 8 | ) |
9 | 9 | ||
10 | const UniqueIdPrefix = `terraform-` | 10 | const UniqueIdPrefix = `terraform-` |
11 | 11 | ||
12 | // idCounter is a randomly seeded monotonic counter for generating ordered | 12 | // idCounter is a monotonic counter for generating ordered unique ids. |
13 | // unique ids. It uses a big.Int so we can easily increment a long numeric | ||
14 | // string. The max possible hex value here with 12 random bytes is | ||
15 | // "01000000000000000000000000", so there's no chance of rollover during | ||
16 | // operation. | ||
17 | var idMutex sync.Mutex | 13 | var idMutex sync.Mutex |
18 | var idCounter = big.NewInt(0).SetBytes(randomBytes(12)) | 14 | var idCounter uint32 |
19 | 15 | ||
20 | // Helper for a resource to generate a unique identifier w/ default prefix | 16 | // Helper for a resource to generate a unique identifier w/ default prefix |
21 | func UniqueId() string { | 17 | func UniqueId() string { |
@@ -25,15 +21,20 @@ func UniqueId() string { | |||
25 | // Helper for a resource to generate a unique identifier w/ given prefix | 21 | // Helper for a resource to generate a unique identifier w/ given prefix |
26 | // | 22 | // |
27 | // After the prefix, the ID consists of an incrementing 26 digit value (to match | 23 | // After the prefix, the ID consists of an incrementing 26 digit value (to match |
28 | // previous timestamp output). | 24 | // previous timestamp output). After the prefix, the ID consists of a timestamp |
25 | // and an incrementing 8 hex digit value The timestamp means that multiple IDs | ||
26 | // created with the same prefix will sort in the order of their creation, even | ||
27 | // across multiple terraform executions, as long as the clock is not turned back | ||
28 | // between calls, and as long as any given terraform execution generates fewer | ||
29 | // than 4 billion IDs. | ||
29 | func PrefixedUniqueId(prefix string) string { | 30 | func PrefixedUniqueId(prefix string) string { |
31 | // Be precise to 4 digits of fractional seconds, but remove the dot before the | ||
32 | // fractional seconds. | ||
33 | timestamp := strings.Replace( | ||
34 | time.Now().UTC().Format("20060102150405.0000"), ".", "", 1) | ||
35 | |||
30 | idMutex.Lock() | 36 | idMutex.Lock() |
31 | defer idMutex.Unlock() | 37 | defer idMutex.Unlock() |
32 | return fmt.Sprintf("%s%026x", prefix, idCounter.Add(idCounter, big.NewInt(1))) | 38 | idCounter++ |
33 | } | 39 | return fmt.Sprintf("%s%s%08x", prefix, timestamp, idCounter) |
34 | |||
35 | func randomBytes(n int) []byte { | ||
36 | b := make([]byte, n) | ||
37 | rand.Read(b) | ||
38 | return b | ||
39 | } | 40 | } |
diff --git a/vendor/github.com/hashicorp/terraform/helper/resource/testing.go b/vendor/github.com/hashicorp/terraform/helper/resource/testing.go index ebdbde2..d7de1a0 100644 --- a/vendor/github.com/hashicorp/terraform/helper/resource/testing.go +++ b/vendor/github.com/hashicorp/terraform/helper/resource/testing.go | |||
@@ -383,11 +383,11 @@ func Test(t TestT, c TestCase) { | |||
383 | c.PreCheck() | 383 | c.PreCheck() |
384 | } | 384 | } |
385 | 385 | ||
386 | ctxProviders, err := testProviderFactories(c) | 386 | providerResolver, err := testProviderResolver(c) |
387 | if err != nil { | 387 | if err != nil { |
388 | t.Fatal(err) | 388 | t.Fatal(err) |
389 | } | 389 | } |
390 | opts := terraform.ContextOpts{Providers: ctxProviders} | 390 | opts := terraform.ContextOpts{ProviderResolver: providerResolver} |
391 | 391 | ||
392 | // A single state variable to track the lifecycle, starting with no state | 392 | // A single state variable to track the lifecycle, starting with no state |
393 | var state *terraform.State | 393 | var state *terraform.State |
@@ -400,15 +400,22 @@ func Test(t TestT, c TestCase) { | |||
400 | var err error | 400 | var err error |
401 | log.Printf("[WARN] Test: Executing step %d", i) | 401 | log.Printf("[WARN] Test: Executing step %d", i) |
402 | 402 | ||
403 | // Determine the test mode to execute | 403 | if step.Config == "" && !step.ImportState { |
404 | if step.Config != "" { | ||
405 | state, err = testStepConfig(opts, state, step) | ||
406 | } else if step.ImportState { | ||
407 | state, err = testStepImportState(opts, state, step) | ||
408 | } else { | ||
409 | err = fmt.Errorf( | 404 | err = fmt.Errorf( |
410 | "unknown test mode for step. Please see TestStep docs\n\n%#v", | 405 | "unknown test mode for step. Please see TestStep docs\n\n%#v", |
411 | step) | 406 | step) |
407 | } else { | ||
408 | if step.ImportState { | ||
409 | if step.Config == "" { | ||
410 | step.Config = testProviderConfig(c) | ||
411 | } | ||
412 | |||
413 | // Can optionally set step.Config in addition to | ||
414 | // step.ImportState, to provide config for the import. | ||
415 | state, err = testStepImportState(opts, state, step) | ||
416 | } else { | ||
417 | state, err = testStepConfig(opts, state, step) | ||
418 | } | ||
412 | } | 419 | } |
413 | 420 | ||
414 | // If there was an error, exit | 421 | // If there was an error, exit |
@@ -496,16 +503,29 @@ func Test(t TestT, c TestCase) { | |||
496 | } | 503 | } |
497 | } | 504 | } |
498 | 505 | ||
499 | // testProviderFactories is a helper to build the ResourceProviderFactory map | 506 | // testProviderConfig takes the list of Providers in a TestCase and returns a |
507 | // config with only empty provider blocks. This is useful for Import, where no | ||
508 | // config is provided, but the providers must be defined. | ||
509 | func testProviderConfig(c TestCase) string { | ||
510 | var lines []string | ||
511 | for p := range c.Providers { | ||
512 | lines = append(lines, fmt.Sprintf("provider %q {}\n", p)) | ||
513 | } | ||
514 | |||
515 | return strings.Join(lines, "") | ||
516 | } | ||
517 | |||
518 | // testProviderResolver is a helper to build a ResourceProviderResolver | ||
500 | // with pre instantiated ResourceProviders, so that we can reset them for the | 519 | // with pre instantiated ResourceProviders, so that we can reset them for the |
501 | // test, while only calling the factory function once. | 520 | // test, while only calling the factory function once. |
502 | // Any errors are stored so that they can be returned by the factory in | 521 | // Any errors are stored so that they can be returned by the factory in |
503 | // terraform to match non-test behavior. | 522 | // terraform to match non-test behavior. |
504 | func testProviderFactories(c TestCase) (map[string]terraform.ResourceProviderFactory, error) { | 523 | func testProviderResolver(c TestCase) (terraform.ResourceProviderResolver, error) { |
505 | ctxProviders := c.ProviderFactories // make(map[string]terraform.ResourceProviderFactory) | 524 | ctxProviders := c.ProviderFactories |
506 | if ctxProviders == nil { | 525 | if ctxProviders == nil { |
507 | ctxProviders = make(map[string]terraform.ResourceProviderFactory) | 526 | ctxProviders = make(map[string]terraform.ResourceProviderFactory) |
508 | } | 527 | } |
528 | |||
509 | // add any fixed providers | 529 | // add any fixed providers |
510 | for k, p := range c.Providers { | 530 | for k, p := range c.Providers { |
511 | ctxProviders[k] = terraform.ResourceProviderFactoryFixed(p) | 531 | ctxProviders[k] = terraform.ResourceProviderFactoryFixed(p) |
@@ -527,7 +547,7 @@ func testProviderFactories(c TestCase) (map[string]terraform.ResourceProviderFac | |||
527 | } | 547 | } |
528 | } | 548 | } |
529 | 549 | ||
530 | return ctxProviders, nil | 550 | return terraform.ResourceProviderResolverFixed(ctxProviders), nil |
531 | } | 551 | } |
532 | 552 | ||
533 | // UnitTest is a helper to force the acceptance testing harness to run in the | 553 | // UnitTest is a helper to force the acceptance testing harness to run in the |
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/provider.go b/vendor/github.com/hashicorp/terraform/helper/schema/provider.go index d52d2f5..fb28b41 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/provider.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/provider.go | |||
@@ -8,6 +8,7 @@ import ( | |||
8 | "sync" | 8 | "sync" |
9 | 9 | ||
10 | "github.com/hashicorp/go-multierror" | 10 | "github.com/hashicorp/go-multierror" |
11 | "github.com/hashicorp/terraform/config" | ||
11 | "github.com/hashicorp/terraform/terraform" | 12 | "github.com/hashicorp/terraform/terraform" |
12 | ) | 13 | ) |
13 | 14 | ||
@@ -89,6 +90,13 @@ func (p *Provider) InternalValidate() error { | |||
89 | validationErrors = multierror.Append(validationErrors, err) | 90 | validationErrors = multierror.Append(validationErrors, err) |
90 | } | 91 | } |
91 | 92 | ||
93 | // Provider-specific checks | ||
94 | for k, _ := range sm { | ||
95 | if isReservedProviderFieldName(k) { | ||
96 | return fmt.Errorf("%s is a reserved field name for a provider", k) | ||
97 | } | ||
98 | } | ||
99 | |||
92 | for k, r := range p.ResourcesMap { | 100 | for k, r := range p.ResourcesMap { |
93 | if err := r.InternalValidate(nil, true); err != nil { | 101 | if err := r.InternalValidate(nil, true); err != nil { |
94 | validationErrors = multierror.Append(validationErrors, fmt.Errorf("resource %s: %s", k, err)) | 102 | validationErrors = multierror.Append(validationErrors, fmt.Errorf("resource %s: %s", k, err)) |
@@ -104,6 +112,15 @@ func (p *Provider) InternalValidate() error { | |||
104 | return validationErrors | 112 | return validationErrors |
105 | } | 113 | } |
106 | 114 | ||
115 | func isReservedProviderFieldName(name string) bool { | ||
116 | for _, reservedName := range config.ReservedProviderFields { | ||
117 | if name == reservedName { | ||
118 | return true | ||
119 | } | ||
120 | } | ||
121 | return false | ||
122 | } | ||
123 | |||
107 | // Meta returns the metadata associated with this provider that was | 124 | // Meta returns the metadata associated with this provider that was |
108 | // returned by the Configure call. It will be nil until Configure is called. | 125 | // returned by the Configure call. It will be nil until Configure is called. |
109 | func (p *Provider) Meta() interface{} { | 126 | func (p *Provider) Meta() interface{} { |
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go b/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go index 856c675..476192e 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/provisioner.go | |||
@@ -43,7 +43,7 @@ type Provisioner struct { | |||
43 | 43 | ||
44 | // ValidateFunc is a function for extended validation. This is optional | 44 | // ValidateFunc is a function for extended validation. This is optional |
45 | // and should be used when individual field validation is not enough. | 45 | // and should be used when individual field validation is not enough. |
46 | ValidateFunc func(*ResourceData) ([]string, []error) | 46 | ValidateFunc func(*terraform.ResourceConfig) ([]string, []error) |
47 | 47 | ||
48 | stopCtx context.Context | 48 | stopCtx context.Context |
49 | stopCtxCancel context.CancelFunc | 49 | stopCtxCancel context.CancelFunc |
@@ -121,32 +121,6 @@ func (p *Provisioner) Stop() error { | |||
121 | return nil | 121 | return nil |
122 | } | 122 | } |
123 | 123 | ||
124 | func (p *Provisioner) Validate(config *terraform.ResourceConfig) ([]string, []error) { | ||
125 | if err := p.InternalValidate(); err != nil { | ||
126 | return nil, []error{fmt.Errorf( | ||
127 | "Internal validation of the provisioner failed! This is always a bug\n"+ | ||
128 | "with the provisioner itself, and not a user issue. Please report\n"+ | ||
129 | "this bug:\n\n%s", err)} | ||
130 | } | ||
131 | w := []string{} | ||
132 | e := []error{} | ||
133 | if p.Schema != nil { | ||
134 | w2, e2 := schemaMap(p.Schema).Validate(config) | ||
135 | w = append(w, w2...) | ||
136 | e = append(e, e2...) | ||
137 | } | ||
138 | if p.ValidateFunc != nil { | ||
139 | data := &ResourceData{ | ||
140 | schema: p.Schema, | ||
141 | config: config, | ||
142 | } | ||
143 | w2, e2 := p.ValidateFunc(data) | ||
144 | w = append(w, w2...) | ||
145 | e = append(e, e2...) | ||
146 | } | ||
147 | return w, e | ||
148 | } | ||
149 | |||
150 | // Apply implementation of terraform.ResourceProvisioner interface. | 124 | // Apply implementation of terraform.ResourceProvisioner interface. |
151 | func (p *Provisioner) Apply( | 125 | func (p *Provisioner) Apply( |
152 | o terraform.UIOutput, | 126 | o terraform.UIOutput, |
@@ -204,3 +178,27 @@ func (p *Provisioner) Apply( | |||
204 | ctx = context.WithValue(ctx, ProvRawStateKey, s) | 178 | ctx = context.WithValue(ctx, ProvRawStateKey, s) |
205 | return p.ApplyFunc(ctx) | 179 | return p.ApplyFunc(ctx) |
206 | } | 180 | } |
181 | |||
182 | // Validate implements the terraform.ResourceProvisioner interface. | ||
183 | func (p *Provisioner) Validate(c *terraform.ResourceConfig) (ws []string, es []error) { | ||
184 | if err := p.InternalValidate(); err != nil { | ||
185 | return nil, []error{fmt.Errorf( | ||
186 | "Internal validation of the provisioner failed! This is always a bug\n"+ | ||
187 | "with the provisioner itself, and not a user issue. Please report\n"+ | ||
188 | "this bug:\n\n%s", err)} | ||
189 | } | ||
190 | |||
191 | if p.Schema != nil { | ||
192 | w, e := schemaMap(p.Schema).Validate(c) | ||
193 | ws = append(ws, w...) | ||
194 | es = append(es, e...) | ||
195 | } | ||
196 | |||
197 | if p.ValidateFunc != nil { | ||
198 | w, e := p.ValidateFunc(c) | ||
199 | ws = append(ws, w...) | ||
200 | es = append(es, e...) | ||
201 | } | ||
202 | |||
203 | return ws, es | ||
204 | } | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/resource.go b/vendor/github.com/hashicorp/terraform/helper/schema/resource.go index c810558..ddba109 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/resource.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/resource.go | |||
@@ -6,6 +6,7 @@ import ( | |||
6 | "log" | 6 | "log" |
7 | "strconv" | 7 | "strconv" |
8 | 8 | ||
9 | "github.com/hashicorp/terraform/config" | ||
9 | "github.com/hashicorp/terraform/terraform" | 10 | "github.com/hashicorp/terraform/terraform" |
10 | ) | 11 | ) |
11 | 12 | ||
@@ -142,6 +143,12 @@ func (r *Resource) Apply( | |||
142 | if err := rt.DiffDecode(d); err != nil { | 143 | if err := rt.DiffDecode(d); err != nil { |
143 | log.Printf("[ERR] Error decoding ResourceTimeout: %s", err) | 144 | log.Printf("[ERR] Error decoding ResourceTimeout: %s", err) |
144 | } | 145 | } |
146 | } else if s != nil { | ||
147 | if _, ok := s.Meta[TimeoutKey]; ok { | ||
148 | if err := rt.StateDecode(s); err != nil { | ||
149 | log.Printf("[ERR] Error decoding ResourceTimeout: %s", err) | ||
150 | } | ||
151 | } | ||
145 | } else { | 152 | } else { |
146 | log.Printf("[DEBUG] No meta timeoutkey found in Apply()") | 153 | log.Printf("[DEBUG] No meta timeoutkey found in Apply()") |
147 | } | 154 | } |
@@ -388,9 +395,25 @@ func (r *Resource) InternalValidate(topSchemaMap schemaMap, writable bool) error | |||
388 | } | 395 | } |
389 | } | 396 | } |
390 | 397 | ||
398 | // Resource-specific checks | ||
399 | for k, _ := range tsm { | ||
400 | if isReservedResourceFieldName(k) { | ||
401 | return fmt.Errorf("%s is a reserved field name for a resource", k) | ||
402 | } | ||
403 | } | ||
404 | |||
391 | return schemaMap(r.Schema).InternalValidate(tsm) | 405 | return schemaMap(r.Schema).InternalValidate(tsm) |
392 | } | 406 | } |
393 | 407 | ||
408 | func isReservedResourceFieldName(name string) bool { | ||
409 | for _, reservedName := range config.ReservedResourceFields { | ||
410 | if name == reservedName { | ||
411 | return true | ||
412 | } | ||
413 | } | ||
414 | return false | ||
415 | } | ||
416 | |||
394 | // Data returns a ResourceData struct for this Resource. Each return value | 417 | // Data returns a ResourceData struct for this Resource. Each return value |
395 | // is a separate copy and can be safely modified differently. | 418 | // is a separate copy and can be safely modified differently. |
396 | // | 419 | // |
diff --git a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go index 632672a..acb5618 100644 --- a/vendor/github.com/hashicorp/terraform/helper/schema/schema.go +++ b/vendor/github.com/hashicorp/terraform/helper/schema/schema.go | |||
@@ -15,6 +15,7 @@ import ( | |||
15 | "fmt" | 15 | "fmt" |
16 | "os" | 16 | "os" |
17 | "reflect" | 17 | "reflect" |
18 | "regexp" | ||
18 | "sort" | 19 | "sort" |
19 | "strconv" | 20 | "strconv" |
20 | "strings" | 21 | "strings" |
@@ -661,7 +662,13 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error { | |||
661 | if v.ValidateFunc != nil { | 662 | if v.ValidateFunc != nil { |
662 | switch v.Type { | 663 | switch v.Type { |
663 | case TypeList, TypeSet: | 664 | case TypeList, TypeSet: |
664 | return fmt.Errorf("ValidateFunc is not yet supported on lists or sets.") | 665 | return fmt.Errorf("%s: ValidateFunc is not yet supported on lists or sets.", k) |
666 | } | ||
667 | } | ||
668 | |||
669 | if v.Deprecated == "" && v.Removed == "" { | ||
670 | if !isValidFieldName(k) { | ||
671 | return fmt.Errorf("%s: Field name may only contain lowercase alphanumeric characters & underscores.", k) | ||
665 | } | 672 | } |
666 | } | 673 | } |
667 | } | 674 | } |
@@ -669,6 +676,11 @@ func (m schemaMap) InternalValidate(topSchemaMap schemaMap) error { | |||
669 | return nil | 676 | return nil |
670 | } | 677 | } |
671 | 678 | ||
679 | func isValidFieldName(name string) bool { | ||
680 | re := regexp.MustCompile("^[a-z0-9_]+$") | ||
681 | return re.MatchString(name) | ||
682 | } | ||
683 | |||
672 | func (m schemaMap) diff( | 684 | func (m schemaMap) diff( |
673 | k string, | 685 | k string, |
674 | schema *Schema, | 686 | schema *Schema, |
diff --git a/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go b/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go index 7edd5e7..edc1e2a 100644 --- a/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go +++ b/vendor/github.com/hashicorp/terraform/helper/shadow/closer.go | |||
@@ -39,6 +39,8 @@ func (w *closeWalker) Struct(reflect.Value) error { | |||
39 | return nil | 39 | return nil |
40 | } | 40 | } |
41 | 41 | ||
42 | var closerType = reflect.TypeOf((*io.Closer)(nil)).Elem() | ||
43 | |||
42 | func (w *closeWalker) StructField(f reflect.StructField, v reflect.Value) error { | 44 | func (w *closeWalker) StructField(f reflect.StructField, v reflect.Value) error { |
43 | // Not sure why this would be but lets avoid some panics | 45 | // Not sure why this would be but lets avoid some panics |
44 | if !v.IsValid() { | 46 | if !v.IsValid() { |
@@ -56,17 +58,18 @@ func (w *closeWalker) StructField(f reflect.StructField, v reflect.Value) error | |||
56 | return nil | 58 | return nil |
57 | } | 59 | } |
58 | 60 | ||
59 | // We're looking for an io.Closer | 61 | var closer io.Closer |
60 | raw := v.Interface() | 62 | if v.Type().Implements(closerType) { |
61 | if raw == nil { | 63 | closer = v.Interface().(io.Closer) |
62 | return nil | 64 | } else if v.CanAddr() { |
65 | // The Close method may require a pointer receiver, but we only have a value. | ||
66 | v := v.Addr() | ||
67 | if v.Type().Implements(closerType) { | ||
68 | closer = v.Interface().(io.Closer) | ||
69 | } | ||
63 | } | 70 | } |
64 | 71 | ||
65 | closer, ok := raw.(io.Closer) | 72 | if closer == nil { |
66 | if !ok && v.CanAddr() { | ||
67 | closer, ok = v.Addr().Interface().(io.Closer) | ||
68 | } | ||
69 | if !ok { | ||
70 | return reflectwalk.SkipEntry | 73 | return reflectwalk.SkipEntry |
71 | } | 74 | } |
72 | 75 | ||
diff --git a/vendor/github.com/hashicorp/terraform/helper/shadow/value.go b/vendor/github.com/hashicorp/terraform/helper/shadow/value.go index 2413335..178b7e7 100644 --- a/vendor/github.com/hashicorp/terraform/helper/shadow/value.go +++ b/vendor/github.com/hashicorp/terraform/helper/shadow/value.go | |||
@@ -26,6 +26,14 @@ type Value struct { | |||
26 | valueSet bool | 26 | valueSet bool |
27 | } | 27 | } |
28 | 28 | ||
29 | func (v *Value) Lock() { | ||
30 | v.lock.Lock() | ||
31 | } | ||
32 | |||
33 | func (v *Value) Unlock() { | ||
34 | v.lock.Unlock() | ||
35 | } | ||
36 | |||
29 | // Close closes the value. This can never fail. For a definition of | 37 | // Close closes the value. This can never fail. For a definition of |
30 | // "close" see the struct docs. | 38 | // "close" see the struct docs. |
31 | func (w *Value) Close() error { | 39 | func (w *Value) Close() error { |