Skip to content

Commit 3cabf78

Browse files
author
Christian Weichel
committed
Config changes, improved version computation and build area synthesis
- typescript packages: library config field is replaced with "packaging" - go packages: library config field is replaced with "packaging" Thanks @AlexTugarev for the suggestion - packages no longer depend on the whole build file but just their own config - safer naming convention for linked dependencies in the build area
1 parent 09d4542 commit 3cabf78

File tree

4 files changed

+152
-40
lines changed

4 files changed

+152
-40
lines changed

cmd/build.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cmd
33
import (
44
"io/ioutil"
55
"os"
6+
"path/filepath"
67

78
log "github.com/sirupsen/logrus"
89
"github.com/spf13/cobra"
@@ -51,7 +52,7 @@ var buildCmd = &cobra.Command{
5152
} else {
5253
localCacheLoc = os.Getenv(leeway.EnvvarCacheDir)
5354
if localCacheLoc == "" {
54-
localCacheLoc = os.TempDir()
55+
localCacheLoc = filepath.Join(os.TempDir(), "cache")
5556
}
5657
}
5758
log.WithField("location", localCacheLoc).Debug("set up local cache")

go.sum

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
6363
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
6464
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
6565
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
66-
github.com/typefox/gitpod v0.4.11 h1:x2OXJfgezSy6FEi3zd590kSM6W8JQoczpTeRO822d/c=
6766
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
6867
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
6968
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=

pkg/leeway/build.go

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -305,13 +305,7 @@ func (p *Package) build(buildctx *buildContext) (err error) {
305305
log.WithField("package", p.FullName()).WithField("version", version).Info("build succeded")
306306
}()
307307

308-
pkgdir := p.FullName()
309-
pkgdir = strings.Replace(pkgdir, "/", "-", -1)
310-
pkgdir = strings.Replace(pkgdir, ":", "--", -1)
311-
pkgdir = pkgdir + "." + version
312-
// components in the workspace root would otherwise start with -- which breaks a lot of shell commands
313-
pkgdir = strings.TrimPrefix(pkgdir, "--")
314-
308+
pkgdir := p.FilesystemSafeName() + "." + version
315309
builddir := filepath.Join(buildctx.BuildDir(), pkgdir)
316310
if _, err := os.Stat(builddir); !os.IsNotExist(err) {
317311
err := os.RemoveAll(builddir)
@@ -324,14 +318,16 @@ func (p *Package) build(buildctx *buildContext) (err error) {
324318
return err
325319
}
326320

327-
cpargs := []string{"--parents"}
328-
for _, src := range p.Sources {
329-
cpargs = append(cpargs, strings.TrimPrefix(src, p.C.Origin+"/"))
330-
}
331-
cpargs = append(cpargs, builddir)
332-
err = run(getRunPrefix(p), nil, p.C.Origin, "cp", cpargs...)
333-
if err != nil {
334-
return err
321+
if len(p.Sources) > 0 {
322+
cpargs := []string{"--parents"}
323+
for _, src := range p.Sources {
324+
cpargs = append(cpargs, strings.TrimPrefix(src, p.C.Origin+"/"))
325+
}
326+
cpargs = append(cpargs, builddir)
327+
err = run(getRunPrefix(p), nil, p.C.Origin, "cp", cpargs...)
328+
if err != nil {
329+
return err
330+
}
335331
}
336332

337333
result, _ := buildctx.LocalCache.Location(p)
@@ -386,31 +382,44 @@ func (p *Package) buildTypescript(buildctx *buildContext, wd, result string) (er
386382
commands = append(commands, []string{"cp", filepath.Join(p.C.Origin, cfg.TSConfig), "."})
387383
}
388384

385+
if cfg.Packaging == TypescriptOfflineMirror {
386+
commands = append(commands, [][]string{
387+
{"mkdir", "_mirror"},
388+
{"sh", "-c", "echo yarn-offline-mirror \"./_mirror\" > .yarnrc"},
389+
}...)
390+
}
391+
389392
pkgYarnLock := "pkg-yarn.lock"
390393
for _, deppkg := range p.GetTransitiveDependencies() {
391394
builtpkg, ok := buildctx.LocalCache.Location(deppkg)
392395
if !ok {
393396
return PkgNotBuiltErr{deppkg}
394397
}
395398

399+
tgt := deppkg.FilesystemSafeName()
400+
if cfg.Packaging == TypescriptOfflineMirror {
401+
fn := fmt.Sprintf("%s.tar.gz", tgt)
402+
commands = append(commands, []string{"cp", builtpkg, filepath.Join("_mirror", fn)})
403+
builtpkg = filepath.Join(wd, "_mirror", fn)
404+
}
405+
396406
if deppkg.Type == TypescriptPackage {
397407
cfg, ok := deppkg.Config.(TypescriptPkgConfig)
398-
if !ok || !cfg.Library {
399-
return xerrors.Errorf("cannot depend on typescript application packages: %s", deppkg.FullName())
408+
if !ok || cfg.Packaging != TypescriptLibrary {
409+
return xerrors.Errorf("can only depend on typescript libraries: %s", deppkg.FullName())
400410
}
401411

402412
// make previously built package availabe through yarn lock
403413
commands = append(commands, []string{"sh", "-c", fmt.Sprintf("tar Ozfx %s package/%s | sed '/resolved /c\\ resolved \"file://%s\"' >> yarn.lock", builtpkg, pkgYarnLock, builtpkg)})
404414
} else {
405-
tgt := strings.Replace(deppkg.FullName(), "/", "-", -1)
406415
commands = append(commands, [][]string{
407416
{"mkdir", tgt},
408417
{"tar", "xfz", builtpkg, "-C", tgt},
409418
}...)
410419
}
411420
}
412421

413-
if cfg.Library {
422+
if cfg.Packaging == TypescriptLibrary {
414423
// We can't modify the `yarn pack` generated tar file without runnign the risk of yarn blocking when attempting to unpack it again. Thus, we must include the pkgYarnLock in the npm
415424
// package we're building. To this end, we modify the package.json of the source package.
416425
pkgJSONFilename := filepath.Join(wd, "package.json")
@@ -452,14 +461,27 @@ func (p *Package) buildTypescript(buildctx *buildContext, wd, result string) (er
452461
yarnMutex = "network"
453462
}
454463
yarnCache := filepath.Join(buildctx.BuildDir(), "yarn-cache")
455-
commands = append(commands, []string{"yarn", "install", "--mutex", yarnMutex, "--cache-folder", yarnCache})
456-
if len(cfg.BuildCmd) == 0 {
464+
if len(cfg.Commands.Install) == 0 {
465+
commands = append(commands, []string{"yarn", "install", "--mutex", yarnMutex, "--cache-folder", yarnCache})
466+
} else {
467+
commands = append(commands, cfg.Commands.Install)
468+
}
469+
if len(cfg.Commands.Build) == 0 {
457470
commands = append(commands, []string{"npx", "tsc"})
458471
} else {
459-
commands = append(commands, cfg.BuildCmd)
472+
commands = append(commands, cfg.Commands.Build)
460473
}
461474

462-
if cfg.Library {
475+
if cfg.Packaging == TypescriptOfflineMirror {
476+
dst := filepath.Join("_mirror", fmt.Sprintf("%s.tar.gz", p.FilesystemSafeName()))
477+
commands = append(commands, [][]string{
478+
{"sh", "-c", fmt.Sprintf("yarn generate-lock-entry --resolved file://./%s > _mirror/content_yarn.lock", dst)},
479+
{"sh", "-c", "cat yarn.lock >> _mirror/content_yarn.lock"},
480+
{"yarn", "pack", "--filename", dst},
481+
{"sh", "-c", "#!/bin/bash\n" + `echo cd \$\(dirname \"\${BASH_SOURCE[0]}\"\) \&\& sed \'s?resolved \"file://.\*\/?resolved \"file:\/\/\'\$\(pwd\)\'\/?g\' content_yarn.lock > _mirror/get_yarn_lock.sh`},
482+
{"tar", "cfz", result, "-C", "_mirror", "."},
483+
}...)
484+
} else if cfg.Packaging == TypescriptLibrary {
463485
commands = append(commands, [][]string{
464486
{"sh", "-c", fmt.Sprintf("yarn generate-lock-entry --resolved file://%s > %s", result, pkgYarnLock)},
465487
{"yarn", "pack", "--filename", result},
@@ -491,7 +513,7 @@ func (p *Package) buildGo(buildctx *buildContext, wd, result string) (err error)
491513
return PkgNotBuiltErr{dep}
492514
}
493515

494-
tgt := filepath.Join("_deps", strings.Replace(dep.FullName(), "/", "-", -1))
516+
tgt := filepath.Join("_deps", dep.FilesystemSafeName())
495517
commands = append(commands, [][]string{
496518
{"mkdir", tgt},
497519
{"tar", "xfz", builtpkg, "-C", tgt},
@@ -518,7 +540,7 @@ func (p *Package) buildGo(buildctx *buildContext, wd, result string) (err error)
518540
if !cfg.DontCheckGoFmt {
519541
commands = append(commands, []string{"sh", "-c", `if [ ! $(go fmt ./... | wc -l) -eq 0 ]; then echo; echo; echo please gofmt your code; echo; echo; exit 1; fi`})
520542
}
521-
if !cfg.Library {
543+
if cfg.Packaging == GoApp {
522544
cmd := []string{"go", "build"}
523545
cmd = append(cmd, cfg.BuildFlags...)
524546
cmd = append(cmd, ".")
@@ -554,7 +576,7 @@ func (p *Package) buildDocker(buildctx *buildContext, wd, result string) (err er
554576
return PkgNotBuiltErr{dep}
555577
}
556578

557-
tgt := strings.Replace(dep.FullName(), "/", "-", -1)
579+
tgt := dep.FilesystemSafeName()
558580
commands = append(commands, [][]string{
559581
{"mkdir", tgt},
560582
{"tar", "xfz", fn, "-C", tgt},
@@ -619,7 +641,7 @@ func (p *Package) buildGeneric(buildctx *buildContext, wd, result string) (err e
619641
return PkgNotBuiltErr{dep}
620642
}
621643

622-
tgt := strings.Replace(dep.FullName(), "/", "-", -1)
644+
tgt := dep.FilesystemSafeName()
623645
commands = append(commands, [][]string{
624646
{"mkdir", tgt},
625647
{"tar", "xfz", fn, "-C", tgt},

pkg/leeway/package.go

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ func loadComponent(workspace *Workspace, path string, args Arguments) (Component
213213

214214
// add component BUILD file and additional sources to package sources
215215
completeSources := make(map[string]struct{})
216-
completeSources[path] = struct{}{}
217216
for _, src := range pkg.Sources {
218217
completeSources[src] = struct{}{}
219218
}
@@ -315,7 +314,8 @@ type Package struct {
315314
versionCache string
316315

317316
packageInternal
318-
Config PackageConfig `yaml:"config"`
317+
Config PackageConfig `yaml:"config"`
318+
rawYAML []byte
319319

320320
dependencies []*Package
321321
}
@@ -376,6 +376,16 @@ func (p *Package) UnmarshalYAML(unmarshal func(interface{}) error) error {
376376
}
377377
*p = Package{packageInternal: tpe}
378378

379+
var buf yaml.MapSlice
380+
err = unmarshal(&buf)
381+
if err != nil {
382+
return err
383+
}
384+
p.rawYAML, err = yaml.Marshal(buf)
385+
if err != nil {
386+
return err
387+
}
388+
379389
cfg, err := unmarshalTypeDependentConfig(tpe.Type, unmarshal)
380390
if err != nil {
381391
return err
@@ -394,6 +404,12 @@ func unmarshalTypeDependentConfig(tpe PackageType, unmarshal func(interface{}) e
394404
if err := unmarshal(&cfg); err != nil {
395405
return nil, err
396406
}
407+
if cfg.Config.Packaging == "" {
408+
cfg.Config.Packaging = TypescriptApp
409+
}
410+
if err := cfg.Config.Validate(); err != nil {
411+
return nil, err
412+
}
397413
return cfg.Config, nil
398414
case GoPackage:
399415
var cfg struct {
@@ -402,6 +418,12 @@ func unmarshalTypeDependentConfig(tpe PackageType, unmarshal func(interface{}) e
402418
if err := unmarshal(&cfg); err != nil {
403419
return nil, err
404420
}
421+
if cfg.Config.Packaging == "" {
422+
cfg.Config.Packaging = GoApp
423+
}
424+
if err := cfg.Config.Validate(); err != nil {
425+
return nil, err
426+
}
405427
return cfg.Config, nil
406428
case DockerPackage:
407429
var cfg struct {
@@ -435,12 +457,40 @@ type PackageConfig interface {
435457

436458
// TypescriptPkgConfig configures a typescript package
437459
type TypescriptPkgConfig struct {
438-
YarnLock string `yaml:"yarnLock,omitempty"`
439-
TSConfig string `yaml:"tsconfig"`
440-
Library bool `yaml:"library,omitempty"`
441-
BuildCmd []string `yaml:"buildCommand,omitempty"`
460+
YarnLock string `yaml:"yarnLock,omitempty"`
461+
TSConfig string `yaml:"tsconfig"`
462+
Packaging TypescriptPackaging `yaml:"packaging,omitempty"`
463+
Commands struct {
464+
Install []string `yaml:"install,omitempty"`
465+
Build []string `yaml:"build,omitempty"`
466+
} `yaml:"commands,omitempty"`
467+
}
468+
469+
// Validate ensures this config can be acted upon/is valid
470+
func (cfg TypescriptPkgConfig) Validate() error {
471+
switch cfg.Packaging {
472+
case TypescriptLibrary:
473+
case TypescriptOfflineMirror:
474+
case TypescriptApp:
475+
default:
476+
return xerrors.Errorf("unknown packaging: %s", cfg.Packaging)
477+
}
478+
479+
return nil
442480
}
443481

482+
// TypescriptPackaging configures the packaging method of a typescript package
483+
type TypescriptPackaging string
484+
485+
const (
486+
// TypescriptLibrary means the package will be created using `yarn pack`
487+
TypescriptLibrary TypescriptPackaging = "library"
488+
// TypescriptOfflineMirror means that the package will become a yarn offline mirror
489+
TypescriptOfflineMirror TypescriptPackaging = "offline-mirror"
490+
// TypescriptApp simply tars the build directory
491+
TypescriptApp TypescriptPackaging = "app"
492+
)
493+
444494
// AdditionalSources returns a list of unresolved sources coming in through this configuration
445495
func (cfg TypescriptPkgConfig) AdditionalSources() []string {
446496
var res []string
@@ -455,13 +505,35 @@ func (cfg TypescriptPkgConfig) AdditionalSources() []string {
455505

456506
// GoPkgConfig configures a Go package
457507
type GoPkgConfig struct {
458-
Library bool `yaml:"library,omitempty"`
459-
Generate bool `yaml:"generate,omitempty"`
460-
DontTest bool `yaml:"dontTest,omitempty"`
461-
DontCheckGoFmt bool `yaml:"dontCheckGoFmt,omitempty"`
462-
BuildFlags []string `yaml:"buildFlags,omitempty"`
508+
Packaging GoPackaging `yaml:"packaging,omitempty"`
509+
Generate bool `yaml:"generate,omitempty"`
510+
DontTest bool `yaml:"dontTest,omitempty"`
511+
DontCheckGoFmt bool `yaml:"dontCheckGoFmt,omitempty"`
512+
BuildFlags []string `yaml:"buildFlags,omitempty"`
513+
}
514+
515+
// Validate ensures this config can be acted upon/is valid
516+
func (cfg GoPkgConfig) Validate() error {
517+
switch cfg.Packaging {
518+
case GoLibrary:
519+
case GoApp:
520+
default:
521+
return xerrors.Errorf("unknown packaging: %s", cfg.Packaging)
522+
}
523+
524+
return nil
463525
}
464526

527+
// GoPackaging configures the packaging method of a Go package
528+
type GoPackaging string
529+
530+
const (
531+
// GoLibrary means the package can be imported in another package
532+
GoLibrary GoPackaging = "library"
533+
// GoApp runs go build and tars the build directory
534+
GoApp GoPackaging = "app"
535+
)
536+
465537
// AdditionalSources returns a list of unresolved sources coming in through this configuration
466538
func (cfg GoPkgConfig) AdditionalSources() []string {
467539
return []string{}
@@ -510,6 +582,16 @@ func (p *Package) FullName() string {
510582
return fmt.Sprintf("%s:%s", p.C.Name, p.Name)
511583
}
512584

585+
// FilesystemSafeName returns a string that is safe to use in a Unix filesystem as directory or filename
586+
func (p *Package) FilesystemSafeName() string {
587+
pkgdir := p.FullName()
588+
pkgdir = strings.Replace(pkgdir, "/", "-", -1)
589+
pkgdir = strings.Replace(pkgdir, ":", "--", -1)
590+
// components in the workspace root would otherwise start with -- which breaks a lot of shell commands
591+
pkgdir = strings.TrimPrefix(pkgdir, "--")
592+
return pkgdir
593+
}
594+
513595
// resolveSources resolves any glob expression in the source list
514596
func (p *Package) resolveSources() error {
515597
var res []string
@@ -633,6 +715,14 @@ func (p *Package) Version() (string, error) {
633715
}
634716

635717
h := sha1.New()
718+
_, err = h.Write(p.rawYAML)
719+
if err != nil {
720+
return "", err
721+
}
722+
_, err = io.WriteString(h, strings.Join(manifest, "\n"))
723+
if err != nil {
724+
return "", err
725+
}
636726
_, err = io.WriteString(h, strings.Join(manifest, "\n"))
637727
if err != nil {
638728
return "", err

0 commit comments

Comments
 (0)