ansible_make_role 0.7.1 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 29ff2c2883c8a8b4d51a218cd24759b9c30800cf3026da0baf6810ff7b277e46
4
- data.tar.gz: af5a5ff7ba52f8738d90ae5933c98e31d315596eced5ad283611444867bc2708
3
+ metadata.gz: 733a900c1e4713d569c5a7c21e99d5bcff43e771579cf3e720dd15acbdc11da6
4
+ data.tar.gz: 98a2b98de83000661a3951dabd2bee6072e1eabc6a4ec95e861e6296c060dac8
5
5
  SHA512:
6
- metadata.gz: ef8c02faa05b9151e13d431a9d85ab96460a19cb2b898bc46f022a860cf57a7d82e83b7dc7974118cbb9364d7d5ecad09ffb2a142abdc6c998373435f72e0bac
7
- data.tar.gz: 167cf5397c44fb3d961fb6a63ea0242956dcd7542d92af86f1d6c97449a8a0454c4fe62fc3a087a88bec529f2fedf02d2eec8bc6cd950d028aafcf7b9911fc2d
6
+ metadata.gz: 9ad554b57fe864dc11678ba72deed77be3de0dae7ae6b2c699b67c0526c151f8b96fd622ea2e465be7b940eb9ea2dc938cbeec7f6168e1d57fe65b599ea7094f
7
+ data.tar.gz: ee02dca7324c5a4b5dd62ed45cd0a2433e7ff2a55421f9e401365ba267cc3b0c504c2e582785b11b58d7961be3d5ccae7145d2feba2cfdf85c19d35ba0b7c4df
data/README.md CHANGED
@@ -1,19 +1,21 @@
1
1
  # ansible-make-role
2
2
 
3
- Pre-compiler that turns `make.yml` files into Ansible roles
3
+ Pre-compiler that turns single-file `role.yml` files into Ansible roles The
4
+ `role.yml` file combines the Ansible `main.yml` where each `main.yml` file is
5
+ represented by a section (`defaults:`, `vars:`, `tasks:` etc.)
4
6
 
5
7
  ## Usage
6
8
 
7
9
  ```shell
8
- ansible-make-role -f|--force -v|--verbose --version DIR...
10
+ ansible-make-role -c|--clean -f|--force -g|--git -r|--roles=DIR -v|--verbose --version DIR...
9
11
  ```
10
12
 
11
- `ansible-make-role` expects a `make.yml` file in each of the given directories
12
- and generate a Ansible role from each of them. The generated files will reside
13
- in subdirectories of the directory of the `make.yml` file but it can be
14
- overridden by the --target-dir option. `ansible-make-role` only generates
15
- out-of-date files unless the --force option is used. Use the `--verbose` option
16
- to get information about the process
13
+ `ansible-make-role` expects a `role.yml` file in each of the given directories
14
+ and generates an Ansible role in it. Existing `main.yml` files will be
15
+ overwritten or removed but other files won't be touched
16
+
17
+ `ansible-make-role` only generates up-to-date files unless the --force option
18
+ is used
17
19
 
18
20
  ## Description
19
21
 
@@ -53,10 +55,18 @@ handlers: # Goes to handlers/main.yml"
53
55
 
54
56
  ## Options
55
57
 
58
+ `-c, --clean`
59
+ Clean the project by removing autogenerated files
56
60
 
57
61
  `-f, --force`
58
62
  Re-generate all files even if not needed
59
63
 
64
+ `-g, --git`
65
+ Also handle per-role .gitignore files. Note that the .gitignore file will be overwritten
66
+
67
+ `-r, --roles=DIR`
68
+ Use DIR instead of default `./roles`
69
+
60
70
  `-v, --verbose`
61
71
  Report progress
62
72
 
data/TODO ADDED
@@ -0,0 +1,19 @@
1
+
2
+ o Add a "warning: auto-generated" header to all generated files
3
+ o Checksum of files?
4
+ o Warn before overwrite if checksum doesn't match
5
+ o Write comments "connected" to a section in the section file:
6
+
7
+ # Goes to meta/main.yml
8
+
9
+ # Goes to defaults/main.yml
10
+ #
11
+ defaults:
12
+ # Goes to defaults/main.yml
13
+
14
+
15
+ + Only copy templates/files if needed. What to do with directories?
16
+ o Remove orphaned files
17
+
18
+ - (Sym-)link files, templates, and directories?
19
+ - Replace ansible-make-role with an option: "-m - Make a single directory with a 'make.yml' file"
@@ -11,11 +11,10 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{Make Ansible role from make.yml file}
13
13
  spec.description = %q{
14
- Instead of having an Ansible role per-directory
15
- main.yml file, ansible-make-role processes a make.yml
16
- file in the role directory and generates the main.yml
17
- files from that. In make.yml each main.yml definition
18
- is contained in a per-file section: 'defaults',
14
+ ansible-make-role process a single-file role
15
+ definition file and generate an Ansible role from it.
16
+ The role is defined in the role.yml file and contain
17
+ a section for each Ansible main.yml file: 'defaults',
19
18
  'vars', 'tasks', and 'handlers'. Definitions outside
20
19
  of those sections (notably 'dependencies') are going
21
20
  to the meta/main.yml file
@@ -40,8 +39,9 @@ Gem::Specification.new do |spec|
40
39
  spec.require_paths = ["lib"]
41
40
 
42
41
  spec.add_development_dependency "bundler", "~> 1.17"
43
- spec.add_development_dependency "rake", "~> 10.0"
42
+ spec.add_development_dependency "rake", ">= 12.3.3"
44
43
  spec.add_development_dependency "rspec", "~> 3.0"
45
44
 
46
45
  spec.add_dependency "shellopts", "0.9.3"
46
+ spec.add_dependency "indented_io"
47
47
  end
@@ -3,21 +3,72 @@
3
3
  require 'ansible_make_role.rb'
4
4
  require "shellopts"
5
5
 
6
- USAGE = "f,force v,verbose version -- DIRECTORY..."
6
+ USAGE = "c,clean f,force g,git +r,roles=DIR v,verbose version -- DIRECTORY..."
7
7
 
8
+ DEFAULT_ROLES_DIR = "./roles"
9
+
10
+ clean = false
8
11
  force = false
12
+ git = false
13
+ roles_dirs = [] # A roles (plural) directory containing role (singular) directories
9
14
  verbose = false
10
15
 
11
16
  args = ShellOpts.process(USAGE, ARGV) { |opt, arg|
12
17
  case opt
18
+ when '-c', '--clean'; clean = true
13
19
  when '-f', '--force'; force = true
20
+ when '-g', '--git'; git = true
21
+ when '-r', '--roles'
22
+ File.directory?(arg) or ShellOpts::error "Not a directory: #{arg}"
23
+ roles_dirs << arg
14
24
  when '-v', '--verbose'; verbose = true
15
25
  when '--version'; puts "ansible-make-role #{AnsibleMakeRole::VERSION}"; exit
16
26
  end
17
27
  }
18
- args.size > 0 or args << "."
19
28
 
20
- for source in args
21
- File.directory?(source) or ShellOpts.error "Not a directory: #{source.inspect}"
22
- AnsibleMakeRole.make(source, verbose: verbose, force: force)
29
+ AnsibleMakeRole.force = force
30
+ AnsibleMakeRole.git = git
31
+ if verbose
32
+ def verb(*msgs) print(msgs.join, "\n") end
33
+ else
34
+ def verb(*_) end
35
+ end
36
+
37
+ if args.empty? && roles_dirs.empty?
38
+ if File.directory?(DEFAULT_ROLES_DIR)
39
+ roles_dirs << DEFAULT_ROLES_DIR
40
+ else
41
+ ShellOpts::error "No role_dirs given"
42
+ end
43
+ end
44
+
45
+ role_dirs = args
46
+ for roles_dir in roles_dirs
47
+ role_dirs += Dir["#{roles_dir}/*"].select { |d| File.directory?(d) }
48
+ end
49
+
50
+ if role_dirs.empty?
51
+ $stderr.puts "#{PROGRAM}: No role_dirs found"
52
+ exit 0
53
+ end
54
+
55
+ begin
56
+ for role_dir in role_dirs
57
+ if clean
58
+ if AnsibleMakeRole.clean(role_dir)
59
+ verb("Cleaned #{role_dir}")
60
+ else
61
+ verb("Skipped #{role_dir} - already clean")
62
+ end
63
+ else
64
+ if AnsibleMakeRole.make(role_dir)
65
+ verb("Updated #{role_dir}")
66
+ else
67
+ verb("Skipped #{role_dir} - up to date")
68
+ end
69
+ end
70
+ end
71
+ rescue AnsibleMakeRole::Error => ex
72
+ ShellOpts::fail(ex.message)
23
73
  end
74
+
@@ -1,29 +1,74 @@
1
1
  require "ansible_make_role/version"
2
2
 
3
- require "shellopts"
4
-
5
3
  require "fileutils"
6
4
 
7
5
  module AnsibleMakeRole
8
- def self.make(source_dir, verbose: false, force: false)
9
- source = "#{source_dir}/make.yml"
10
- target_dir = source_dir
11
- # TODO: Doesn't belong at this level - catch exceptions in exe instead
12
- File.file?(source) or ShellOpts::error "Can't read file #{source.inspect}"
13
- File.directory?(target_dir) or ShellOpts::error "Can't find directory #{target_dir}"
14
-
15
- meta_yml = "#{target_dir}/meta/main.yml"
16
- if force || !File.exist?(meta_yml) || File.mtime(source) > File.mtime(meta_yml)
17
- compile_role(source, target_dir, verbose: verbose)
18
- else
19
- puts "#{target_dir} is up to date" if verbose
20
- end
6
+ ROLE_FILE_NAME = "role.yml"
7
+
8
+ DEFAULT_FORCE_FLAG = false
9
+ DEFAULT_GIT_FLAG = false
10
+
11
+ class Error < StandardError; end
12
+
13
+ @force = DEFAULT_FORCE_FLAG
14
+ def self.force() @force end
15
+ def self.force=(value) @force = value end
16
+
17
+ @git = DEFAULT_GIT_FLAG
18
+ def self.git() @git end
19
+ def self.git=(value) @git = value end
20
+
21
+ def self.make(role_dir)
22
+ wrap_system_call_error {
23
+ role_file = "#{role_dir}/#{ROLE_FILE_NAME}"
24
+ meta_file = "#{role_dir}/meta/main.yml"
25
+ if force || !File.exist?(meta_file) || File.mtime(role_file) > File.mtime(meta_file)
26
+ files = compile_role(role_file, role_dir)
27
+ if git
28
+ git_file = "#{role_dir}/.gitignore"
29
+ FileUtils.rm_f(git_file)
30
+ if !files.empty?
31
+ lines = files.map { |f| "./" + f.split("/")[-2..-1].join("/") + "\n" }.join
32
+ IO.write(git_file, lines)
33
+ end
34
+ end
35
+ true
36
+ end
37
+ }
38
+ end
39
+
40
+ def self.clean(role_dir)
41
+ changed = false
42
+ wrap_system_call_error {
43
+ File.exists?("#{role_dir}/#{ROLE_FILE_NAME}") or raise Error "Not a role directory: #{role_dir}"
44
+ for file in Dir["#{role_dir}/*/main.yml"]
45
+ FileUtils.rm(file)
46
+ dir = File.dirname(file)
47
+ FileUtils.rmdir(dir) if File.empty?(dir)
48
+ changed = true
49
+ end
50
+ git_file = "#{role_dir}/.gitignore"
51
+ if git && File.exist?(git_file)
52
+ FileUtils.rm(git_file)
53
+ changed = true
54
+ end
55
+ }
56
+ return changed
21
57
  end
22
58
 
23
59
  private
24
- # source is a file, target is a directory. Target can be nil and defaults to
25
- # dirname of source
26
- def self.compile_role(source, target, verbose: false)
60
+ # Turn a SystemCallError into a AnsibleMakeRole::Error exception and remove
61
+ # Ruby reference from message (eg. "@ rb_sysopen")
62
+ def self.wrap_system_call_error(&block)
63
+ begin
64
+ yield
65
+ rescue SystemCallError => ex
66
+ raise Error.new(ex.message.sub(/ @ \w+/, ""))
67
+ end
68
+ end
69
+
70
+ # source is a single-file role and target is the role directory. Returns list generated files
71
+ def self.compile_role(source, target)
27
72
  meta = []
28
73
  sections = {
29
74
  "defaults" => [],
@@ -33,7 +78,6 @@ private
33
78
  }
34
79
  current_section = meta
35
80
 
36
- puts "Parsing #{source}" if verbose
37
81
  File.readlines(source).each { |line|
38
82
  line.chomp!
39
83
  next if line =~ /^---\s*$/
@@ -50,18 +94,21 @@ private
50
94
  end
51
95
  }
52
96
 
97
+ generated_files = []
53
98
  (sections.to_a + [["meta", meta]]).each { |section, lines|
54
99
  next if lines.empty? && section != "meta"
100
+ next if lines.all? { |l| l =~ /^\s*$/ }
55
101
  dir = "#{target}/#{section}"
56
102
  file = "#{dir}/main.yml"
103
+ generated_files << file
57
104
 
58
- puts "Create #{file}" if verbose
59
105
  FileUtils.mkdir_p(dir)
60
- File.open("#{dir}/main.yml", "w") { |f|
106
+ File.open(file, "w") { |f|
61
107
  f.puts "---" if section != "meta"
62
108
  unindent(lines).each { |l| f.puts l }
63
109
  }
64
110
  }
111
+ generated_files
65
112
  end
66
113
 
67
114
  # Unindent lines by the indentation of the first non-comment and non-blank
@@ -74,3 +121,6 @@ private
74
121
  lines.map { |l| l.sub(/^#{prefix}/, "") }
75
122
  end
76
123
  end
124
+
125
+
126
+
@@ -1,3 +1,3 @@
1
1
  module AnsibleMakeRole
2
- VERSION = "0.7.1"
2
+ VERSION = "0.7.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ansible_make_role
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-15 00:00:00.000000000 Z
11
+ date: 2020-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,14 +66,27 @@ dependencies:
66
66
  - - '='
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.9.3
69
- description: "\n Instead of having an Ansible role per-directory\n
70
- \ main.yml file, ansible-make-role processes a make.yml\n
71
- \ file in the role directory and generates the main.yml\n
72
- \ files from that. In make.yml each main.yml definition\n
73
- \ is contained in a per-file section: 'defaults',\n 'vars',
74
- 'tasks', and 'handlers'. Definitions outside\n of those
75
- sections (notably 'dependencies') are going\n to the meta/main.yml
76
- file\n "
69
+ - !ruby/object:Gem::Dependency
70
+ name: indented_io
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: "\n ansible-make-role process a single-file
84
+ role\n definition file and generate an Ansible role from
85
+ it.\n The role is defined in the role.yml file and contain\n
86
+ \ a section for each Ansible main.yml file: 'defaults',\n
87
+ \ 'vars', 'tasks', and 'handlers'. Definitions outside\n
88
+ \ of those sections (notably 'dependencies') are going\n
89
+ \ to the meta/main.yml file\n "
77
90
  email:
78
91
  - claus.l.rasmussen@gmail.com
79
92
  executables:
@@ -88,6 +101,7 @@ files:
88
101
  - Gemfile
89
102
  - README.md
90
103
  - Rakefile
104
+ - TODO
91
105
  - ansible_make_role.gemspec
92
106
  - bin/console
93
107
  - bin/setup