github.com/Xenoex/gopm@v0.6.5/doc/oschina.go (about)

     1  // Copyright 2013 gopm authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"): you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    11  // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    12  // License for the specific language governing permissions and limitations
    13  // under the License.
    14  
    15  package doc
    16  
    17  import (
    18  	"archive/zip"
    19  	"bytes"
    20  	"errors"
    21  	"io"
    22  	"net/http"
    23  	"os"
    24  	"regexp"
    25  	"strings"
    26  
    27  	"github.com/Unknwon/com"
    28  	"github.com/codegangsta/cli"
    29  )
    30  
    31  var (
    32  	oscTagRe   = regexp.MustCompile(`/repository/archive\?ref=(.*)">`)
    33  	oscPattern = regexp.MustCompile(`^git\.oschina\.net/(?P<owner>[a-z0-9A-Z_.\-]+)/(?P<repo>[a-z0-9A-Z_.\-]+)(?P<dir>/[a-z0-9A-Z_.\-/]*)?$`)
    34  )
    35  
    36  // getGithubDoc downloads tarball from git.oschina.com.
    37  func getOSCDoc(client *http.Client, match map[string]string, installRepoPath string, nod *Node, ctx *cli.Context) ([]string, error) {
    38  	// Check downlaod type.
    39  	switch nod.Type {
    40  	case BRANCH:
    41  		if len(nod.Value) == 0 {
    42  			match["sha"] = MASTER
    43  		} else {
    44  			match["sha"] = nod.Value
    45  		}
    46  	case TAG, COMMIT:
    47  		match["sha"] = nod.Value
    48  	default:
    49  		return nil, errors.New("Unknown node type: " + nod.Type)
    50  	}
    51  
    52  	// zip: http://{projectRoot}/repository/archive?ref={sha}
    53  
    54  	// Downlaod archive.
    55  	p, err := com.HttpGetBytes(client, com.Expand("http://git.oschina.net/{owner}/{repo}/repository/archive?ref={sha}", match), nil)
    56  	if err != nil {
    57  		return nil, errors.New("Fail to donwload OSChina repo -> " + err.Error())
    58  	}
    59  
    60  	var installPath string
    61  	if nod.ImportPath == nod.DownloadURL {
    62  		suf := "." + nod.Value
    63  		if len(suf) == 1 {
    64  			suf = ""
    65  		}
    66  		projectPath := com.Expand("git.oschina.net/{owner}/{repo}", match)
    67  		installPath = installRepoPath + "/" + projectPath + suf
    68  		nod.ImportPath = projectPath
    69  	} else {
    70  		installPath = installRepoPath + "/" + nod.ImportPath
    71  	}
    72  
    73  	// Remove old files.
    74  	os.RemoveAll(installPath + "/")
    75  	os.MkdirAll(installPath+"/", os.ModePerm)
    76  
    77  	r, err := zip.NewReader(bytes.NewReader(p), int64(len(p)))
    78  	if err != nil {
    79  		return nil, errors.New("Fail to unzip OSChina repo -> " + err.Error())
    80  	}
    81  
    82  	nameLen := len(match["repo"])
    83  	dirs := make([]string, 0, 5)
    84  	// Need to add root path because we cannot get from tarball.
    85  	dirs = append(dirs, installPath+"/")
    86  	for _, f := range r.File {
    87  		fileName := f.Name[nameLen+1:]
    88  		absPath := installPath + "/" + fileName
    89  
    90  		if strings.HasSuffix(absPath, "/") {
    91  			dirs = append(dirs, absPath)
    92  			os.MkdirAll(absPath, os.ModePerm)
    93  			continue
    94  		}
    95  
    96  		// Get file from archive.
    97  		r, err := f.Open()
    98  		if err != nil {
    99  			return nil, errors.New("Fail to open OSChina repo -> " + err.Error())
   100  		}
   101  
   102  		fbytes := make([]byte, f.FileInfo().Size())
   103  		_, err = io.ReadFull(r, fbytes)
   104  		if err != nil {
   105  			return nil, err
   106  		}
   107  
   108  		if err = com.WriteFile(absPath, fbytes); err != nil {
   109  			return nil, err
   110  		}
   111  	}
   112  
   113  	var imports []string
   114  
   115  	// Check if need to check imports.
   116  	if nod.IsGetDeps {
   117  		for _, d := range dirs {
   118  			importPkgs, err := CheckImports(d, match["importPath"], nod)
   119  			if err != nil {
   120  				return nil, err
   121  			}
   122  			imports = append(imports, importPkgs...)
   123  		}
   124  	}
   125  
   126  	return imports, err
   127  }