github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/core/chaincode/platforms/golang/package.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package golang
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"strings"
    23  
    24  	"os"
    25  	"path/filepath"
    26  
    27  	"github.com/hyperledger/fabric/common/flogging"
    28  	ccutil "github.com/hyperledger/fabric/core/chaincode/platforms/util"
    29  	pb "github.com/hyperledger/fabric/protos/peer"
    30  )
    31  
    32  var includeFileTypes = map[string]bool{
    33  	".c":    true,
    34  	".h":    true,
    35  	".go":   true,
    36  	".yaml": true,
    37  	".json": true,
    38  }
    39  
    40  var logger = flogging.MustGetLogger("golang-platform")
    41  
    42  func getCodeFromFS(path string) (codegopath string, err error) {
    43  	logger.Debugf("getCodeFromFS %s", path)
    44  	gopath, err := getGopath()
    45  	if err != nil {
    46  		return "", err
    47  	}
    48  
    49  	tmppath := filepath.Join(gopath, "src", path)
    50  	if err := ccutil.IsCodeExist(tmppath); err != nil {
    51  		return "", fmt.Errorf("code does not exist %s", err)
    52  	}
    53  
    54  	return gopath, nil
    55  }
    56  
    57  type CodeDescriptor struct {
    58  	Gopath, Pkg string
    59  	Cleanup     func()
    60  }
    61  
    62  // collectChaincodeFiles collects chaincode files. If path is a HTTP(s) url it
    63  // downloads the code first.
    64  //
    65  //NOTE: for dev mode, user builds and runs chaincode manually. The name provided
    66  //by the user is equivalent to the path.
    67  func getCode(spec *pb.ChaincodeSpec) (*CodeDescriptor, error) {
    68  	if spec == nil {
    69  		return nil, errors.New("Cannot collect files from nil spec")
    70  	}
    71  
    72  	chaincodeID := spec.ChaincodeId
    73  	if chaincodeID == nil || chaincodeID.Path == "" {
    74  		return nil, errors.New("Cannot collect files from empty chaincode path")
    75  	}
    76  
    77  	// code root will point to the directory where the code exists
    78  	var gopath string
    79  	gopath, err := getCodeFromFS(chaincodeID.Path)
    80  	if err != nil {
    81  		return nil, fmt.Errorf("Error getting code %s", err)
    82  	}
    83  
    84  	return &CodeDescriptor{Gopath: gopath, Pkg: chaincodeID.Path, Cleanup: nil}, nil
    85  }
    86  
    87  type SourceDescriptor struct {
    88  	Name, Path string
    89  	Info       os.FileInfo
    90  }
    91  type SourceMap map[string]SourceDescriptor
    92  
    93  type Sources []SourceDescriptor
    94  
    95  func (s Sources) Len() int {
    96  	return len(s)
    97  }
    98  
    99  func (s Sources) Swap(i, j int) {
   100  	s[i], s[j] = s[j], s[i]
   101  }
   102  
   103  func (s Sources) Less(i, j int) bool {
   104  	return strings.Compare(s[i].Name, s[j].Name) < 0
   105  }
   106  
   107  func findSource(gopath, pkg string) (SourceMap, error) {
   108  	sources := make(SourceMap)
   109  	tld := filepath.Join(gopath, "src", pkg)
   110  	walkFn := func(path string, info os.FileInfo, err error) error {
   111  
   112  		if err != nil {
   113  			return err
   114  		}
   115  
   116  		if info.IsDir() {
   117  			if path == tld {
   118  				// We dont want to import any directories, but we don't want to stop processing
   119  				// at the TLD either.
   120  				return nil
   121  			}
   122  
   123  			// Do not recurse
   124  			logger.Debugf("skipping dir: %s", path)
   125  			return filepath.SkipDir
   126  		}
   127  
   128  		ext := filepath.Ext(path)
   129  		// we only want 'fileTypes' source files at this point
   130  		if _, ok := includeFileTypes[ext]; ok != true {
   131  			return nil
   132  		}
   133  
   134  		name, err := filepath.Rel(gopath, path)
   135  		if err != nil {
   136  			return fmt.Errorf("error obtaining relative path for %s: %s", path, err)
   137  		}
   138  
   139  		sources[name] = SourceDescriptor{Name: name, Path: path, Info: info}
   140  
   141  		return nil
   142  	}
   143  
   144  	if err := filepath.Walk(tld, walkFn); err != nil {
   145  		return nil, fmt.Errorf("Error walking directory: %s", err)
   146  	}
   147  
   148  	return sources, nil
   149  }