Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: service/datastore/datastore.go

Issue 1574353004: GitHub #8: Seed indexes from index.yml (Closed) Base URL: https://github.com/luci/gae@master
Patch Set: path argument in FindAndParseIndexYAML, add a couple of tests Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | service/datastore/datastore_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 absolute path of the first source filename
381 // ending with `_test.go`. If no test file is found, getCallingTestFilePath
382 // returns a non-nil error.
383 func getCallingTestFilePath(maxStackDepth int) (string, error) {
384 pcs := make([]uintptr, maxStackDepth)
385
386 for _, pc := range pcs[:runtime.Callers(0, pcs)] {
387 path, _ := runtime.FuncForPC(pc - 1).FileLine(pc - 1)
388 if filename := filepath.Base(path); strings.HasSuffix(filename, "_test.go") {
389 return path, nil
390 }
391 }
392
393 return "", fmt.Errorf("datastore: failed to determine source file name")
394 }
395
396 // FindAndParseIndexYAML walks up from the directory specified by path until it
397 // finds a `index.yaml` or `index.yml` file. If an index YAML file
398 // is found, it opens and parses the file, and returns all the indexes found.
399 // If path is a relative path, it is converted into an absolute path
400 // relative to the calling test file. To determine the path of the calling test
401 // file, FindAndParseIndexYAML walks upto a maximum of 100 call stack frames
402 // looking for a file ending with `_test.go`.
403 //
404 // FindAndParseIndexYAML returns a non-nil error if the root of the drive is
405 // reached without finding an index YAML file, if there was
406 // an error reading the found index YAML file, or if the calling test file could
407 // not be located in the case of a relative path argument.
408 func FindAndParseIndexYAML(path string) ([]*IndexDefinition, error) {
409 var currentDir string
410
411 if filepath.IsAbs(path) {
412 currentDir = path
413 } else {
414 testPath, err := getCallingTestFilePath(100)
415 if err != nil {
416 return nil, err
417 }
418 currentDir = filepath.Join(filepath.Dir(testPath), path)
419 }
420
421 isRoot := func(dir string) bool {
422 parentDir := filepath.Dir(dir)
423 return os.IsPathSeparator(dir[len(dir)-1]) && os.IsPathSeparator (parentDir[len(parentDir)-1])
424 }
425
426 for {
427 for _, filename := range []string{"index.yml", "index.yaml"} {
428 file, err := os.Open(filepath.Join(currentDir, filename) )
429 if err == nil {
430 defer file.Close()
431 return ParseIndexYAML(file)
432 }
433 }
434
435 if isRoot(currentDir) {
436 return nil, fmt.Errorf("datastore: failed to find index YAML file")
437 }
438
439 currentDir = filepath.Dir(currentDir)
440 }
441 }
OLDNEW
« no previous file with comments | « no previous file | service/datastore/datastore_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698