OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package datastore | 5 package datastore |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "io" | |
10 "io/ioutil" | |
11 "os" | |
12 "path/filepath" | |
9 "reflect" | 13 "reflect" |
14 "runtime" | |
15 "strings" | |
10 | 16 |
11 "github.com/luci/luci-go/common/errors" | 17 "github.com/luci/luci-go/common/errors" |
18 | |
19 "gopkg.in/yaml.v2" | |
12 ) | 20 ) |
13 | 21 |
14 type datastoreImpl struct { | 22 type datastoreImpl struct { |
15 RawInterface | 23 RawInterface |
16 | 24 |
17 aid string | 25 aid string |
18 ns string | 26 ns string |
19 } | 27 } |
20 | 28 |
21 var _ Interface = (*datastoreImpl)(nil) | 29 var _ Interface = (*datastoreImpl)(nil) |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 err = lme.Get() | 349 err = lme.Get() |
342 if err == nil { | 350 if err == nil { |
343 err = extErr | 351 err = extErr |
344 } | 352 } |
345 return | 353 return |
346 } | 354 } |
347 | 355 |
348 func (d *datastoreImpl) Raw() RawInterface { | 356 func (d *datastoreImpl) Raw() RawInterface { |
349 return d.RawInterface | 357 return d.RawInterface |
350 } | 358 } |
359 | |
360 // ParseIndexYAML parses the contents of a index YAML file into a list of | |
361 // IndexDefinitions. | |
362 func ParseIndexYAML(content io.Reader) ([]*IndexDefinition, error) { | |
363 serialized, err := ioutil.ReadAll(content) | |
364 if err != nil { | |
365 return nil, err | |
366 } | |
367 | |
368 var m map[string][]*IndexDefinition | |
369 if err := yaml.Unmarshal(serialized, &m); err != nil { | |
370 return nil, err | |
371 } | |
372 | |
373 if _, ok := m["indexes"]; !ok { | |
374 return nil, fmt.Errorf("datastore: missing key `indexes`: %v", m ) | |
375 } | |
376 return m["indexes"], nil | |
377 } | |
378 | |
379 // getCallingTestFilePath looks up the call stack until the specified | |
380 // maxStackDepth and returns the path of the first source filename ending with | |
381 // `_test.go`. If no test file is found, getCallingTestFilePath returns a | |
382 // non-nil error. | |
383 func getCallingTestFilePath(maxStackDepth int) (string, error) { | |
384 pc := make([]uintptr, maxStackDepth) | |
385 n := runtime.Callers(0, pc) | |
iannucci
2016/01/15 04:32:53
try
for _, elem := range pc[:runtime.Callers(0, p
nishanths (utexas)
2016/01/15 06:17:04
Done.
| |
386 | |
387 for i := 0; i < n; i += 1 { | |
388 path, _ := runtime.FuncForPC(pc[i] - 1).FileLine(pc[i] - 1) | |
389 if filename := filepath.Base(path); strings.HasSuffix(filename, "_test.go") { | |
390 return path, nil | |
391 } | |
392 } | |
393 | |
394 return "", fmt.Errorf("datastore: failed to determine source file name") | |
395 } | |
396 | |
397 // FindAndParseIndexYAML walks up from the directory of the calling test file | |
398 // until it finds a `index.yaml` or `index.yml` file. | |
399 // If an index YAML file is found, it opens and parses the file, | |
400 // and returns all the indexes found. | |
401 // | |
402 // FindAndParseIndexYAML returns a non-nil error if the root of the drive is | |
403 // reached without finding an index YAML file, or if there was | |
404 // an error reading the found index YAML file. | |
405 func FindAndParseIndexYAML() ([]*IndexDefinition, error) { | |
406 path, err := getCallingTestFilePath(100) | |
iannucci
2016/01/15 04:32:53
document the 100 element limit in the docstring ab
nishanths (utexas)
2016/01/15 06:17:04
Yep :) Done.
| |
407 if err != nil { | |
408 return nil, err | |
409 } | |
410 | |
411 isRoot := func(currentDir string) bool { | |
412 parentDir := filepath.Dir(currentDir) | |
413 return os.IsPathSeparator(currentDir[len(currentDir)-1]) && os.I sPathSeparator(parentDir[len(parentDir)-1]) | |
414 } | |
415 | |
416 currentDir := filepath.Dir(path) | |
417 | |
418 for { | |
419 for _, filename := range []string{"index.yml", "index.yaml"} { | |
420 file, err := os.Open(filepath.Join(currentDir, filename) ) | |
421 if err == nil { | |
422 defer file.Close() | |
423 return ParseIndexYAML(file) | |
424 } | |
425 } | |
426 | |
427 if isRoot(currentDir) { | |
428 return nil, fmt.Errorf("datastore: failed to find index YAML file") | |
429 } | |
430 | |
431 currentDir = filepath.Dir(currentDir) | |
432 } | |
433 } | |
OLD | NEW |