github.com/hwaf/hwaf@v0.0.0-20140814122253-5465f73b20f1/cmd_bdist_deb.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  	"runtime"
    11  	"strings"
    12  	"text/template"
    13  	"time"
    14  
    15  	"github.com/gonuts/commander"
    16  	"github.com/gonuts/flag"
    17  )
    18  
    19  func hwaf_make_cmd_waf_bdist_deb() *commander.Command {
    20  	cmd := &commander.Command{
    21  		Run:       hwaf_run_cmd_waf_bdist_deb,
    22  		UsageLine: "bdist-deb [deb-name]",
    23  		Short:     "create a DEB from the local project/packages",
    24  		Long: `
    25  bdist-deb creates a DEB from the local project/packages.
    26  
    27  ex:
    28   $ hwaf bdist-deb
    29   $ hwaf bdist-deb -name=mana
    30   $ hwaf bdist-deb -name=mana -version=20130101
    31  `,
    32  		Flag: *flag.NewFlagSet("hwaf-bdist-deb", flag.ExitOnError),
    33  	}
    34  	cmd.Flag.Bool("v", false, "enable verbose output")
    35  	cmd.Flag.String("name", "", "name of the binary distribution (default: project name)")
    36  	cmd.Flag.String("version", "", "version of the binary distribution (default: project version)")
    37  	cmd.Flag.String("release", "1", "release version of the binary distribution (default: 1)")
    38  	cmd.Flag.String("variant", "", "HWAF_VARIANT quadruplet for the binary distribution (default: project variant)")
    39  	cmd.Flag.String("spec", "", "DEB control file for the binary distribution")
    40  	cmd.Flag.String("url", "", "URL for the DEB binary distribution")
    41  	return cmd
    42  }
    43  
    44  func hwaf_run_cmd_waf_bdist_deb(cmd *commander.Command, args []string) error {
    45  	var err error
    46  	n := "hwaf-" + cmd.Name()
    47  
    48  	switch len(args) {
    49  	case 0:
    50  	default:
    51  		return fmt.Errorf("%s: too many arguments (%s)", n, len(args))
    52  	}
    53  
    54  	verbose := cmd.Flag.Lookup("v").Value.Get().(bool)
    55  
    56  	bdist_name := cmd.Flag.Lookup("name").Value.Get().(string)
    57  	bdist_vers := cmd.Flag.Lookup("version").Value.Get().(string)
    58  	bdist_release := cmd.Flag.Lookup("release").Value.Get().(string)
    59  	bdist_variant := cmd.Flag.Lookup("variant").Value.Get().(string)
    60  	bdist_spec := cmd.Flag.Lookup("spec").Value.Get().(string)
    61  
    62  	bdist_url := cmd.Flag.Lookup("url").Value.Get().(string)
    63  	if bdist_url == "" {
    64  		bdist_url = "http://cern.ch/mana-fwk"
    65  	}
    66  
    67  	type DebInfo struct {
    68  		Name      string // DEB package name
    69  		Vers      string // DEB package version
    70  		Release   string // DEB package release
    71  		Variant   string // DEB VARIANT quadruplet
    72  		BuildRoot string // DEB build directory
    73  		Url       string // URL home page
    74  		Arch      string // DEB architecture (32b/64b)
    75  	}
    76  
    77  	workdir, err := g_ctx.Workarea()
    78  	if err != nil {
    79  		// not a git repo... assume we are at the root, then...
    80  		workdir, err = os.Getwd()
    81  	}
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	if bdist_name == "" {
    87  		bdist_name = workdir
    88  		bdist_name = filepath.Base(bdist_name)
    89  	}
    90  	if bdist_vers == "" {
    91  		bdist_vers = time.Now().Format("20060102")
    92  	}
    93  	if bdist_variant == "" {
    94  		pinfo, err := g_ctx.ProjectInfos()
    95  		if err != nil {
    96  			return err
    97  		}
    98  		bdist_variant, err = pinfo.Get("HWAF_VARIANT")
    99  		if err != nil {
   100  			return err
   101  		}
   102  	}
   103  	fname := bdist_name + "-" + bdist_vers + "-" + bdist_variant
   104  	debtopdir, err := ioutil.TempDir("", "hwaf-deb-buildroot-")
   105  	if err != nil {
   106  		return err
   107  	}
   108  	defer os.RemoveAll(debtopdir)
   109  
   110  	debbldroot := filepath.Join(debtopdir, "debian")
   111  	err = os.MkdirAll(debbldroot, 0755)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	for _, dir := range []string{
   117  		"DEBIAN",
   118  	} {
   119  		err = os.MkdirAll(filepath.Join(debbldroot, dir), 0755)
   120  		if err != nil {
   121  			return err
   122  		}
   123  	}
   124  
   125  	specfile, err := os.Create(filepath.Join(debbldroot, "DEBIAN", "control"))
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	debarch := ""
   131  	switch runtime.GOARCH {
   132  	case "amd64":
   133  		debarch = "amd64"
   134  	case "386":
   135  		debarch = "i386"
   136  	default:
   137  		return fmt.Errorf("unhandled GOARCH [%s]", runtime.GOARCH)
   138  	}
   139  
   140  	debinfos := DebInfo{
   141  		Name:      bdist_name,
   142  		Vers:      bdist_vers,
   143  		Release:   bdist_release,
   144  		Variant:   bdist_variant,
   145  		BuildRoot: debbldroot,
   146  		Url:       bdist_url,
   147  		Arch:      debarch,
   148  	}
   149  
   150  	// get tarball from 'hwaf bdist'...
   151  	bdist_fname := strings.Replace(fname, ".deb", "", 1) + ".tar.gz"
   152  	if !path_exists(bdist_fname) {
   153  		err = fmt.Errorf("no such file [%s]. did you run \"hwaf bdist\" ?", bdist_fname)
   154  		if err != nil {
   155  			return err
   156  		}
   157  	}
   158  	bdist_fname, err = filepath.Abs(bdist_fname)
   159  	if err != nil {
   160  		return err
   161  	}
   162  	{
   163  		untar := exec.Command("tar", "-zxf", bdist_fname, "--strip", "1")
   164  		untar.Dir = debbldroot
   165  		untar.Stdin = os.Stdin
   166  		untar.Stdout = os.Stdout
   167  		untar.Stderr = os.Stderr
   168  		err = untar.Run()
   169  		if err != nil {
   170  			return err
   171  		}
   172  	}
   173  
   174  	if bdist_spec != "" {
   175  		bdist_spec = os.ExpandEnv(bdist_spec)
   176  		bdist_spec, err = filepath.Abs(bdist_spec)
   177  		if err != nil {
   178  			return err
   179  		}
   180  
   181  		if !path_exists(bdist_spec) {
   182  			err = fmt.Errorf("no such file [%s]", bdist_spec)
   183  			if err != nil {
   184  				return err
   185  			}
   186  		}
   187  		user_spec, err := os.Open(bdist_spec)
   188  		if err != nil {
   189  			return err
   190  		}
   191  		defer user_spec.Close()
   192  
   193  		_, err = io.Copy(specfile, user_spec)
   194  		if err != nil {
   195  			return err
   196  		}
   197  	} else {
   198  		bdist_spec = specfile.Name()
   199  
   200  		var spec_tmpl *template.Template
   201  		spec_tmpl, err = template.New("SPEC").Parse(`
   202  Package: {{.Name}}
   203  Version: {{.Vers}}-{{.Release}}
   204  Section: devel
   205  Priority: optional
   206  Architecture: {{.Arch}}
   207  Depends: coreutils
   208  Maintainer: hwaf
   209  Description: hwaf generated DEB for {{.Name}}
   210  `) // */ for emacs...
   211  		if err != nil {
   212  			return err
   213  		}
   214  
   215  		err = spec_tmpl.Execute(specfile, debinfos)
   216  		if err != nil {
   217  			return err
   218  		}
   219  	}
   220  
   221  	err = specfile.Sync()
   222  	if err != nil {
   223  		return err
   224  	}
   225  	err = specfile.Close()
   226  	if err != nil {
   227  		return err
   228  	}
   229  
   230  	if !strings.HasSuffix(fname, ".deb") {
   231  		fname = fname + ".deb"
   232  	}
   233  
   234  	if verbose {
   235  		fmt.Printf("%s: building DEB [%s]...\n", n, fname)
   236  	}
   237  
   238  	debbld, err := exec.LookPath("dpkg-deb")
   239  	if err != nil {
   240  		return err
   241  	}
   242  	//dpkg-deb --build debian
   243  	deb := exec.Command(debbld,
   244  		"--build",
   245  		"debian",
   246  	)
   247  	deb.Dir = debtopdir
   248  	if verbose {
   249  		deb.Stdin = os.Stdin
   250  		deb.Stdout = os.Stdout
   251  		deb.Stderr = os.Stderr
   252  	}
   253  	err = deb.Run()
   254  	if err != nil {
   255  		return err
   256  	}
   257  
   258  	dst, err := os.Create(fname)
   259  	if err != nil {
   260  		return err
   261  	}
   262  	defer dst.Close()
   263  
   264  	src, err := os.Open(filepath.Join(debtopdir, "debian.deb"))
   265  	if err != nil {
   266  		return err
   267  	}
   268  	defer src.Close()
   269  
   270  	_, err = io.Copy(dst, src)
   271  	if err != nil {
   272  		return err
   273  	}
   274  	err = dst.Sync()
   275  	if err != nil {
   276  		return err
   277  	}
   278  
   279  	if verbose {
   280  		fmt.Printf("%s: building DEB [%s]...[ok]\n", n, fname)
   281  	}
   282  
   283  	return nil
   284  }
   285  
   286  // EOF