ian 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fcf55fe8183aa26141bafc1011ff313f325531ff
4
+ data.tar.gz: 43770450bb488b08e7b546274ecefc0646b133df
5
+ SHA512:
6
+ metadata.gz: c705fadaad72699deedc70fd6e1a34c9bd8f2dcb44563dc0336b5aac206a0e80e203259d0c06dbc39b9824946fdb896a2e2a52a3cdae8556c802d9ae75510a22
7
+ data.tar.gz: 0b0fe9a490eb2c685ad2f831c0995691b20ab44211f9cc82b9eef41260e65dd9d96657c28ff5688507462e9be2c11cba8048f7630e0eafc8deeacc1bfa7f82d3
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ian.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Ian
2
+
3
+ A Debian CLI package hacking tool named in memory of the late Ian Murdock.
4
+
5
+ This tool will help you to create and maintain the source repos for Debain
6
+ packages and tries to mimic the CLI of other popular tools such as git and
7
+ bundler.
8
+
9
+ It is intended to be helpful when integrating other build tools/systems and
10
+ with CI/CD.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'ian'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install ian
27
+
28
+ ## Usage
29
+
30
+ Create a new package (like `bundle new gemname`):
31
+
32
+ $ ian new mycoolpackage
33
+
34
+ Init an existing directory (like `git init`):
35
+
36
+ $ ian init
37
+
38
+ Show the info for the package (basically `cat DEBAIN/control`):
39
+
40
+ $ ian info
41
+
42
+ Set info in the control file:
43
+
44
+ $ ian set -v 2.3.1-beta
45
+ $ ian set -a amd64
46
+
47
+ Build a package:
48
+
49
+ $ ian pkg
50
+
51
+ Before building a package ian will determine the installed size, leave out any
52
+ cruft (such as the `.git` directory) and move READMEs and the like to `/usr/share/doc`.
53
+
54
+ ## TODO
55
+
56
+ - [ ] MD5sums generation
57
+ - [x] finish package generation code
58
+ - [ ] ADD SPECS!!!!
59
+
60
+ ## Development
61
+
62
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
63
+
64
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
65
+
66
+ ## Contributing
67
+
68
+ Bug reports and pull requests are welcome on GitHub at https://github.com/penguinpowernz/ian.
69
+
70
+ ## In Memory Of
71
+
72
+ In memory of Ian Ashley Murdock (1973 - 2015) founder of the Debian project.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ian"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/ian ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'slop'
4
+ require 'logger'
5
+ require 'ian'
6
+
7
+ IAN_DIR = Dir.pwd
8
+
9
+ def initialized?
10
+ File.directory?("#{IAN_DIR}/DEBIAN") and
11
+ File.exist?("#{IAN_DIR}/DEBIAN/control")
12
+ end
13
+
14
+ log = Logger.new(STDOUT)
15
+
16
+ Slop.parse help: true do
17
+
18
+ on :v, "Print the version" do
19
+ puts Ian::VERSION
20
+ exit
21
+ end
22
+
23
+ command :new do
24
+ description "Create a new Debian package from scratch"
25
+
26
+ run do |opts, args|
27
+ name = args.first
28
+
29
+ if name.nil?
30
+ abort "Must provide name as the first argument"
31
+ end
32
+
33
+ if File.directory?(name)
34
+ abort "Directory '#{name}' exists"
35
+ end
36
+
37
+ Ian.create(name)
38
+ end
39
+ end
40
+
41
+
42
+ command :init do
43
+ description "Initialize the current folder as a Debian package"
44
+
45
+ run do |opts, args|
46
+ abort "Already initialized." if initialized?
47
+ Ian.init(IAN_DIR, log)
48
+ end
49
+ end
50
+
51
+ command :pkg do
52
+ description "Build a Debian package"
53
+
54
+ run do |opts, args|
55
+ pkg = Ian.build_package(IAN_DIR, log)
56
+ log.info "Package built to #{pkg}"
57
+ end
58
+ end
59
+
60
+ command :set do
61
+ description "Modify the Debian control file"
62
+
63
+ on :v, :version=, "Change the version"
64
+ on :a, :arch=, "Change the architecture"
65
+
66
+ run do |opts, args|
67
+ c = Ian.control(IAN_DIR)
68
+ c.update(opts.to_hash)
69
+ c.save
70
+ puts "Updated control file"
71
+ end
72
+ end
73
+
74
+ command :info do
75
+ description "Print information for this package"
76
+
77
+ run do |opts, args|
78
+ puts Ian.control(IAN_DIR)
79
+ end
80
+ end
81
+
82
+ command :deps do
83
+ description "Print dependencies for this package"
84
+
85
+ run do |opts, args|
86
+ ctrl = Ian.control(IAN_DIR)
87
+ ctrl[:depends].each do |dep|
88
+ puts dep
89
+ end
90
+ end
91
+ end
92
+
93
+ end
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/ian.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ian/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ian"
8
+ spec.version = Ian::VERSION
9
+ spec.authors = ["Robert McLeod"]
10
+ spec.email = ["robert@autogrow.com"]
11
+
12
+ spec.summary = %q{Gem for manipulating Debian source packages from CLI}
13
+ spec.description = %q{Gem for manipulating Debian source packages from CLI}
14
+ spec.homepage = "http://penguinpowernz.github.io/ian"
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
20
+ else
21
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ spec.bindir = "bin"
26
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency "slop", "= 3.6.0"
30
+
31
+ spec.add_development_dependency "bundler", "~> 1.12"
32
+ spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rspec", "~> 3.0"
34
+ end
data/lib/ian.rb ADDED
@@ -0,0 +1,66 @@
1
+
2
+ require 'ian/version'
3
+ require 'ian/control'
4
+ require 'ian/packager'
5
+ require 'ian/utils'
6
+
7
+ require 'fileutils'
8
+
9
+ module Ian
10
+
11
+ class << self
12
+
13
+ def debpath(path)
14
+ "#{path}/DEBIAN"
15
+ end
16
+
17
+ def ctrlpath(path)
18
+ "#{debpath(path)}/control"
19
+ end
20
+
21
+ def create(name)
22
+ FileUtils.mkdir(name)
23
+
24
+ init(name)
25
+ end
26
+
27
+ def init(path, log)
28
+ FileUtils.mkdir(debpath(path))
29
+
30
+ control(path).save
31
+ log.info "Generated #{path}"
32
+
33
+ pi = "#{debpath(path)}/postinst"
34
+
35
+ File.write(pi, "#!/bin/bash\n\n\nexit 0;")
36
+ log.info "Generated #{pi}"
37
+
38
+ FileUtils.chmod(0755, Dir["#{debpath(path)}/*"])
39
+ FileUtils.chmod(0755, debpath(path))
40
+
41
+ #cfg = {}
42
+
43
+ #File.write("#{path}/ian.yml", cfg.to_yaml)
44
+ #log.info "Generated ian.yml"
45
+
46
+ File.write("#{path}/.ianignore", "pkg\n")
47
+ log.info "Generated .ianignore"
48
+ end
49
+
50
+ def control(path)
51
+ Ian::Control.new(ctrlpath(path))
52
+ end
53
+
54
+ def build_package(path, log)
55
+ c = control(path)
56
+ c[:size] = Utils.determine_installed_size(path)
57
+ c.save
58
+
59
+ pkgr = Ian::Packager.new(path, c, log)
60
+ pkgr.run
61
+ end
62
+
63
+
64
+ end
65
+
66
+ end
@@ -0,0 +1,129 @@
1
+ module Ian
2
+ class Control
3
+ attr_reader :path
4
+
5
+ def initialize(path)
6
+ @path = path
7
+
8
+ if File.exist?(@path)
9
+ parse
10
+ else
11
+ @fields = defaults
12
+ end
13
+ end
14
+
15
+ # allow setting fields directly
16
+ def []=(field, value)
17
+ raise ArgumentError, "Invalid field: #{field}" unless defaults.keys.include?(field)
18
+ @fields[field] = value
19
+ end
20
+
21
+ # allow reading fields directly
22
+ def [](field)
23
+ @fields[field]
24
+ end
25
+
26
+ # parse this control file into the fields hash
27
+ def parse
28
+ text = File.read(@path)
29
+
30
+ @fields = {}
31
+
32
+ fields.each do |f, name|
33
+ m = text.match(/^#{name}: (.*)$/)
34
+ next unless m
35
+ @fields[f] = m[1]
36
+ end
37
+
38
+ if @fields[:depends]
39
+ @fields[:depends] = @fields[:depends].split(",").map! {|d| d.strip }
40
+ end
41
+
42
+ @fields[:long_desc] = text.scan(/^ (.*)$/).flatten
43
+ end
44
+
45
+ # update a bunch of fields
46
+ def update(hash)
47
+ hash.each do |k, v|
48
+ if fields.keys.include?(k) and v
49
+ @fields[k] = v
50
+ end
51
+ end
52
+ end
53
+
54
+ # output the control file as a string
55
+ def to_s
56
+ lines = []
57
+
58
+ [:package, :version, :section, :priority, :arch, :essential, :size, :maintainer, :homepage].each do |key|
59
+ lines << "#{fields[key]}: #{@fields[key]}"
60
+ end
61
+
62
+ if @fields[:depends] and @fields[:depends].any?
63
+ lines << "Depends: #{@fields[:depends].join(", ")}"
64
+ end
65
+
66
+ lines << "Description: #{@fields[:desc]}"
67
+
68
+ lines += @fields[:long_desc].map do |ld|
69
+ " #{ld}"
70
+ end
71
+
72
+ lines << "" # blank line as per debian control spec
73
+ lines.join("\n")
74
+ end
75
+
76
+ # save the control file to disk
77
+ def save
78
+ File.write(@path, to_s)
79
+ end
80
+
81
+ # TODO: move this out of here
82
+ def guess_maintainer
83
+ text = File.read("#{ENV['HOME']}/.gitconfig")
84
+ name = text.match(/name = (.*)$/)[1]
85
+ email = text.match(/email = (.*)$/)[1]
86
+
87
+ "#{name} <#{email}>"
88
+ rescue
89
+ return ""
90
+ end
91
+
92
+ def defaults
93
+ {
94
+ package: "name",
95
+ priority: "optional",
96
+ section: "misc",
97
+ essential: "no",
98
+ size: 0,
99
+ maintainer: guess_maintainer,
100
+ homepage: "http://example.com",
101
+ arch: "all",
102
+ version: "0.0.1",
103
+ depends: [],
104
+ desc: "This is a description",
105
+ long_desc: [
106
+ "This is a longer description that can take",
107
+ "up multiple lines"
108
+ ]
109
+ }
110
+ end
111
+
112
+ def fields
113
+ {
114
+ package: "Package",
115
+ depends: "Depends",
116
+ version: "Version",
117
+ priority: "Priority",
118
+ section: "Section",
119
+ essential: "Essential",
120
+ size: "Installed-Size",
121
+ maintainer: "Maintainer",
122
+ homepage: "Homepage",
123
+ arch: "Architecture",
124
+ desc: "Description"
125
+ }
126
+ end
127
+
128
+ end
129
+ end
@@ -0,0 +1,113 @@
1
+ require 'tmpdir'
2
+ require 'fileutils'
3
+
4
+ module Ian
5
+ class Packager
6
+ def initialize(path, ctrl, log)
7
+ @path = path
8
+ @ctrl = ctrl
9
+ @log = log
10
+ end
11
+
12
+ # run the packager
13
+ def run
14
+ @dir = Dir.mktmpdir
15
+
16
+ success = copy_contents
17
+
18
+ if success
19
+ @log.info("Copied files for packaging to #{@dir}")
20
+ else
21
+ raise StandardError, "Failed to copy files for packaging"
22
+ end
23
+
24
+ move_root_files
25
+ success, pkg, output = *build
26
+
27
+ raise RuntimeError, "Failed to build package: #{output}" unless success
28
+
29
+ pkg
30
+ ensure
31
+ FileUtils.rm_rf @dir if File.exist? @dir
32
+ end
33
+
34
+ # copy the contents to a tmp dir
35
+ def copy_contents
36
+ cmd = rsync_cmd
37
+
38
+ @log.debug "Copying contents with: #{cmd}"
39
+
40
+ %x[#{cmd}]
41
+ $?.success?
42
+ end
43
+
44
+ # move extraneous stuff like README and CHANGELOG to /usr/share/doc
45
+ def move_root_files
46
+ docs = "#{@dir}/usr/share/docs/#{pkgname}"
47
+ files = %x[find #{@dir} -type f -maxdepth 1].lines.map {|l| l.chomp}
48
+ raise RuntimeError, "Unable to copy root files" unless $?.success?
49
+
50
+ FileUtils.mkdir_p(docs)
51
+
52
+ # move all the files from the root of the package
53
+ files.each do |file|
54
+ next unless File.exist?(file)
55
+ FileUtils.mv(file, docs)
56
+ @log.info "#{file} => usr/share/docs/#{pkgname}"
57
+ end
58
+ end
59
+
60
+ # build the package out of the temp dir
61
+ def build
62
+ pkgdir = File.join(@path, "pkg")
63
+ FileUtils.mkdir_p pkgdir
64
+
65
+ FileUtils.chmod(0755, Dir["#{Ian.debpath(@dir)}/*"])
66
+ FileUtils.chmod(0755, Ian.debpath(@dir))
67
+
68
+ pkg = File.join(pkgdir, "#{pkgname}.deb")
69
+ output = %x[dpkg-deb -b #{@dir} #{pkg}]
70
+
71
+ return [$?.success?, pkg, output]
72
+ end
73
+
74
+ private
75
+
76
+ def pkgname
77
+ parts = [
78
+ @ctrl[:package],
79
+ @ctrl[:version],
80
+ @ctrl[:arch]
81
+ ]
82
+
83
+ "%s_%s_%s" % parts
84
+ end
85
+
86
+ # generate the rsync command
87
+ def rsync_cmd
88
+ cmd = "rsync -ra #{@path}/* #{@dir}"
89
+
90
+ # exclude the files
91
+ excludes.each do |x|
92
+ cmd << " --exclude=#{x}"
93
+ end
94
+
95
+ cmd
96
+ end
97
+
98
+ def excludes
99
+ files = %w[.git .gitignore .ianignore]
100
+
101
+ File.read(File.join(@path, ".ianignore")).lines.each do |ign|
102
+ next if ign.start_with? "#"
103
+
104
+ ign.chomp!
105
+ igns = Dir["#{@path}/#{ign}"]
106
+ next if igns.empty?
107
+
108
+ files+= igns
109
+ end
110
+ end
111
+
112
+ end
113
+ end
data/lib/ian/utils.rb ADDED
@@ -0,0 +1,10 @@
1
+ module Ian
2
+ module Utils
3
+ extend self
4
+
5
+ def determine_installed_size(path)
6
+ %x[du #{path} -ks --exclude=".git"].split.first
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Ian
2
+ VERSION = "0.4.3"
3
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ian
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.3
5
+ platform: ruby
6
+ authors:
7
+ - Robert McLeod
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: slop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.6.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.6.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: Gem for manipulating Debian source packages from CLI
70
+ email:
71
+ - robert@autogrow.com
72
+ executables:
73
+ - console
74
+ - ian
75
+ - setup
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".gitignore"
80
+ - ".rspec"
81
+ - ".travis.yml"
82
+ - Gemfile
83
+ - README.md
84
+ - Rakefile
85
+ - bin/console
86
+ - bin/ian
87
+ - bin/setup
88
+ - ian.gemspec
89
+ - lib/ian.rb
90
+ - lib/ian/control.rb
91
+ - lib/ian/packager.rb
92
+ - lib/ian/utils.rb
93
+ - lib/ian/version.rb
94
+ homepage: http://penguinpowernz.github.io/ian
95
+ licenses: []
96
+ metadata:
97
+ allowed_push_host: https://rubygems.org
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.5.1
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Gem for manipulating Debian source packages from CLI
118
+ test_files: []