Chromium Code Reviews| 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 |