quik 0.1.1 → 1.0.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.
- checksums.yaml +5 -5
- data/{HISTORY.md → CHANGELOG.md} +3 -3
- data/LICENSE.md +116 -0
- data/Manifest.txt +30 -24
- data/README.md +133 -106
- data/Rakefile +33 -34
- data/bin/qk +5 -5
- data/bin/quik +5 -5
- data/lib/quik.rb +55 -43
- data/lib/quik/builder.rb +96 -94
- data/lib/quik/catalog.rb +73 -0
- data/lib/quik/cli/main.rb +213 -150
- data/lib/quik/cli/opts.rb +33 -33
- data/lib/quik/colors.rb +148 -0
- data/lib/quik/config.rb +60 -60
- data/lib/quik/merger.rb +207 -202
- data/lib/quik/package.rb +116 -99
- data/lib/quik/version.rb +24 -24
- data/lib/quik/wizard.rb +88 -88
- data/test/data/gem-starter-template/Manifest.txt +9 -9
- data/test/data/gem-starter-template/README.md +22 -22
- data/test/data/gem-starter-template/lib/__filename__/version.rb +12 -12
- data/test/helper.rb +18 -22
- data/test/test_colors.rb +39 -0
- data/test/test_config.rb +35 -0
- data/test/test_merger.rb +35 -35
- data/test/test_package.rb +22 -22
- data/test/test_wizard.rb +50 -0
- metadata +31 -35
- data/.gemtest +0 -0
data/lib/quik/package.rb
CHANGED
@@ -1,99 +1,116 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Quik
|
4
|
-
|
5
|
-
class Package
|
6
|
-
|
7
|
-
def initialize( key ) ## e.g.
|
8
|
-
if key.index( '/' ).nil? ## if just 'gems' etc; assumbe
|
9
|
-
@key = "
|
10
|
-
else
|
11
|
-
@key = key # use as is e.g. seattlerb/hoe etc.
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
worker
|
67
|
-
|
68
|
-
###
|
69
|
-
###
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
#
|
77
|
-
# !/_layouts/
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Quik
|
4
|
+
|
5
|
+
class Package
|
6
|
+
|
7
|
+
def initialize( key ) ## e.g. quikstart/gems
|
8
|
+
if key.index( '/' ).nil? ## if just 'gems' etc; assumbe quikstart "standard" github org
|
9
|
+
@key = "quikstart/#{key}"
|
10
|
+
else
|
11
|
+
@key = key # use as is e.g. seattlerb/hoe etc.
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
def remote_zip_url # remote zip url
|
17
|
+
"https://github.com/#{@key}/archive/master.zip"
|
18
|
+
end
|
19
|
+
|
20
|
+
def local_zip_name
|
21
|
+
## note: change / to --I-- for "flat" structure (e.g. no dirs)
|
22
|
+
@key.sub( '/', '--I--' ) # note: will NOT include/return .zip extension
|
23
|
+
end
|
24
|
+
|
25
|
+
def local_zip_dir
|
26
|
+
"." ## use ./tmp or ./dl or ~/.quik/cache - why?? why not??
|
27
|
+
end
|
28
|
+
|
29
|
+
def local_zip_path # local zip path
|
30
|
+
"#{local_zip_dir}/#{local_zip_name}.zip"
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
def download
|
36
|
+
src = remote_zip_url
|
37
|
+
dest_zip = local_zip_path
|
38
|
+
|
39
|
+
## make sure dest folder exists
|
40
|
+
FileUtils.mkdir_p( local_zip_dir ) unless Dir.exist?( local_zip_dir )
|
41
|
+
fetch_archive( src, dest_zip )
|
42
|
+
end
|
43
|
+
|
44
|
+
def unzip( unzip_dir )
|
45
|
+
src = local_zip_path
|
46
|
+
dest_unzip = unzip_dir ## local_unzip_dir
|
47
|
+
|
48
|
+
## check if folders exists? if not create folder in path
|
49
|
+
FileUtils.mkdir_p( dest_unzip ) unless Dir.exist?( dest_unzip )
|
50
|
+
unzip_archive( src, dest_unzip )
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def merge( root_dir, hash )
|
55
|
+
## replace/merge variable in files
|
56
|
+
Dir.chdir( "#{root_dir}" ) do
|
57
|
+
files = Dir[ '**/*' ] ## get all files
|
58
|
+
pp files
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
private
|
64
|
+
def fetch_archive( src, dest )
|
65
|
+
## step 1 - fetch archive
|
66
|
+
worker = Fetcher::Worker.new
|
67
|
+
worker.copy( src, dest )
|
68
|
+
### fix: add src.sha5
|
69
|
+
### inside folder
|
70
|
+
### lets us check if current HEAD version is in place across datafiles etc.
|
71
|
+
## - try HTTP HEAD ?? to check?
|
72
|
+
end
|
73
|
+
|
74
|
+
def unzip_archive( src, dest, opts={} )
|
75
|
+
### todo/fix: rename or remove root folder -- use opts { root: false or something??}
|
76
|
+
# e.g
|
77
|
+
# !/starter-gh-pages/_layouts/ becomes
|
78
|
+
# !/_layouts/ etc.
|
79
|
+
|
80
|
+
##
|
81
|
+
## note:
|
82
|
+
## skip all files in "root" folder
|
83
|
+
## only unzip files in /template(s)/ folder
|
84
|
+
|
85
|
+
Zip::File.open( src ) do |zipfile|
|
86
|
+
zipfile.each do |file|
|
87
|
+
if file.directory?
|
88
|
+
puts " skip directory zip entry - #{file.name}"
|
89
|
+
else
|
90
|
+
### fix: only cut-off if master or gh-pages ???
|
91
|
+
## check if others include root folder?
|
92
|
+
name = file.name[ file.name.index('/')+1..-1] ## cut-off root/first path entry
|
93
|
+
|
94
|
+
## note: name must start w/ template/ or templates/
|
95
|
+
## otherwise gets skipped as "top level" docu
|
96
|
+
if name =~ /^template(s)?\//
|
97
|
+
name = name[ name.index('/')+1..-1] ## cut-off first path entry (e.g. template(s)/)
|
98
|
+
|
99
|
+
path = File.join( dest, name)
|
100
|
+
puts " unzip file zip entry - #{file.name} to #{path}"
|
101
|
+
FileUtils.mkdir_p( File.dirname( path) )
|
102
|
+
## todo/fix: check - always overwrite if file exists - why? why not??
|
103
|
+
zipfile.extract(file, path) unless File.exist?(path)
|
104
|
+
else
|
105
|
+
puts " skip top-level docu file entry - #{file.name}"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end # method unzip_theme
|
111
|
+
|
112
|
+
|
113
|
+
end # class Package
|
114
|
+
|
115
|
+
end # module Quik
|
116
|
+
|
data/lib/quik/version.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module Quik
|
4
|
-
|
5
|
-
MAJOR =
|
6
|
-
MINOR =
|
7
|
-
PATCH =
|
8
|
-
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
9
|
-
|
10
|
-
def self.version
|
11
|
-
VERSION
|
12
|
-
end
|
13
|
-
|
14
|
-
# version string for generator meta tag (includes ruby version)
|
15
|
-
def self.banner
|
16
|
-
"quik/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.root
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
end # module Quik
|
24
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Quik
|
4
|
+
|
5
|
+
MAJOR = 1 ## todo: namespace inside version or something - why? why not??
|
6
|
+
MINOR = 0
|
7
|
+
PATCH = 0
|
8
|
+
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
9
|
+
|
10
|
+
def self.version
|
11
|
+
VERSION
|
12
|
+
end
|
13
|
+
|
14
|
+
# version string for generator meta tag (includes ruby version)
|
15
|
+
def self.banner
|
16
|
+
"quik/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.root
|
20
|
+
File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
|
21
|
+
end
|
22
|
+
|
23
|
+
end # module Quik
|
24
|
+
|
data/lib/quik/wizard.rb
CHANGED
@@ -1,88 +1,88 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
## note:
|
5
|
-
## use global $QUIK_WIZARD_STDIN
|
6
|
-
## lets you redirect stdin for testing e.g $QUIK_WIZARD_STDIN = StringIO.new( 'test/n' )
|
7
|
-
$QUIK_WIZARD_IN = $stdin
|
8
|
-
|
9
|
-
|
10
|
-
module Quik
|
11
|
-
|
12
|
-
module Wizard ## use a different name e.g. WizardHelpers, FormHelpers, InputHelper, etc - why, why not??
|
13
|
-
|
14
|
-
def getstr ## use getstr to avoid conflict w/ gets (use better name? read_string, readline (already exists too), etc.?)
|
15
|
-
## note: gets will include trailing newline (user hits return to enter data)
|
16
|
-
## - use strip for now (remove leading and traling whitspaces) - might later just use chomp ? (jsut removes newlines)
|
17
|
-
$QUIK_WIZARD_IN.gets.strip
|
18
|
-
end
|
19
|
-
|
20
|
-
def say( text )
|
21
|
-
puts text
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
YES_REGEX = /y|yes|on|t|true/i ## support YAML true values - double check (YAML does NOT support t/f)
|
26
|
-
NO_REGEX = /n|no|off|f|false/i
|
27
|
-
|
28
|
-
def yes?( question ) ## defaults to yes - why, why not??
|
29
|
-
## todo: strip trailing question mark (?) if present (gets auto-included)
|
30
|
-
print( "Q: #{question} (y/n)? [y]: " )
|
31
|
-
str = getstr
|
32
|
-
if str.empty? || str =~ YES_REGEX
|
33
|
-
true
|
34
|
-
elsif str =~ NO_REGEX
|
35
|
-
false
|
36
|
-
else ## warn: unknown value??
|
37
|
-
true
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def no?( question ) ## defaults to yes - why, why not??
|
42
|
-
## todo: strip trailing question mark (?) if present (gets auto-included)
|
43
|
-
print( "Q: #{question} (y/n)? [n]: " )
|
44
|
-
str = getstr
|
45
|
-
if str.empty? || str =~ NO_REGEX
|
46
|
-
true
|
47
|
-
elsif str =~ YES_REGEX
|
48
|
-
false
|
49
|
-
else ## warn: unknown value??
|
50
|
-
true
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
def ask( question, default=nil )
|
56
|
-
## todo: strip trailing question mark (?) if present (gets auto-included)
|
57
|
-
if default
|
58
|
-
print( "Q: #{question}? [#{default}]: " )
|
59
|
-
else
|
60
|
-
print( "Q: #{question}?: " )
|
61
|
-
end
|
62
|
-
|
63
|
-
str = getstr
|
64
|
-
if default && str.empty? ## todo: best way to check for empty string?
|
65
|
-
str = default
|
66
|
-
end
|
67
|
-
str
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
def select( title, options )
|
72
|
-
puts( "Q: #{title}: " )
|
73
|
-
options.each_with_index do |opt,i|
|
74
|
-
puts " #{i+1} - #{opt}"
|
75
|
-
end
|
76
|
-
print( " Your choice (1-#{options.size})? [1]: " )
|
77
|
-
str = getstr
|
78
|
-
if str.empty? ## todo: best way to check for empty string?
|
79
|
-
num = 0 ## default to first option for now
|
80
|
-
else
|
81
|
-
num = str.to_i ## note: defaults to 0 if cannot convert?
|
82
|
-
num -= 1 if num > 0 ## note: "convert" from 1-based to 0-based for ary; if invalid entry; default to 0
|
83
|
-
end
|
84
|
-
options[ num ]
|
85
|
-
end
|
86
|
-
|
87
|
-
end # module Wizard
|
88
|
-
end # module Quik
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
## note:
|
5
|
+
## use global $QUIK_WIZARD_STDIN
|
6
|
+
## lets you redirect stdin for testing e.g $QUIK_WIZARD_STDIN = StringIO.new( 'test/n' )
|
7
|
+
$QUIK_WIZARD_IN = $stdin
|
8
|
+
|
9
|
+
|
10
|
+
module Quik
|
11
|
+
|
12
|
+
module Wizard ## use a different name e.g. WizardHelpers, FormHelpers, InputHelper, etc - why, why not??
|
13
|
+
|
14
|
+
def getstr ## use getstr to avoid conflict w/ gets (use better name? read_string, readline (already exists too), etc.?)
|
15
|
+
## note: gets will include trailing newline (user hits return to enter data)
|
16
|
+
## - use strip for now (remove leading and traling whitspaces) - might later just use chomp ? (jsut removes newlines)
|
17
|
+
$QUIK_WIZARD_IN.gets.strip
|
18
|
+
end
|
19
|
+
|
20
|
+
def say( text )
|
21
|
+
puts text
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
YES_REGEX = /y|yes|on|t|true/i ## support YAML true values - double check (YAML does NOT support t/f)
|
26
|
+
NO_REGEX = /n|no|off|f|false/i
|
27
|
+
|
28
|
+
def yes?( question ) ## defaults to yes - why, why not??
|
29
|
+
## todo: strip trailing question mark (?) if present (gets auto-included)
|
30
|
+
print( "Q: #{question} (y/n)? [y]: " )
|
31
|
+
str = getstr
|
32
|
+
if str.empty? || str =~ YES_REGEX
|
33
|
+
true
|
34
|
+
elsif str =~ NO_REGEX
|
35
|
+
false
|
36
|
+
else ## warn: unknown value??
|
37
|
+
true
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def no?( question ) ## defaults to yes - why, why not??
|
42
|
+
## todo: strip trailing question mark (?) if present (gets auto-included)
|
43
|
+
print( "Q: #{question} (y/n)? [n]: " )
|
44
|
+
str = getstr
|
45
|
+
if str.empty? || str =~ NO_REGEX
|
46
|
+
true
|
47
|
+
elsif str =~ YES_REGEX
|
48
|
+
false
|
49
|
+
else ## warn: unknown value??
|
50
|
+
true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
def ask( question, default=nil )
|
56
|
+
## todo: strip trailing question mark (?) if present (gets auto-included)
|
57
|
+
if default
|
58
|
+
print( "Q: #{question}? [#{default}]: " )
|
59
|
+
else
|
60
|
+
print( "Q: #{question}?: " )
|
61
|
+
end
|
62
|
+
|
63
|
+
str = getstr
|
64
|
+
if default && str.empty? ## todo: best way to check for empty string?
|
65
|
+
str = default
|
66
|
+
end
|
67
|
+
str
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def select( title, options )
|
72
|
+
puts( "Q: #{title}: " )
|
73
|
+
options.each_with_index do |opt,i|
|
74
|
+
puts " #{i+1} - #{opt}"
|
75
|
+
end
|
76
|
+
print( " Your choice (1-#{options.size})? [1]: " )
|
77
|
+
str = getstr
|
78
|
+
if str.empty? ## todo: best way to check for empty string?
|
79
|
+
num = 0 ## default to first option for now
|
80
|
+
else
|
81
|
+
num = str.to_i ## note: defaults to 0 if cannot convert?
|
82
|
+
num -= 1 if num > 0 ## note: "convert" from 1-based to 0-based for ary; if invalid entry; default to 0
|
83
|
+
end
|
84
|
+
options[ num ]
|
85
|
+
end
|
86
|
+
|
87
|
+
end # module Wizard
|
88
|
+
end # module Quik
|
@@ -1,9 +1,9 @@
|
|
1
|
-
---
|
2
|
-
# Gem Starter Template
|
3
|
-
---
|
4
|
-
Manifest.txt
|
5
|
-
HISTORY.md
|
6
|
-
README.md
|
7
|
-
Rakefile
|
8
|
-
lib/{{filename}}.rb
|
9
|
-
lib/{{filename}}/version.rb
|
1
|
+
---
|
2
|
+
# Gem Starter Template
|
3
|
+
---
|
4
|
+
Manifest.txt
|
5
|
+
HISTORY.md
|
6
|
+
README.md
|
7
|
+
Rakefile
|
8
|
+
lib/{{filename}}.rb
|
9
|
+
lib/{{filename}}/version.rb
|