appifier 0.1.2 → 0.3.0

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/VERSION +1 -1
  4. data/appifier.gemspec +6 -0
  5. data/exe/app +10 -0
  6. data/lib/appifier/actors/collector.rb +20 -16
  7. data/lib/appifier/actors/generator.rb +14 -3
  8. data/lib/appifier/actors/retriever.rb +21 -5
  9. data/lib/appifier/cli/configuration.rb +40 -2
  10. data/lib/appifier/cli/datasets.rb +75 -0
  11. data/lib/appifier/cli/templates.rb +53 -5
  12. data/lib/appifier/cli.rb +36 -11
  13. data/lib/appifier/components/Appifile.rb +52 -10
  14. data/lib/appifier/components/dataset.rb +60 -0
  15. data/lib/appifier/components/template.rb +125 -0
  16. data/lib/appifier/setup.rb +26 -3
  17. data/lib/appifier.rb +6 -10
  18. data/samples/baddummy/Appifile +18 -0
  19. data/samples/baddummy/skeleton/%%APPNAME.downcase%%/.rspec +0 -0
  20. data/samples/baddummy/skeleton/%%APPNAME.downcase%%/Rakefile +0 -0
  21. data/samples/baddummy/skeleton/%%APPNAME.downcase%%/config.ru +0 -0
  22. data/samples/baddummy/skeleton/%%APPNAME.downcase%%/exe/%%APPNAME.downcase%% +0 -0
  23. data/samples/baddummy/skeleton/%%APPNAME.downcase%%/lib/%%APPNAME.downcase%%.rb +0 -0
  24. data/samples/baddummy/skeleton/%%APPNAME.downcase%%/spec/%%APPNAME.downcase%%_spec.rb +0 -0
  25. data/samples/baddummy.tgz +0 -0
  26. data/samples/dummy/Appifile +8 -1
  27. data/samples/dummy/README.md +4 -0
  28. data/samples/dummy.tgz +0 -0
  29. data/samples/dummy_warn/Appifile +19 -0
  30. data/samples/dummy_warn/skeleton/%%APPNAME.downcase%%/.rspec +0 -0
  31. data/samples/dummy_warn/skeleton/%%APPNAME.downcase%%/Rakefile +0 -0
  32. data/samples/dummy_warn/skeleton/%%APPNAME.downcase%%/config.ru +0 -0
  33. data/samples/dummy_warn/skeleton/%%APPNAME.downcase%%/exe/%%APPNAME.downcase%% +0 -0
  34. data/samples/dummy_warn/skeleton/%%APPNAME.downcase%%/lib/%%APPNAME.downcase%%.rb +0 -0
  35. data/samples/dummy_warn/skeleton/%%APPNAME.downcase%%/spec/%%APPNAME.downcase%%_spec.rb +0 -0
  36. metadata +111 -7
  37. data/lib/appifier/components/templates.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aeea227ea8e3eaa87c58fcbd7333297f73b7e2c82f7ba51da9b8bccb4f979f05
4
- data.tar.gz: 3121f0753db7fbc4b8d68f2acfaf141cf9ee9785f5abfc5edca2b5a645faa942
3
+ metadata.gz: bc6decc46de1031b29f5752b5a8e9e19ff34503910f853a796c13becde17f516
4
+ data.tar.gz: 7cf6cff0288638c120c74f815087ea5e668a1299b1cde1407f0e42b46286057a
5
5
  SHA512:
6
- metadata.gz: d7aceeba188e836380bd52eebdfb87839c6227f79282e2ae90fe12d1486d03c4dbb53147c61abb84d4aab172bca8e10b8d7aa419b214e0f0bb151bbd30e4a17c
7
- data.tar.gz: 90fa233237110cfc8c815e6d3002dbc831eaf08b9979d9f0d499f9d08228768c87e519f212fde8241ee9c944f158d90cadbe9924fc4031bd8a8eaa42a6165873
6
+ metadata.gz: 1383dc7d00f324f6831066639eb4ae19577571ba6c3cf0eaa712fae13d41997ffa56ae10b90d74a9249c8fe8a18f29f1bc24b103f9a2bdaccb28934dc594ccd0
7
+ data.tar.gz: adb3a368020d53a60a880baba3f688b65e8b608224c1227e26acd9850d76753c85ddd64e77abe59635eed4f075369884eecadf29275ce8717866de29da36bb5d
data/Gemfile CHANGED
@@ -3,3 +3,4 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.3.0
data/appifier.gemspec CHANGED
@@ -37,4 +37,10 @@ Gem::Specification.new do |spec|
37
37
  spec.add_dependency 'carioca', '~> 2.0.9'
38
38
  spec.add_dependency 'thor', '~> 1.2'
39
39
  spec.add_dependency 'tty-prompt', '~> 0.23.1'
40
+ spec.add_dependency "thot", "~> 1.0"
41
+ spec.add_dependency "git", "~> 1.12"
42
+ spec.add_dependency "schash","~> 0.1.2"
43
+ spec.add_dependency "tty-tree", "~> 0.4.0"
44
+ spec.add_dependency "tty-markdown", "~> 0.7.0"
45
+ spec.add_dependency "tty-link", "~> 0.1.1"
40
46
  end
data/exe/app ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'appifier'
5
+
6
+ require 'appifier/cli'
7
+
8
+ include Appifier::CLI
9
+
10
+ MainCommand.start(ARGV)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- require "tty-prompt"
2
+
3
3
 
4
4
  module Appifier
5
5
  module Actors
@@ -7,6 +7,7 @@ module Appifier
7
7
 
8
8
  extend Carioca::Injector
9
9
  inject service: :output
10
+ inject service: :finisher
10
11
 
11
12
  attr_accessor :dataset
12
13
  attr_reader :template
@@ -19,22 +20,25 @@ module Appifier
19
20
 
20
21
 
21
22
  def collect
22
-
23
- appifilename = "#{File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)}/#{template}/Appifile"
24
- appifile = Appifier::Components::Appifile::new path: appifilename
25
- prompt = TTY::Prompt.new
26
- @dataset = {}
27
- appifile.dataset_rules.each do |name, rule|
28
- default = (rule[:default])? rule[:default] : ""
29
- @dataset[name] = prompt.ask("Give #{rule[:description]} : ", default: default) do |q|
30
- q.required true
31
- q.validate Regexp.new(rule[:format]) if rule[:format]
32
- end
23
+ begin
24
+ appifilename = "#{File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)}/#{template}/Appifile"
25
+ appifile = Appifier::Components::Appifile::new path: appifilename
26
+ prompt = TTY::Prompt.new
27
+ @dataset = {}
28
+ appifile.dataset_rules.each do |name, rule|
29
+ default = (rule[:default])? rule[:default] : ""
30
+ @dataset[name] = prompt.ask("Give #{rule[:description]} : ", default: default) do |q|
31
+ q.required true
32
+ q.validate Regexp.new(rule[:format]) if rule[:format]
33
+ end
34
+ end
35
+ write_dataset template: @template, data: @dataset
36
+ @collected = true
37
+ output.info "Dataset recorded for #{@template}"
38
+ rescue TTY::Reader::InputInterrupt
39
+ output.warn "Interactive collect interrupted"
40
+ finisher.terminate exit_case: :interrupt
33
41
  end
34
- write_dataset template: @template, data: @dataset
35
- @collected = true
36
- output.info "Dataset recorded for #{@template}"
37
-
38
42
  end
39
43
 
40
44
  def collected?
@@ -9,8 +9,9 @@ module Appifier
9
9
  inject service: :output
10
10
 
11
11
 
12
- def initialize(src_root:, target_root:, dataset: )
13
- @src_root = src_root
12
+ def initialize(template_root:, target_root:, dataset: )
13
+ @template_root = template_root
14
+ @src_root = "#{template_root}/skeleton"
14
15
  @target_root = target_root
15
16
  @target_folders = []
16
17
  @target_files = []
@@ -19,7 +20,7 @@ module Appifier
19
20
  @src_paths.delete_if { |file| file =~ %r{/\.$} }
20
21
  @src_folders = @src_paths.select { |item| File.directory? item }
21
22
  @src_files = @src_paths.select { |item| File.file? item }
22
- raise 'Application template not found' unless File.exist?(src_root)
23
+ raise 'Application template not found' unless File.exist?(@template_root)
23
24
  end
24
25
 
25
26
  def generate(dry_run: false, force: false)
@@ -31,6 +32,7 @@ module Appifier
31
32
  generate_folders dry_run: dry_run
32
33
  output.info 'Generate files'
33
34
  generate_files dry_run: dry_run
35
+ copy_appifile dry_run: dry_run
34
36
  end
35
37
 
36
38
  def calculate
@@ -53,6 +55,15 @@ module Appifier
53
55
  end
54
56
  end
55
57
 
58
+
59
+ def copy_appifile(dry_run:)
60
+ output.info "Copy Appifile in #{@target_root} :"
61
+ action = dry_run ? :skipped : :ok
62
+ FileUtils.cp "#{@template_root}/Appifile", @target_root unless dry_run
63
+ output.send action, "Install Appifile"
64
+ end
65
+
66
+
56
67
  def generate_files(dry_run:)
57
68
  output.info "Target files to create in #{@target_root} :"
58
69
  @src_files.each_with_index do |path, index|
@@ -1,18 +1,27 @@
1
1
  # frozen_string_literal: false
2
-
2
+ require 'git'
3
+ require 'uri'
3
4
  module Appifier
4
5
  module Actors
5
6
  module Retrivers
6
7
  class Git
7
- def self.get(origin:, destination:);
8
- raise 'not yest implemented'
8
+ def self.get(origin:, destination:)
9
+ uri = URI.parse(origin)
10
+ path = uri.path
11
+ name = File.basename(path, ".git")
12
+ raise "Git URL format failed (only http bare git format)" if name.include?('.')
13
+ ::Git.clone(origin, nil, path: destination)
14
+ return name
9
15
  end
10
16
  end
11
17
 
12
18
  class Archive
13
19
  def self.get(origin:, destination:)
14
20
  raise "Archive : #{origin} not found" unless File::exist? origin
21
+ name = File.basename(origin, ".tgz")
22
+ raise "Template name format failed : must be .tgz file" if name.include?('.')
15
23
  untar_gz archive: origin, destination: destination
24
+ return name
16
25
  end
17
26
  end
18
27
  end
@@ -27,11 +36,18 @@ module Appifier
27
36
  @origin = origin
28
37
  @type = type
29
38
  @destination = destination
30
- output.info "retrieving template from #{origin}"
39
+ output.info "Retrieving template from #{origin}"
31
40
  end
32
41
 
33
42
  def get
34
- TYPE[@type].get origin: @origin, destination: @destination
43
+ template = TYPE[@type].get origin: @origin, destination: @destination
44
+ result = Appifier::Components::Template.validate!(template: template)
45
+ unless result[:error].empty?
46
+ output.ko "Template #{template} retrieving cancelled"
47
+ Appifier::Components::Template.rm(template) unless result[:error].empty?
48
+
49
+ end
50
+ return result
35
51
  end
36
52
  end
37
53
  end
@@ -4,13 +4,51 @@ module Appifier
4
4
  module CLI
5
5
  module Subcommands
6
6
  class Configuration < ::Thor
7
+
8
+ def initialize(*args)
9
+ super
10
+ @output = Carioca::Registry.get.get_service name: :output
11
+ @finisher = Carioca::Registry.get.get_service name: :finisher
12
+ end
13
+
7
14
  # Thor method : running of Appifier sanitycheck
8
15
  desc 'sanitycheck', 'Verify installation of Appifier for user'
9
- def sanitycheck; end
16
+ def sanitycheck
17
+ Appifier::Configuration::Checker.sanitycheck
18
+
19
+ end
20
+
21
+
22
+ # Thor method : running of Appifier setup for config rebuild [DANGER]
23
+ desc 'reset', 'Running Appifier setup for configuration rebuild [DANGER]'
24
+ long_desc <<-LONGDESC
25
+ Running Appifier setup for configuration rebuild [DANGER]\n
26
+ with --force => force collect, and destroy previous configuration [DANGER]
27
+ LONGDESC
28
+ option :force, type: :boolean, aliases: '-F'
29
+ def reset
30
+ begin
31
+ raise "[DANGER] please add -F if you sure : appifier configuration reset -F" unless options[:force]
32
+ @output.warn "Appifier reset configuration"
33
+ Appifier::Configuration.setup force: true
34
+ @finisher.terminate exit_case: :quiet_exit
35
+ rescue RuntimeError => e
36
+ @output.error e.message
37
+ @finisher.terminate exit_case: :error_exit
38
+ end
39
+
40
+ end
10
41
 
11
42
  # Thor method : Getting the current Appifier version
12
43
  desc 'version', 'Display current Appifier version'
13
- def version; end
44
+ def version;
45
+ @output.info "Querying version"
46
+ puts 'Appifier (c) Ultragreen Software'
47
+ puts "Camille PAQUET - Romain GEORGES "
48
+ puts TTY::Link.link_to("http://www.ultragreen.net", "http://www.ultragreen.net")
49
+ puts "Version #{Appifier::VERSION}"
50
+ @finisher.terminate exit_case: :quiet_exit
51
+ end
14
52
  end
15
53
  end
16
54
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+ module Appifier
3
+ module CLI
4
+ module Subcommands
5
+ class Datasets < ::Thor
6
+
7
+ def initialize(*args)
8
+ super
9
+ @output = Carioca::Registry.get.get_service name: :output
10
+ @finisher = Carioca::Registry.get.get_service name: :finisher
11
+ end
12
+
13
+ # Thor method : list availables datasets in user bundle
14
+ desc 'ls', 'list defined datasets in user bundle'
15
+ def ls
16
+ begin
17
+ Appifier::Components::Dataset::list
18
+ @finisher.terminate exit_case: :quiet_exit
19
+ rescue RuntimeError => e
20
+ @output.error e.message
21
+ @finisher.terminate exit_case: :error_exit
22
+ end
23
+ end
24
+
25
+ # Thor method : show a specific dataset in user bundle
26
+ desc 'show DATASET', 'show a specific dataset in user bundle'
27
+ def show(dataset)
28
+ begin
29
+ Appifier::Components::Dataset::show dataset
30
+ @finisher.terminate exit_case: :quiet_exit
31
+ rescue RuntimeError => e
32
+ @output.error e.message
33
+ @finisher.terminate exit_case: :error_exit
34
+ end
35
+ end
36
+
37
+ # Thor method : remove a dataset from user bundle
38
+ desc 'rm DATASET', 'Remove dataset from user bundle'
39
+ def rm(dataset)
40
+ begin
41
+ Appifier::Components::Dataset::rm(dataset)
42
+ @finisher.terminate exit_case: :quiet_exit
43
+ rescue RuntimeError => e
44
+ @output.error e.message
45
+ @finisher.terminate exit_case: :error_exit
46
+ end
47
+ end
48
+
49
+
50
+ # Thor method : Prune orphans datasets in user bundle
51
+ desc 'prune', 'Prune orphans datasets in user bundle'
52
+ long_desc <<-LONGDESC
53
+ Prune orphans datasets in user bundle\n
54
+ with --force, force pruning of dataset [DANGER]
55
+ LONGDESC
56
+ option :force, type: :boolean, aliases: '-F'
57
+ def prune
58
+ begin
59
+ ok = (options[:force]) ? true : TTY::Prompt.new.yes?("Do you want to prune datasets?")
60
+ if ok
61
+ Appifier::Components::Dataset::prune
62
+ @finisher.terminate exit_case: :quiet_exit
63
+ else
64
+ puts "Pruning cancelled"
65
+ @finisher.terminate exit_case: :quiet_exit
66
+ end
67
+ rescue TTY::Reader::InputInterrupt
68
+ @output.warn "Command interrupted"
69
+ @finisher.terminate exit_case: :interrupt
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
-
2
+ require 'tty-markdown'
3
3
  module Appifier
4
4
  module CLI
5
5
  module Subcommands
@@ -14,15 +14,63 @@ module Appifier
14
14
  # Thor method : list availables templates in user bundle
15
15
  desc 'ls', 'list templates availables in user bundle'
16
16
  def ls
17
- Appifier::Components::Templates::list
18
- @finisher.terminate exit_case: :error_exit
17
+ begin
18
+ Appifier::Components::Template::list
19
+ @finisher.terminate exit_case: :quiet_exit
20
+ rescue RuntimeError => e
21
+ @output.error e.message
22
+ @finisher.terminate exit_case: :error_exit
23
+ end
19
24
  end
20
25
 
21
26
  # Thor method : remove a template from user bundle
22
- desc 'rm', 'rm templates from user bundle'
27
+ desc 'rm TEMPLATE', 'Remove templates from user bundle'
23
28
  def rm(template)
24
29
  begin
25
- Appifier::Components::Templates::rm(template)
30
+ Appifier::Components::Template::rm(template)
31
+ @finisher.terminate exit_case: :quiet_exit
32
+ rescue RuntimeError => e
33
+ @output.error e.message
34
+ @finisher.terminate exit_case: :error_exit
35
+ end
36
+ end
37
+
38
+ # Thor method : show information for a specific template in user bundle
39
+ desc 'show TEMPLATE', 'show information for a specific template in user bundle'
40
+ def show(template)
41
+ begin
42
+ Appifier::Components::Template::show(template)
43
+ temp = Appifier::Components::Template::new(template: template)
44
+ if temp.readme?
45
+ puts " "
46
+ puts TTY::Markdown.parse_file(temp.readme_path)
47
+ end
48
+
49
+ @finisher.terminate exit_case: :quiet_exit
50
+ rescue RuntimeError => e
51
+ @output.error e.message
52
+ @finisher.terminate exit_case: :error_exit
53
+ end
54
+ end
55
+
56
+ # Thor method : display directory tree view for a specific template in user bundle
57
+ desc 'treeview TEMPLATE', 'display directory tree view for a specific template in user bundle'
58
+ def treeview(template)
59
+ begin
60
+ Appifier::Components::Template::treeview(template)
61
+ @finisher.terminate exit_case: :quiet_exit
62
+ rescue RuntimeError => e
63
+ @output.error e.message
64
+ @finisher.terminate exit_case: :error_exit
65
+ end
66
+ end
67
+
68
+ # Thor method : lint a specific template in user bundle
69
+ desc 'lint TEMPLATE', 'Lint a specific template in user bundle'
70
+ def lint(template)
71
+ begin
72
+ Appifier::Components::Template::lint(template)
73
+ @finisher.terminate exit_case: :quiet_exit
26
74
  rescue RuntimeError => e
27
75
  @output.error e.message
28
76
  @finisher.terminate exit_case: :error_exit
data/lib/appifier/cli.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  require 'appifier'
4
- require 'thor'
5
4
 
6
5
  Dir["#{File.dirname(__FILE__)}/cli/*.rb"].sort.each { |file| require file }
7
6
 
@@ -22,6 +21,9 @@ module Appifier
22
21
  true
23
22
  end
24
23
 
24
+ desc 'datasets SUBCOMMAND ...ARGS', 'Managing apps datasets'
25
+ subcommand 'datasets', Subcommands::Datasets
26
+
25
27
  desc 'templates SUBCOMMAND ...ARGS', 'Managing apps templates'
26
28
  subcommand 'templates', Subcommands::Templates
27
29
 
@@ -29,28 +31,45 @@ module Appifier
29
31
  subcommand 'configuration', Subcommands::Configuration
30
32
 
31
33
  # Thor method : running of Appifier generate
32
- desc 'generate TEMPLATE [TARGET]', 'Generate application from bundled template'
34
+ desc 'generate TEMPLATE [TARGET]', 'Generate application from bundled template (IF TARGET ommited use the current path as ROOTPATH)'
33
35
  long_desc <<-LONGDESC
34
36
  Generate application from bundled template\n
35
- with --simulate, only simulate folders and files installed
37
+ (IF TARGET ommited use the current path as ROOTPATH)\n
38
+ with --simulate, only simulate folders and files installed\n
36
39
  with --force, force regeneration of application, remove old files [DANGER]
37
40
  LONGDESC
38
41
  option :simulate, type: :boolean, aliases: '-s'
39
42
  option :force, type: :boolean, aliases: '-F'
40
43
  def generate(template, target = '.')
41
44
  root = "#{File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)}/#{template}"
42
- source = "#{root}/skeleton"
43
-
45
+ unless File::exist? root
46
+ @output.error "Template not found #{template}"
47
+ @finisher.terminate exit_case: :error_exit
48
+ end
44
49
  if File::exist? File::expand_path("#{DEFAULT_DATASETS_PATH}/#{template}.yml") then
45
50
  dataset = open_dataset(template: template)
46
51
  @output.info "Dataset file found for #{template}"
47
52
  else
48
- @output.ko "Dataset file not found for #{template}"
49
- @finisher.terminate exit_case: :error_exit
53
+ begin
54
+ @output.warn "Dataset file not found for #{template}"
55
+ if TTY::Prompt.new.yes?("Do you want to collect dataset interactively ?")
56
+ @output.info "Beginning interactive Dataset input for #{template}"
57
+ collector = Appifier::Actors::Collector.new template: template
58
+ collector.collect
59
+ dataset = open_dataset(template: template)
60
+ else
61
+ puts "=> Exiting run 'appifier collect #{template}' for collecting data"
62
+ puts " (use -S for collecting from STDIN or -f <FILE>) "
63
+ @finisher.terminate exit_case: :quiet_exit
64
+ end
65
+ rescue TTY::Reader::InputInterrupt
66
+ @output.warn "Command interrupted"
67
+ @finisher.terminate exit_case: :interrupt
68
+ end
50
69
  end
51
70
 
52
71
  begin
53
- generator = Appifier::Actors::Generator.new src_root: source, target_root: File.expand_path(target), dataset: dataset
72
+ generator = Appifier::Actors::Generator.new template_root: root, target_root: File.expand_path(target), dataset: dataset
54
73
  generator.generate dry_run: options[:simulate], force: options[:force]
55
74
  @finisher.terminate exit_case: :quiet_exit
56
75
  rescue RuntimeError => e
@@ -70,7 +89,13 @@ module Appifier
70
89
  begin
71
90
  type = options[:type].to_sym
72
91
  retriever = Appifier::Actors::Retriever.new type: type, origin: origin
73
- retriever.get
92
+ results = retriever.get
93
+ @output.info "Detail of notifications : " unless results[:error].empty? and results[:warn].empty? and results[:cleaned].empty?
94
+ [:error, :warn].each do |level|
95
+ results[level].each { |value| @output.send level, "#{level.to_s} : #{value}" }
96
+ end
97
+ results[:cleaned].each { |value| @output.ok "cleaned : #{value}" }
98
+ @finisher.terminate exit_case: :error_exit unless results[:error].empty?
74
99
  @finisher.terminate exit_case: :quiet_exit
75
100
  rescue RuntimeError => e
76
101
  @output.error e.message
@@ -82,8 +107,8 @@ module Appifier
82
107
  desc 'collect TEMPLATE', 'Collect dataset for an application template in user templates bundle'
83
108
  long_desc <<-LONGDESC
84
109
  Collect dataset for an application template in user templates bundle\n
85
- with --force => force collect, and destroy previous Dataset [DANGER]
86
- with --file FILENAME get data from à YAML File
110
+ with --force => force collect, and destroy previous Dataset [DANGER]\n
111
+ with --file FILENAME get data from à YAML File\n
87
112
  with --stdin get data from STDIN
88
113
 
89
114
  LONGDESC
@@ -1,3 +1,5 @@
1
+ require 'schash'
2
+
1
3
  module Appifier
2
4
  module Components
3
5
  class Appifile
@@ -6,8 +8,11 @@ module Appifier
6
8
 
7
9
  def initialize(path:)
8
10
  @path = path
9
- @content = {}
10
- openfile
11
+ begin
12
+ @content = open_yaml filename: @path
13
+ rescue RuntimeError
14
+ raise "Appifile missing"
15
+ end
11
16
  end
12
17
 
13
18
  def dataset_rules
@@ -18,17 +23,54 @@ module Appifier
18
23
  @content[:actions]
19
24
  end
20
25
 
21
- private
22
- def openfile
23
- raise 'Appifile not foud' unless File::exist? @path
26
+ def self.validate!(path:)
27
+ appifile = {}
28
+ res = {status: :ok, warn: [], error: [], cleaned: []}
24
29
  begin
25
- @content = YAML.load_file(@path)
26
- rescue StandardError => e
27
- raise e.message
30
+ appifile = open_yaml filename: path
31
+ validator = Schash::Validator.new do
32
+ {
33
+ template: {
34
+ authors: optional(array_of(string)),
35
+ version: numeric,
36
+ contact: optional(string),
37
+ description: optional(string),
38
+ dataset: {
39
+
40
+ }
41
+ },
42
+ actions: {
43
+ deploy: {},
44
+ run: {},
45
+ build: {},
46
+ publish: {},
47
+ test: {},
48
+ },
49
+ }
50
+
51
+ end
52
+
53
+ dataset_rules_validator = Schash::Validator.new do
54
+ {
55
+ format: string,
56
+ description: string,
57
+ default: optional(string)
58
+ }
59
+ end
60
+
61
+
62
+ result = validator.validate(appifile)
63
+ result.each {|item| res[:error].push "Appifiler : //#{item.position.join('/')} #{item.message}"}
64
+ appifile[:template][:dataset].each do |rule, definition|
65
+ result = dataset_rules_validator.validate definition
66
+ result.each {|item| res[:error].push "Appifiler : //template/dataset/#{rule}/#{item.position.join('/')} #{item.message}"}
67
+ end
68
+ rescue RuntimeError
69
+ res[:error].push "Appifile missing"
28
70
  end
29
-
30
-
71
+ return res
31
72
  end
73
+
32
74
  end
33
75
  end
34
76
  end
@@ -0,0 +1,60 @@
1
+ module Appifier
2
+ module Components
3
+ class Dataset
4
+
5
+ extend Carioca::Injector
6
+ inject service: :output
7
+
8
+
9
+ def self.list
10
+ output.info "List of available Datasets for user : #{current_user} :"
11
+ templates_path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
12
+ datasets_path = File.expand_path(Appifier::DEFAULT_DATASETS_PATH)
13
+ templates = Dir.glob("#{templates_path}/*").map { |item| item.delete_prefix("#{templates_path}/") }
14
+ Dir.glob("#{datasets_path}/*").map { |item| item.delete_prefix("#{datasets_path}/") }.each do |file|
15
+ dataset = File::basename(file,'.yml')
16
+ res = dataset; res << " [TEMPLATE MISSING]" unless templates.include? dataset
17
+ output.item res
18
+ end
19
+ end
20
+
21
+
22
+ def self.prune
23
+ output.info "Pruning Datasets for user : #{current_user} :"
24
+ templates_path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
25
+ datasets_path = File.expand_path(Appifier::DEFAULT_DATASETS_PATH)
26
+ templates = Dir.glob("#{templates_path}/*").map { |item| item.delete_prefix("#{templates_path}/") }
27
+ Dir.glob("#{datasets_path}/*").each do |file|
28
+ dataset = File::basename(file,'.yml')
29
+ unless templates.include? dataset
30
+ FileUtils::rm file
31
+ output.item "Pruned : #{dataset}"
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ def self.show(dataset)
38
+ raise "Not yet Implemented"
39
+ end
40
+
41
+ def self.rm(dataset)
42
+ output.info "Removing dataset #{dataset} for user : #{current_user}"
43
+ dataset_path = File.expand_path(Appifier::DEFAULT_DATASETS_PATH)
44
+ begin
45
+ if File::exist? "#{dataset_path}/#{dataset}.yml"
46
+ FileUtils.rm_rf "#{dataset_path}/#{dataset}.yml"
47
+ output.ok "Dataset #{dataset} deleted of bundle for user #{current_user}"
48
+ else
49
+ raise "Dataset #{dataset} not found in bundle for user #{current_user}"
50
+ end
51
+ rescue Errno::ENOENT
52
+ raise "Dataset #{dataset} not found in bundle for user #{current_user}"
53
+ end
54
+ end
55
+
56
+
57
+
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+ require 'tty-tree'
3
+ module Appifier
4
+ module Components
5
+
6
+
7
+ class Template
8
+ extend Carioca::Injector
9
+ inject service: :output
10
+ attr_accessor :appifile
11
+ attr_reader :readme_path, :skeleton_path
12
+ IGNORE_LIST = [".git"]
13
+
14
+ def initialize(template: nil, path: nil)
15
+ raise "Missing template or path keyword" if template.nil? && path.nil?
16
+ @path = File.expand_path("#{Appifier::DEFAULT_TEMPLATES_PATH}/#{template}") if template
17
+ @path = path if path
18
+ @appifile_name = "#{@path}/Appifile"
19
+ @skeleton_path = "#{@path}/skeleton"
20
+ @readme_path = "#{@path}/README.md"
21
+ begin
22
+ @appifile = Appifier::Components::Appifile::new(path: @appifile_name)
23
+ rescue RuntimeError
24
+ raise "Template format error"
25
+ end
26
+ end
27
+
28
+ def readme?
29
+ File.exist? @readme_path
30
+ end
31
+
32
+ def self.validate!(template: nil, path: nil)
33
+ raise "Missing template or path keyword" if template.nil? && path.nil?
34
+ path = File.expand_path("#{Appifier::DEFAULT_TEMPLATES_PATH}/#{template}") if template
35
+ path = path if path
36
+ appifile_name = "#{path}/Appifile"
37
+
38
+ result = Appifier::Components::Appifile.validate!(path: appifile_name)
39
+ IGNORE_LIST.each do |item|
40
+ item_path = "#{path}/#{item}"
41
+ if File.exist? item_path
42
+ FileUtils::rm_rf item_path
43
+ result[:cleaned].push item
44
+ end
45
+ end unless result.include? :error
46
+ result[:error].push "Skeleton path missing" unless File.exist?("#{path}/skeleton")
47
+ result[:warn].push "README.md missing" unless File.exist?("#{path}/README.md")
48
+ result[:status] = :ok
49
+ result[:status] = :partial unless result[:warn].empty?
50
+ result[:status] = :ko unless result[:error].empty?
51
+ return result
52
+ end
53
+
54
+ def self.list
55
+ output.info "List of available templates for user : #{current_user} :"
56
+ template_path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
57
+ Dir.glob("#{template_path}/*").map { |item| item.delete_prefix("#{template_path}/") }.each do |template|
58
+ output.item "#{template}"
59
+ end
60
+ end
61
+
62
+ def self.rm(template)
63
+ output.info "Removing template #{template} for user : #{current_user}"
64
+ template_path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
65
+ begin
66
+ if File::exist? "#{template_path}/#{template}"
67
+ FileUtils.rm_rf "#{template_path}/#{template}"
68
+ output.ok "Template #{template} deleted of bundle for user #{current_user}"
69
+ else
70
+ raise "Template #{template} not found in bundle for user #{current_user}"
71
+ end
72
+ rescue Errno::ENOENT
73
+ raise "Template #{template} not found in bundle for user #{current_user}"
74
+ end
75
+ end
76
+
77
+ def self.show(template)
78
+ data = Appifier::Components::Template::new(template: template)
79
+ data_template = data.appifile.content[:template]
80
+ output.info "Template #{template} informations"
81
+ output.item "Name : #{data_template[:name]}"
82
+ output.item "Version : #{data_template[:version]}"
83
+ if data_template[:authors]
84
+ output.item "Authors : "
85
+ data_template[:authors].each do |author|
86
+ output.arrow author
87
+ end
88
+ end
89
+ output.item "Description : #{data_template[:description]}" if data_template[:description]
90
+ output.item "Contact : #{data_template[:contact]}" if data_template[:contact]
91
+ output.info "Dataset informations : "
92
+ data_template[:dataset].each do |rule, definition|
93
+ output.item "Rule : #{rule}"
94
+ output.arrow "Description : #{definition[:description]}"
95
+ output.arrow "Default : #{definition[:default]}" if definition[:default]
96
+ output.arrow "Format : #{definition[:format]}"
97
+ end
98
+
99
+ end
100
+
101
+ def self.treeview(template)
102
+ begin
103
+ data = Appifier::Components::Template::new(template: template)
104
+ output.info "Getting tree view for template #{template} : "
105
+ tree = TTY::Tree.new(data.skeleton_path)
106
+ puts tree.render
107
+ rescue RuntimeError
108
+ raise "Template not found"
109
+ end
110
+ end
111
+
112
+ def self.lint(template)
113
+ begin
114
+ res = Appifier::Components::Template.validate!(template: template)
115
+ output.info "List of warnings for template #{template}"
116
+ res[:warn].each do |warn|
117
+ output.warn warn
118
+ end
119
+ rescue RuntimeError
120
+ raise "Template not found"
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -1,20 +1,43 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appifier
4
- class Configuration
4
+ module Configuration
5
5
  def self.setup(force: false)
6
6
  if File.exist?(File.expand_path(Appifier::DEFAULT_CONFIG_PATH)) && !force
7
7
  puts 'Appifier already configured'
8
8
  else
9
+ FileUtils.rm_rf File.expand_path(Appifier::DEFAULT_PATH)
9
10
  config_file = search_file_in_gem('appifier', 'config/settings.yml')
10
- path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
11
11
  [Appifier::DEFAULT_TEMPLATES_PATH, Appifier::DEFAULT_LOGS_PATH, Appifier::DEFAULT_CONFIG_PATH, Appifier::DEFAULT_DATASETS_PATH].each do |path|
12
12
  FileUtils.mkdir_p File.expand_path(path)
13
13
  end
14
- File.open(File.expand_path("#{Appifier::DEFAULT_LOGS_PATH}/#{Appifier::DEFAULT_LOG_FILENAME}"), 'w') { |file| file.write("# Appifier : beginning of log file") }
14
+ File.open(File.expand_path("#{Appifier::DEFAULT_LOGS_PATH}/#{Appifier::DEFAULT_LOG_FILENAME}"), 'w') { |file| file.write("# Appifier : beginning of log file\n") }
15
15
  FileUtils.cp config_file, File.expand_path(Appifier::DEFAULT_CONFIG_PATH)
16
16
  puts '[OK] Building config folder and initialize settings'
17
17
  end
18
18
  end
19
+
20
+
21
+ class Checker
22
+
23
+ extend Carioca::Injector
24
+ inject service: :output
25
+ inject service: :finisher
26
+
27
+ def self.sanitycheck
28
+ output.info "Checking path for #{current_user} : "
29
+ status = { true => :ok, false => :error }
30
+ [DEFAULT_PATH,DEFAULT_TEMPLATES_PATH,DEFAULT_CONFIG_PATH,DEFAULT_LOGS_PATH,DEFAULT_DATASETS_PATH].each do |path|
31
+ output.send status[File::exist?(File::expand_path(path))], path
32
+ end
33
+ output.info "Checking file for #{current_user} : "
34
+
35
+ ["#{DEFAULT_CONFIG_PATH}/#{DEFAULT_SETTINGS_FILENAME}","#{DEFAULT_LOGS_PATH}/#{DEFAULT_LOG_FILENAME}"].each do |file|
36
+ output.send status[File::exist?(File::expand_path(file))], file
37
+ end
38
+ end
39
+ end
40
+
41
+
19
42
  end
20
43
  end
data/lib/appifier.rb CHANGED
@@ -5,6 +5,11 @@ require 'thot'
5
5
  require 'fileutils'
6
6
  require 'etc'
7
7
 
8
+
9
+ require 'thor'
10
+ require "tty-prompt"
11
+ require 'tty-link'
12
+
8
13
  include Thot
9
14
 
10
15
 
@@ -14,7 +19,7 @@ require 'appifier/helpers/init'
14
19
  module Appifier
15
20
  DEFAULT_PATH = '~/.appifier'
16
21
  DEFAULT_TEMPLATES_PATH = "#{DEFAULT_PATH}/templates"
17
- DEFAULT_CONFIG_PATH = "#{DEFAULT_PATH}/config/"
22
+ DEFAULT_CONFIG_PATH = "#{DEFAULT_PATH}/config"
18
23
  DEFAULT_LOGS_PATH = "#{DEFAULT_PATH}/logs"
19
24
  DEFAULT_DATASETS_PATH = "#{DEFAULT_PATH}/datasets"
20
25
  DEFAULT_LOG_FILENAME = "appifier.log"
@@ -49,13 +54,4 @@ Carioca::Registry.configure do |spec|
49
54
  end
50
55
 
51
56
  require_relative 'appifier/services/init'
52
-
53
- module Appifier
54
- class Application < Carioca::Container
55
- inject service: :configuration
56
- inject service: :i18n
57
- inject service: :terminator
58
- end
59
- end
60
-
61
57
  require_relative 'appifier/components/init'
@@ -0,0 +1,18 @@
1
+ ---
2
+ :template:
3
+ :name: dummy
4
+ :authors:
5
+ - Romain Georges
6
+ - Camille Paquet
7
+ :description: dummy template
8
+ :dataset:
9
+ :appname:
10
+ :description: The application name
11
+ :default: test_application
12
+ :format: \w+
13
+ :actions:
14
+ :deploy: {}
15
+ :run: {}
16
+ :build: {}
17
+ :publish: {}
18
+ :test: {}
Binary file
@@ -1,8 +1,14 @@
1
1
  ---
2
2
  :template:
3
+ :name: dummy
4
+ :version: 1.0
5
+ :authors:
6
+ - Romain Georges
7
+ - Camille Paquet
8
+ :description: a dummy template
3
9
  :dataset:
4
10
  :appname:
5
- :description: The application name
11
+ :description: application name
6
12
  :default: test_application
7
13
  :format: \w+
8
14
  :actions:
@@ -10,3 +16,4 @@
10
16
  :run: {}
11
17
  :build: {}
12
18
  :publish: {}
19
+ :test: {}
@@ -0,0 +1,4 @@
1
+ ## dummy template
2
+
3
+
4
+ this is a test
data/samples/dummy.tgz CHANGED
Binary file
@@ -0,0 +1,19 @@
1
+ ---
2
+ :template:
3
+ :name: dummy
4
+ :version: 1.0
5
+ :authors:
6
+ - Romain Georges
7
+ - Camille Paquet
8
+ :description: a dummy template
9
+ :dataset:
10
+ :appname:
11
+ :description: application name
12
+ :default: test_application
13
+ :format: \w+
14
+ :actions:
15
+ :deploy: {}
16
+ :run: {}
17
+ :build: {}
18
+ :publish: {}
19
+ :test: {}
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appifier
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Camille Paquet
8
8
  - Romain GEORGES
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-10-24 00:00:00.000000000 Z
12
+ date: 2022-10-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: code_statistics
@@ -165,10 +165,95 @@ dependencies:
165
165
  - - "~>"
166
166
  - !ruby/object:Gem::Version
167
167
  version: 0.23.1
168
+ - !ruby/object:Gem::Dependency
169
+ name: thot
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '1.0'
175
+ type: :runtime
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: '1.0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: git
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - "~>"
187
+ - !ruby/object:Gem::Version
188
+ version: '1.12'
189
+ type: :runtime
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - "~>"
194
+ - !ruby/object:Gem::Version
195
+ version: '1.12'
196
+ - !ruby/object:Gem::Dependency
197
+ name: schash
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - "~>"
201
+ - !ruby/object:Gem::Version
202
+ version: 0.1.2
203
+ type: :runtime
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - "~>"
208
+ - !ruby/object:Gem::Version
209
+ version: 0.1.2
210
+ - !ruby/object:Gem::Dependency
211
+ name: tty-tree
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - "~>"
215
+ - !ruby/object:Gem::Version
216
+ version: 0.4.0
217
+ type: :runtime
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - "~>"
222
+ - !ruby/object:Gem::Version
223
+ version: 0.4.0
224
+ - !ruby/object:Gem::Dependency
225
+ name: tty-markdown
226
+ requirement: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - "~>"
229
+ - !ruby/object:Gem::Version
230
+ version: 0.7.0
231
+ type: :runtime
232
+ prerelease: false
233
+ version_requirements: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - "~>"
236
+ - !ruby/object:Gem::Version
237
+ version: 0.7.0
238
+ - !ruby/object:Gem::Dependency
239
+ name: tty-link
240
+ requirement: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - "~>"
243
+ - !ruby/object:Gem::Version
244
+ version: 0.1.1
245
+ type: :runtime
246
+ prerelease: false
247
+ version_requirements: !ruby/object:Gem::Requirement
248
+ requirements:
249
+ - - "~>"
250
+ - !ruby/object:Gem::Version
251
+ version: 0.1.1
168
252
  description: 'Appifier : Applications templating and management tools '
169
253
  email:
170
254
  - gems@ultragreen.net
171
255
  executables:
256
+ - app
172
257
  - appifier
173
258
  extensions: []
174
259
  extra_rdoc_files: []
@@ -185,6 +270,7 @@ files:
185
270
  - bin/setup
186
271
  - config/appifier.registry
187
272
  - config/settings.yml
273
+ - exe/app
188
274
  - exe/appifier
189
275
  - lib/appifier.rb
190
276
  - lib/appifier/actors/collector.rb
@@ -193,10 +279,12 @@ files:
193
279
  - lib/appifier/actors/retriever.rb
194
280
  - lib/appifier/cli.rb
195
281
  - lib/appifier/cli/configuration.rb
282
+ - lib/appifier/cli/datasets.rb
196
283
  - lib/appifier/cli/templates.rb
197
284
  - lib/appifier/components/Appifile.rb
285
+ - lib/appifier/components/dataset.rb
198
286
  - lib/appifier/components/init.rb
199
- - lib/appifier/components/templates.rb
287
+ - lib/appifier/components/template.rb
200
288
  - lib/appifier/helpers/archives.rb
201
289
  - lib/appifier/helpers/datasets.rb
202
290
  - lib/appifier/helpers/gem.rb
@@ -206,14 +294,30 @@ files:
206
294
  - lib/appifier/services/init.rb
207
295
  - lib/appifier/setup.rb
208
296
  - lib/appifier/version.rb
297
+ - samples/baddummy.tgz
298
+ - samples/baddummy/Appifile
299
+ - samples/baddummy/skeleton/%%APPNAME.downcase%%/.rspec
300
+ - samples/baddummy/skeleton/%%APPNAME.downcase%%/Rakefile
301
+ - samples/baddummy/skeleton/%%APPNAME.downcase%%/config.ru
302
+ - samples/baddummy/skeleton/%%APPNAME.downcase%%/exe/%%APPNAME.downcase%%
303
+ - samples/baddummy/skeleton/%%APPNAME.downcase%%/lib/%%APPNAME.downcase%%.rb
304
+ - samples/baddummy/skeleton/%%APPNAME.downcase%%/spec/%%APPNAME.downcase%%_spec.rb
209
305
  - samples/dummy.tgz
210
306
  - samples/dummy/Appifile
307
+ - samples/dummy/README.md
211
308
  - samples/dummy/skeleton/%%APPNAME.downcase%%/.rspec
212
309
  - samples/dummy/skeleton/%%APPNAME.downcase%%/Rakefile
213
310
  - samples/dummy/skeleton/%%APPNAME.downcase%%/config.ru
214
311
  - samples/dummy/skeleton/%%APPNAME.downcase%%/exe/%%APPNAME.downcase%%
215
312
  - samples/dummy/skeleton/%%APPNAME.downcase%%/lib/%%APPNAME.downcase%%.rb
216
313
  - samples/dummy/skeleton/%%APPNAME.downcase%%/spec/%%APPNAME.downcase%%_spec.rb
314
+ - samples/dummy_warn/Appifile
315
+ - samples/dummy_warn/skeleton/%%APPNAME.downcase%%/.rspec
316
+ - samples/dummy_warn/skeleton/%%APPNAME.downcase%%/Rakefile
317
+ - samples/dummy_warn/skeleton/%%APPNAME.downcase%%/config.ru
318
+ - samples/dummy_warn/skeleton/%%APPNAME.downcase%%/exe/%%APPNAME.downcase%%
319
+ - samples/dummy_warn/skeleton/%%APPNAME.downcase%%/lib/%%APPNAME.downcase%%.rb
320
+ - samples/dummy_warn/skeleton/%%APPNAME.downcase%%/spec/%%APPNAME.downcase%%_spec.rb
217
321
  homepage: https://github.com/Ultragreen/appifier
218
322
  licenses:
219
323
  - MIT
@@ -222,7 +326,7 @@ metadata:
222
326
  source_code_uri: https://github.com/Ultragreen/appifier
223
327
  changelog_uri: https://github.com/Ultragreen/appifier
224
328
  rubygems_mfa_required: 'false'
225
- post_install_message:
329
+ post_install_message:
226
330
  rdoc_options: []
227
331
  require_paths:
228
332
  - lib
@@ -237,8 +341,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
237
341
  - !ruby/object:Gem::Version
238
342
  version: '0'
239
343
  requirements: []
240
- rubygems_version: 3.1.2
241
- signing_key:
344
+ rubygems_version: 3.2.3
345
+ signing_key:
242
346
  specification_version: 4
243
347
  summary: 'Appifier : Applications templating and management tools'
244
348
  test_files: []
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appifier
4
- module Components
5
- class Templates
6
-
7
- extend Carioca::Injector
8
- inject service: :output
9
-
10
- def self.list
11
- output.info "List of avaible templates for user : #{current_user} :"
12
- template_path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
13
- Dir.glob("#{template_path}/*").map { |item| item.delete_prefix("#{template_path}/") }.each do |template|
14
- output.item "#{template}"
15
- end
16
- end
17
-
18
- def self.rm(template)
19
- output.info "Removing template #{template} for user : #{current_user} :"
20
- template_path = File.expand_path(Appifier::DEFAULT_TEMPLATES_PATH)
21
- begin
22
- if File::exist? "#{template_path}/#{template}"
23
- FileUtils.rm_rf "#{template_path}/#{template}"
24
- output.ok "Template #{template} deleted of bundle for user #{current_user}"
25
- else
26
- raise "Template #{template} not found in bundle for user #{current_user}"
27
- end
28
- rescue Errno::ENOENT
29
- raise "Template #{template} not found in bundle for user #{current_user}"
30
- end
31
- end
32
- end
33
- end
34
- end