pkgforge 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ca053ae9faf8703044efb96aa5af946b834cc0a
4
- data.tar.gz: 79fbafd6cfff400c531ac02017bf5e905f120aef
3
+ metadata.gz: db7f41b90da9053a2afaa72620879e7edc44f860
4
+ data.tar.gz: 6bdddd3a26207ef02fa8ae5836886b9d5dffd022
5
5
  SHA512:
6
- metadata.gz: c84d652a7053e84fcee047d3807a2540dd9ad44221ca4539f902ad30253fb49292e8da091167ad0b5a296e69e3de27d267c26709365288ff60460a9672985b87
7
- data.tar.gz: 9201e5291269fa244432e799b5a616e21acac36dffadb8441dc7462d3048dcfff977effe4d85b32ac2efe19ccb17798286fd96bd33347503de732092be1807f5
6
+ metadata.gz: 7896cebed55fb4301058c26801cce22c4a606b9b5fac57ec33fbc24920157cc6b213baf05f5cd2acef385811214584618be3a012bb5f24ffe6875b1d92aee38d
7
+ data.tar.gz: b7212896f57b374944d7bfb1e1b216b31d16c8fddbc8eff65a8fd135c6f934079a4183473cb26ca9d3a88687b357fb81f97d3978fe9ff8b9d1dd5184e2f0d4b4
data/lib/pkgforge.rb CHANGED
@@ -1,14 +1,19 @@
1
1
  require 'contracts'
2
2
 
3
+ require 'pkgforge/base'
3
4
  require 'pkgforge/version'
4
- require 'pkgforge/helpers'
5
- require 'pkgforge/prepare'
6
- require 'pkgforge/push'
7
- require 'pkgforge/forge'
8
- require 'pkgforge/forgedsl'
9
- require 'pkgforge/builddsl'
10
- require 'pkgforge/testdsl'
11
- require 'pkgforge/versiondsl'
5
+ require 'pkgforge/components/build'
6
+ require 'pkgforge/components/cflags'
7
+ require 'pkgforge/components/configure'
8
+ require 'pkgforge/components/deps'
9
+ require 'pkgforge/components/dirs'
10
+ require 'pkgforge/components/metadata'
11
+ require 'pkgforge/components/patch'
12
+ require 'pkgforge/components/run'
13
+ require 'pkgforge/components/source'
14
+ require 'pkgforge/components/test'
15
+ require 'pkgforge/components/upload'
16
+ require 'pkgforge/components/version'
12
17
 
13
18
  ##
14
19
  # DSL engine for compiling Arch packages
@@ -31,7 +36,7 @@ module PkgForge
31
36
  def load_from_file(params = {})
32
37
  file = params[:file] || DEFAULT_FILE
33
38
  forge = Forge.new(params)
34
- dsl = ForgeDSL.new(forge, params)
39
+ dsl = DSL::Forge.new(forge)
35
40
  dsl.instance_eval(File.read(file), file)
36
41
  forge
37
42
  end
@@ -0,0 +1,43 @@
1
+ require 'contracts'
2
+
3
+ module PkgForge
4
+ ##
5
+ # Starter Forge object
6
+ class Forge
7
+ include Contracts::Core
8
+ include Contracts::Builtin
9
+
10
+ Contract Maybe[HashOf[Symbol => Any]] => nil
11
+ def initialize(params = {})
12
+ @options = params
13
+ nil
14
+ end
15
+ end
16
+
17
+ ##
18
+ # Base engine structure
19
+ class Base
20
+ include Contracts::Core
21
+ include Contracts::Builtin
22
+
23
+ Contract PkgForge::Forge => nil
24
+ def initialize(forge)
25
+ @forge = forge
26
+ nil
27
+ end
28
+ end
29
+
30
+ module DSL
31
+ class Forge < PkgForge::Base
32
+ end
33
+
34
+ class Build < PkgForge::Base
35
+ end
36
+
37
+ class Test < PkgForge::Base
38
+ end
39
+
40
+ class Version < PkgForge::Base
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,72 @@
1
+ require 'fileutils'
2
+
3
+ module PkgForge
4
+ ##
5
+ # Add build methods to Forge
6
+ class Forge
7
+ attr_writer :build_block
8
+
9
+ Contract None => Proc
10
+ def build_block
11
+ @build_block ||= proc { raise 'No build block provided' }
12
+ end
13
+
14
+ Contract None => nil
15
+ def build!
16
+ prepare_source!
17
+ patch_source!
18
+ prepare_deps!
19
+ builder = PkgForge::DSL::Build.new(self)
20
+ builder.instance_eval(&build_block)
21
+ end
22
+ end
23
+
24
+ module DSL
25
+ ##
26
+ # Add build method to Forge DSL
27
+ class Forge
28
+ Contract Func[None => nil] => nil
29
+ def build(&block)
30
+ @forge.build_block = block
31
+ nil
32
+ end
33
+ end
34
+
35
+ ##
36
+ # Add build methods to Build DSL
37
+ class Build
38
+ Contract Or[String, Array], Or[HashOf[String => String], {}, nil] => nil
39
+ def run(*args)
40
+ @forge.run(*args)
41
+ end
42
+
43
+ Contract None => nil
44
+ def configure
45
+ env = {
46
+ 'CC' => 'musl-gcc',
47
+ 'CFLAGS' => @forge.cflags.join(' '),
48
+ 'LIBS' => @forge.libs.join(' ')
49
+ }
50
+ run ['./configure'] + configure_flag_strings, env
51
+ end
52
+
53
+ Contract None => nil
54
+ def make
55
+ run 'make'
56
+ end
57
+
58
+ Contract None => nil
59
+ def install
60
+ run "make DESTDIR=#{@forge.releasedir} install"
61
+ end
62
+
63
+ Contract Or[String, ArrayOf[String]] => nil
64
+ def rm(paths)
65
+ paths = [paths] if paths.is_a? String
66
+ paths.map { |x| File.join(@forge.releasedir, x) }
67
+ FileUtils.rm_r paths
68
+ nil
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,57 @@
1
+ module PkgForge
2
+ ##
3
+ # Add cflag options to Forge
4
+ class Forge
5
+ attr_writer :cflags, :libs
6
+
7
+ Contract None => ArrayOf[String]
8
+ def cflags
9
+ @cflags ||= []
10
+ end
11
+
12
+ Contract None => ArrayOf[String]
13
+ def libs
14
+ @libs ||= []
15
+ end
16
+ end
17
+
18
+ module DSL
19
+ ##
20
+ # Add cflag options to Forge DSL
21
+ class Forge
22
+ Contract Maybe[String] => nil
23
+ def cflags(value = nil)
24
+ default = '-I%{dep}/usr/include -L%{dep}/usr/lib'
25
+ value ||= @forge.deps.map { |x, _| default % { dep: dep(x) }.split }
26
+ @forge.cflags += value.flatten
27
+ nil
28
+ end
29
+
30
+ Contract Maybe[String] => nil
31
+ def libs(value = nil)
32
+ value ||= @forge.deps.map { |x, _| '-l' + x }
33
+ @forge.libs += value
34
+ nil
35
+ end
36
+
37
+ # Shamelessly sourced from:
38
+ # https://blog.mayflower.de/5800-Hardening-Compiler-Flags-for-NixOS.html
39
+ ALL_HARDEN_OPTS = {
40
+ format: %w(-Wformat -Wformat-security -Werror=format-security),
41
+ stackprotector: %w(-fstack-protector-strong --param ssp-buffer-size=4),
42
+ fortify: %w(-O2 -D_FORTIFY_SOURCE=2),
43
+ pic: '-fPIC',
44
+ strictoverflow: '-fno-strict-overflow',
45
+ relro: '-z=relro',
46
+ bindnow: '-z=bindnow',
47
+ pie: %w(-fPIE -pie)
48
+ }.freeze
49
+
50
+ Contract Maybe[Array[String]] => nil
51
+ def harden(list = [])
52
+ harden_opts = ALL_HARDEN_OPTS.reject { |k, _| list.include? k.to_s }
53
+ @forge.cflags += harden_opts.flatten
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ module PkgForge
2
+ ##
3
+ # Add configure flag options to Forge
4
+ class Forge
5
+ attr_writer :configure_flags
6
+
7
+ Contract None => HashOf[Symbol => Maybe[String]]
8
+ def configure_flags
9
+ @configure_flags ||= {}
10
+ end
11
+ end
12
+
13
+ module DSL
14
+ ##
15
+ # Add configure flag options to Forge DSL
16
+ class Forge
17
+ Contract HashOf[Symbol => Maybe[String]] => nil
18
+ def configure_flags(value)
19
+ @forge.configure_flags = value
20
+ nil
21
+ end
22
+ end
23
+
24
+ ##
25
+ # Add configure flag options to Build DSL
26
+ class Build
27
+ Contract None => ArrayOf[String]
28
+ def configure_flag_strings
29
+ @forge.configure_flags.map do |flag, value|
30
+ "--#{flag}#{'=' if value}#{value}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ require 'open-uri'
2
+
3
+ module PkgForge
4
+ ##
5
+ # Add dep methods to Forge
6
+ class Forge
7
+ attr_writer :deps
8
+
9
+ Contract None => HashOf[Symbol => String]
10
+ def deps
11
+ @deps ||= {}
12
+ end
13
+
14
+ private
15
+
16
+ Contract None => nil
17
+ def prepare_deps!
18
+ deps.each do |dep_name, dep_version|
19
+ url = "https://github.com/#{org}/#{dep_name}/releases/download/#{dep_version}/#{dep_name}.tar.gz" # rubocop:disable Metrics/LineLength
20
+ open(tmpfile(dep_name), 'wb') { |fh| fh << open(url, 'rb').read }
21
+ run_local "tar -x -C #{tmpdir(dep_name)} -f #{tmpfile(dep_name)}"
22
+ end
23
+ nil
24
+ end
25
+ end
26
+
27
+ module DSL
28
+ ##
29
+ # Add dep methods to Forge DSL
30
+ class Forge
31
+ Contract HashOf[Symbol => String] => nil
32
+ def deps(value)
33
+ @forge.deps = value
34
+ nil
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,41 @@
1
+ require 'tmpdir'
2
+ require 'tempfile'
3
+
4
+ module PkgForge
5
+ ##
6
+ # Add dir methods to Forge
7
+ class Forge
8
+ Contract String => String
9
+ def dep(package)
10
+ tmpdir(package.to_sym)
11
+ end
12
+
13
+ Contract None => String
14
+ def releasedir
15
+ tmpdir(:release)
16
+ end
17
+
18
+ Contract Symbol => String
19
+ def tmpdir(id)
20
+ @tmpdirs ||= {}
21
+ @tmpdirs[id] ||= Dir.mktmpdir(id.to_s)
22
+ end
23
+
24
+ Contract Symbol => String
25
+ def tmpfile(id)
26
+ @tmpfiles ||= {}
27
+ @tmpfiles[id] ||= Tempfile.create(id.to_s).path
28
+ end
29
+ end
30
+
31
+ module DSL
32
+ ##
33
+ # Add dir methods to Forge DSL
34
+ class Forge
35
+ Contract String => String
36
+ def dep(dep_name)
37
+ @forge.dep(dep_name)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,60 @@
1
+ require 'fileutils'
2
+
3
+ module PkgForge
4
+ ##
5
+ # Add metadata methods to Forge
6
+ class Forge
7
+ attr_writer :name, :org, :license
8
+
9
+ Contract None => String
10
+ def name
11
+ @name || raise('No name provided')
12
+ end
13
+
14
+ Contract None => String
15
+ def org
16
+ @org || raise('No org provided')
17
+ end
18
+
19
+ Contract None => String
20
+ def license
21
+ @license ||= 'LICENSE'
22
+ end
23
+
24
+ Contract None => nil
25
+ def add_license!
26
+ src_file = File.join(tmpdir(:build), license)
27
+ dest_dir = File.join(
28
+ tmpdir(:release), 'usr', 'share', 'licenses', name
29
+ )
30
+ dest_file = File.join(dest_dir, 'LICENSE')
31
+ FileUtils.mkdir_p dest_dir
32
+ FileUtils.cp src_file, dest_file
33
+ nil
34
+ end
35
+ end
36
+
37
+ module DSL
38
+ ##
39
+ # Add metadata methods to Forge DSL
40
+ class Forge
41
+ Contract String => nil
42
+ def name(value)
43
+ @forge.name = value
44
+ nil
45
+ end
46
+
47
+ Contract String => nil
48
+ def org(value)
49
+ @forge.org = value
50
+ nil
51
+ end
52
+
53
+ Contract String => nil
54
+ def license(file)
55
+ @forge.license = file
56
+ nil
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,34 @@
1
+ module PkgForge
2
+ ##
3
+ # Add patch methods to Forge
4
+ class Forge
5
+ attr_writer :patches
6
+
7
+ Contract None => ArrayOf[String]
8
+ def patches
9
+ @patches ||= []
10
+ end
11
+
12
+ private
13
+
14
+ Contract None => nil
15
+ def patch_source!
16
+ patches.each do |patch|
17
+ run_local "patch -d #{tmpdir(:build)} -p1 < patches/#{patch}"
18
+ end
19
+ nil
20
+ end
21
+ end
22
+
23
+ module DSL
24
+ ##
25
+ # Add patch methods to Forge DSL
26
+ class Forge
27
+ Contract String => nil
28
+ def patch(file)
29
+ @forge.patches << file
30
+ nil
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ module PkgForge
2
+ ##
3
+ # Add run methods to Forge
4
+ class Forge
5
+ Contract Or[String, Array], Or[HashOf[String => String], {}, nil] => nil
6
+ def run(cmd, env = {})
7
+ Dir.chdir(tmpdir(:build)) do
8
+ run_local(cmd, env)
9
+ end
10
+ nil
11
+ end
12
+
13
+ Contract Or[String, Array], Or[HashOf[String => String], {}, nil] => nil
14
+ def test_run(cmd, env = {})
15
+ Dir.chdir(tmpdir(:release)) do
16
+ run_local(cmd, env)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ Contract Or[String, Array], Or[HashOf[String => String], {}, nil] => nil
23
+ def run_local(cmd, env = {})
24
+ puts "Running command in #{Dir.pwd}: #{cmd}"
25
+ puts "Using env: #{env}" unless env.empty?
26
+ res = system env, *cmd
27
+ raise('Command failed!') unless res
28
+ nil
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ require 'fileutils'
2
+
3
+ module PkgForge
4
+ ##
5
+ # Add source methods to Forge
6
+ class Forge
7
+ private
8
+
9
+ Contract None => nil
10
+ def prepare_source!
11
+ dest = tmpdir(:build)
12
+ dest_git = File.join(dest, '.git')
13
+ dest_git_config = File.join(dest_git, 'config')
14
+ run_local 'git submodule update --init'
15
+ FileUtils.cp_r 'upstream/.', dest
16
+ FileUtils.rm_r dest_git
17
+ FileUtils.cp_r '.git/modules/upstream', dest_git
18
+ new_config = File.readlines(dest_git_config).grep_v(/worktree =/).join
19
+ File.open(dest_git_config, 'w') { |fh| fh << new_config }
20
+ nil
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,44 @@
1
+ require 'fileutils'
2
+
3
+ module PkgForge
4
+ ##
5
+ # Add test methods to Forge
6
+ class Forge
7
+ attr_writer :test_block
8
+
9
+ Contract None => Proc
10
+ def test_block
11
+ @test_block ||= proc { raise 'No test block provided' }
12
+ end
13
+
14
+ Contract None => nil
15
+ def test!
16
+ tester = PkgForge::DSL::Test.new(self)
17
+ tester.instance_eval(&test_block)
18
+ end
19
+ end
20
+
21
+ module DSL
22
+ ##
23
+ # Add test methods to Forge DSL
24
+ class Forge
25
+ Contract Func[None => nil] => nil
26
+ def test(&block)
27
+ @forge.test_block = block
28
+ nil
29
+ end
30
+ end
31
+
32
+ ##
33
+ # Add test methods to Test DSL
34
+ class Test
35
+ Contract Or[String, Array], Or[HashOf[String => String], {}, nil] => nil
36
+ def run(cmd, env = {})
37
+ cmd.unshift('/usr/bin/env') if cmd.is_a? Array
38
+ cmd << ';' if cmd.is_a? String
39
+ env['PATH'] ||= './usr/bin'
40
+ @forge.test_run(cmd, env)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,12 +1,25 @@
1
1
  module PkgForge
2
2
  ##
3
- # Helpers for pushing
4
- module Push
5
- include Contracts::Core
6
- include Contracts::Builtin
3
+ # Add upload methods to Forge
4
+ class Forge
5
+ Contract None => nil
6
+ def push!
7
+ add_license!
8
+ make_tarball!
9
+ update_repo!
10
+ upload_artifact!
11
+ end
7
12
 
8
13
  private
9
14
 
15
+ Contract None => nil
16
+ def make_tarball!
17
+ Dir.chdir(tmpdir(:release)) do
18
+ run_local "tar -czvf #{tmpfile(:tarball)} *"
19
+ end
20
+ nil
21
+ end
22
+
10
23
  Contract None => nil
11
24
  def update_repo!
12
25
  run_local "git tag -f '#{full_version}'"
@@ -0,0 +1,52 @@
1
+ module PkgForge
2
+ ##
3
+ # Add version methods to Forge
4
+ class Forge
5
+ attr_writer :version_block
6
+
7
+ Contract None => Proc
8
+ def version_block
9
+ @version_block ||= proc { raise 'No version block provided' }
10
+ end
11
+
12
+ Contract None => String
13
+ def version
14
+ @version ||= Dir.chdir(tmpdir(:build)) do
15
+ PkgForge::DSL::Version.new(self).instance_eval(&version_block)
16
+ end
17
+ end
18
+
19
+ Contract None => Num
20
+ def revision
21
+ @revision ||= `git describe --abbrev=0 --tags`.split('-').last.to_i + 1
22
+ end
23
+
24
+ Contract None => String
25
+ def full_version
26
+ "#{version}-#{revision}"
27
+ end
28
+ end
29
+
30
+ module DSL
31
+ ##
32
+ # Add version methods to Forge DSL
33
+ class Forge
34
+ Contract Func[None => Maybe[String]] => nil
35
+ def version(&block)
36
+ @forge.version_block = block
37
+ nil
38
+ end
39
+ end
40
+
41
+ ##
42
+ # Add version methods to Version DSL
43
+ class Version
44
+ Contract Maybe[Regexp], Maybe[String] => String
45
+ def git_tag(regex = nil, replace = '\1')
46
+ tag = `git describe --tags`.rstrip
47
+ tag.gsub!(regex, replace) if regex
48
+ tag
49
+ end
50
+ end
51
+ end
52
+ end
@@ -1,5 +1,5 @@
1
1
  ##
2
2
  # Declare version number
3
3
  module PkgForge
4
- VERSION = '0.2.2'.freeze
4
+ VERSION = '0.3.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pkgforge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Les Aker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-30 00:00:00.000000000 Z
11
+ date: 2016-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mercenary
@@ -127,15 +127,20 @@ files:
127
127
  - bin/pkgforge
128
128
  - circle.yml
129
129
  - lib/pkgforge.rb
130
- - lib/pkgforge/builddsl.rb
131
- - lib/pkgforge/forge.rb
132
- - lib/pkgforge/forgedsl.rb
133
- - lib/pkgforge/helpers.rb
134
- - lib/pkgforge/prepare.rb
135
- - lib/pkgforge/push.rb
136
- - lib/pkgforge/testdsl.rb
130
+ - lib/pkgforge/base.rb
131
+ - lib/pkgforge/components/build.rb
132
+ - lib/pkgforge/components/cflags.rb
133
+ - lib/pkgforge/components/configure.rb
134
+ - lib/pkgforge/components/deps.rb
135
+ - lib/pkgforge/components/dirs.rb
136
+ - lib/pkgforge/components/metadata.rb
137
+ - lib/pkgforge/components/patch.rb
138
+ - lib/pkgforge/components/run.rb
139
+ - lib/pkgforge/components/source.rb
140
+ - lib/pkgforge/components/test.rb
141
+ - lib/pkgforge/components/upload.rb
142
+ - lib/pkgforge/components/version.rb
137
143
  - lib/pkgforge/version.rb
138
- - lib/pkgforge/versiondsl.rb
139
144
  - pkgforge.gemspec
140
145
  - spec/pkgforge_spec.rb
141
146
  - spec/spec_helper.rb
@@ -1,55 +0,0 @@
1
- require 'fileutils'
2
-
3
- module PkgForge
4
- ##
5
- # Builder engine
6
- class BuildDSL
7
- include Contracts::Core
8
- include Contracts::Builtin
9
-
10
- Contract PkgForge::Forge => nil
11
- def initialize(forge)
12
- @forge = forge
13
- nil
14
- end
15
-
16
- private
17
-
18
- Contract Or[String, Array], Or[Hash[String => String], {}, nil] => nil
19
- def run(*args)
20
- @forge.run(*args)
21
- end
22
-
23
- Contract None => nil
24
- def configure
25
- flag_strings = @forge.configure_flags.map do |flag, value|
26
- "--#{flag}#{'=' if value}#{value}"
27
- end
28
- env = {
29
- 'CC' => 'musl-gcc',
30
- 'CFLAGS' => @forge.all_cflags,
31
- 'LDFLAGS' => @forge.all_cflags,
32
- 'LIBS' => @forge.libs
33
- }
34
- run ['./configure'] + flag_strings, env
35
- end
36
-
37
- Contract None => nil
38
- def make
39
- run 'make'
40
- end
41
-
42
- Contract None => nil
43
- def install
44
- run "make DESTDIR=#{@forge.releasedir} install"
45
- end
46
-
47
- Contract Or[String, Array[String]] => nil
48
- def rm(paths)
49
- paths = [paths] if paths.is_a? String
50
- paths.map { |x| File.join(@forge.releasedir, x) }
51
- FileUtils.rm_r paths
52
- nil
53
- end
54
- end
55
- end
@@ -1,57 +0,0 @@
1
- require 'tmpdir'
2
- require 'tempfile'
3
- require 'fileutils'
4
- require 'open-uri'
5
-
6
- ##
7
- # Declare actual Forge with package-building
8
- module PkgForge
9
- ##
10
- # Real Forge object
11
- class Forge
12
- include Contracts::Core
13
- include Contracts::Builtin
14
- include PkgForge::Helpers
15
- include PkgForge::Prepare
16
- include PkgForge::Push
17
-
18
- attr_accessor :name, :org, :deps, :configure_flags, :version_block,
19
- :patches, :build_block, :test_block, :license, :cflags,
20
- :libs, :harden_flags
21
-
22
- Contract Maybe[HashOf[Symbol => Any]] => nil
23
- def initialize(params = {})
24
- @options = params
25
- @license = 'LICENSE'
26
- @deps = {}
27
- @flags = {}
28
- @patches = []
29
- @build_block = proc { raise('No build block provided') }
30
- @test_block = proc { raise('No test block provided') }
31
- nil
32
- end
33
-
34
- Contract None => nil
35
- def build!
36
- prepare_source!
37
- patch_source!
38
- prepare_deps!
39
- builder = BuildDSL.new(self)
40
- builder.instance_eval(&build_block)
41
- end
42
-
43
- Contract None => nil
44
- def test!
45
- tester = TestDSL.new(self)
46
- tester.instance_eval(&test_block)
47
- end
48
-
49
- Contract None => nil
50
- def push!
51
- add_license!
52
- make_tarball!
53
- update_repo!
54
- upload_artifact!
55
- end
56
- end
57
- end
@@ -1,110 +0,0 @@
1
- ##
2
- # Declare DSL for Forge objects
3
- module PkgForge
4
- ##
5
- # DSL for generating a Forge
6
- class ForgeDSL
7
- include Contracts::Core
8
- include Contracts::Builtin
9
-
10
- Contract Forge, Maybe[Hash] => nil
11
- def initialize(forge, params = {})
12
- @forge = forge
13
- @options = params
14
- nil
15
- end
16
-
17
- Contract String => nil
18
- def name(value)
19
- @forge.name = value
20
- nil
21
- end
22
-
23
- Contract String => nil
24
- def org(value)
25
- @forge.org = value
26
- nil
27
- end
28
-
29
- Contract HashOf[Symbol => String] => nil
30
- def deps(value)
31
- @forge.deps = value
32
- nil
33
- end
34
-
35
- Contract HashOf[Symbol => String] => nil
36
- def configure_flags(value)
37
- @forge.configure_flags = value
38
- nil
39
- end
40
-
41
- Contract Func[None => Maybe[String]] => nil
42
- def version(&block)
43
- @forge.version_block = block
44
- nil
45
- end
46
-
47
- Contract String => nil
48
- def patch(file)
49
- @forge.patches ||= []
50
- @forge.patches << file
51
- nil
52
- end
53
-
54
- Contract Func[None => nil] => nil
55
- def build(&block)
56
- @forge.build_block = block
57
- nil
58
- end
59
-
60
- Contract Func[None => nil] => nil
61
- def test(&block)
62
- @forge.test_block = block
63
- nil
64
- end
65
-
66
- Contract String => nil
67
- def license(file)
68
- @forge.license = file
69
- nil
70
- end
71
-
72
- Contract String => String
73
- def dep(dep_name)
74
- @forge.dep(dep_name)
75
- end
76
-
77
- Contract Maybe[String] => nil
78
- def cflags(value = nil)
79
- default = '-I%{dep}/usr/include -L%{dep}/usr/lib'
80
- value ||= @forge.deps.map { |x, _| default % { dep: dep(x) }.split }
81
- @forge.cflags = value.flatten
82
- nil
83
- end
84
-
85
- Contract Maybe[String] => nil
86
- def libs(value = nil)
87
- value ||= @forge.deps.map { |x, _| '-l' + x }
88
- @forge.libs = value
89
- nil
90
- end
91
-
92
- # hamelessly sourced from:
93
- # https://blog.mayflower.de/5800-Hardening-Compiler-Flags-for-NixOS.html
94
- HARDEN_OPTS = {
95
- format: %w(-Wformat -Wformat-security -Werror=format-security),
96
- stackprotector: %w(-fstack-protector-strong --param ssp-buffer-size=4),
97
- fortify: %w(-O2 -D_FORTIFY_SOURCE=2),
98
- pic: '-fPIC',
99
- strictoverflow: '-fno-strict-overflow',
100
- relro: '-z=relro',
101
- bindnow: '-z=bindnow',
102
- pie: %w(-fPIE -pie)
103
- }.freeze
104
-
105
- Contract Maybe[Array[String]] => nil
106
- def harden(list = [])
107
- @forge.harden_flags = HARDEN_OPTS.reject { |k, _| list.include? k.to_s }
108
- end
109
- end
110
- end
@@ -1,78 +0,0 @@
1
- module PkgForge
2
- ##
3
- # Helper functions for building packages
4
- module Helpers
5
- include Contracts::Core
6
- include Contracts::Builtin
7
-
8
- Contract String => String
9
- def dep(package)
10
- tmpdir(package.to_sym)
11
- end
12
-
13
- Contract None => String
14
- def releasedir
15
- tmpdir(:release)
16
- end
17
-
18
- Contract Or[String, Array], Or[Hash[String => String], {}, nil] => nil
19
- def run(cmd, env = {})
20
- Dir.chdir(tmpdir(:build)) do
21
- run_local(cmd, env)
22
- end
23
- nil
24
- end
25
-
26
- Contract Or[String, Array], Or[Hash[String => String], {}, nil] => nil
27
- def test_run(cmd, env = {})
28
- Dir.chdir(tmpdir(:release)) do
29
- run_local(cmd, env)
30
- end
31
- end
32
-
33
- Contract None => Array[String]
34
- def all_cflags
35
- cflags + harden_flags
36
- end
37
-
38
- private
39
-
40
- Contract Symbol => String
41
- def tmpdir(id)
42
- @tmpdirs ||= {}
43
- @tmpdirs[id] ||= Dir.mktmpdir(id.to_s)
44
- end
45
-
46
- Contract Symbol => String
47
- def tmpfile(id)
48
- @tmpfiles ||= {}
49
- @tmpfiles[id] ||= Tempfile.create(id.to_s).path
50
- end
51
-
52
- Contract Or[String, Array], Or[Hash[String => String], {}, nil] => nil
53
- def run_local(cmd, env = {})
54
- puts "Running command in #{Dir.pwd}: #{cmd}"
55
- puts "Using env: #{env}" unless env.empty?
56
- res = system env, *cmd
57
- raise('Command failed!') unless res
58
- nil
59
- end
60
-
61
- Contract None => String
62
- def version
63
- @version ||= Dir.chdir(tmpdir(:build)) do
64
- VersionDSL.new(self).instance_eval(&version_block)
65
- end
66
- end
67
-
68
- Contract None => Num
69
- def revision
70
- @revision ||= `git describe --abbrev=0 --tags`.split('-').last.to_i + 1
71
- end
72
-
73
- Contract None => String
74
- def full_version
75
- "#{version}-#{revision}"
76
- end
77
- end
78
- end
@@ -1,62 +0,0 @@
1
- module PkgForge
2
- ##
3
- # Preparation methods
4
- module Prepare
5
- include Contracts::Core
6
- include Contracts::Builtin
7
-
8
- private
9
-
10
- Contract None => nil
11
- def prepare_source!
12
- dest = tmpdir(:build)
13
- dest_git = File.join(dest, '.git')
14
- dest_git_config = File.join(dest_git, 'config')
15
- run_local 'git submodule update --init'
16
- FileUtils.cp_r 'upstream/.', dest
17
- FileUtils.rm_r dest_git
18
- FileUtils.cp_r '.git/modules/upstream', dest_git
19
- new_config = File.readlines(dest_git_config).grep_v(/worktree =/).join
20
- File.open(dest_git_config, 'w') { |fh| fh << new_config }
21
- nil
22
- end
23
-
24
- Contract None => nil
25
- def patch_source!
26
- patches.each do |patch|
27
- run_local "patch -d #{tmpdir(:build)} -p1 < patches/#{patch}"
28
- end
29
- nil
30
- end
31
-
32
- Contract None => nil
33
- def prepare_deps!
34
- deps.each do |dep_name, dep_version|
35
- url = "https://github.com/#{org}/#{dep_name}/releases/download/#{dep_version}/#{dep_name}.tar.gz" # rubocop:disable Metrics/LineLength
36
- open(tmpfile(dep_name), 'wb') { |fh| fh << open(url, 'rb').read }
37
- run_local "tar -x -C #{tmpdir(dep_name)} -f #{tmpfile(dep_name)}"
38
- end
39
- nil
40
- end
41
-
42
- Contract None => nil
43
- def add_license!
44
- src_file = File.join(tmpdir(:build), license)
45
- dest_dir = File.join(
46
- tmpdir(:release), 'usr', 'share', 'licenses', name
47
- )
48
- dest_file = File.join(dest_dir, 'LICENSE')
49
- FileUtils.mkdir_p dest_dir
50
- FileUtils.cp src_file, dest_file
51
- nil
52
- end
53
-
54
- Contract None => nil
55
- def make_tarball!
56
- Dir.chdir(tmpdir(:release)) do
57
- run_local "tar -czvf #{tmpfile(:tarball)} *"
58
- end
59
- nil
60
- end
61
- end
62
- end
@@ -1,26 +0,0 @@
1
- require 'fileutils'
2
-
3
- module PkgForge
4
- ##
5
- # Test engine
6
- class TestDSL
7
- include Contracts::Core
8
- include Contracts::Builtin
9
-
10
- Contract PkgForge::Forge => nil
11
- def initialize(forge)
12
- @forge = forge
13
- nil
14
- end
15
-
16
- private
17
-
18
- Contract Or[String, Array], Or[Hash[String => String], {}, nil] => nil
19
- def run(cmd, env = {})
20
- cmd.unshift('/usr/bin/env') if cmd.is_a? Array
21
- cmd << ';' if cmd.is_a? String
22
- env['PATH'] ||= './usr/bin'
23
- @forge.test_run(cmd, env)
24
- end
25
- end
26
- end
@@ -1,23 +0,0 @@
1
- module PkgForge
2
- ##
3
- # Version engine
4
- class VersionDSL
5
- include Contracts::Core
6
- include Contracts::Builtin
7
-
8
- Contract PkgForge::Forge => nil
9
- def initialize(forge)
10
- @forge = forge
11
- nil
12
- end
13
-
14
- private
15
-
16
- Contract Maybe[Regexp], Maybe[String] => String
17
- def git_tag(regex = nil, replace = '\1')
18
- tag = `git describe --tags`.rstrip
19
- tag.gsub!(regex, replace) if regex
20
- tag
21
- end
22
- end
23
- end