palco 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +6 -0
- data/LICENSE +24 -0
- data/README.md +45 -0
- data/Rakefile +7 -0
- data/bin/palco +72 -0
- data/lib/README.md +99 -0
- data/lib/palco.rb +7 -0
- data/lib/palco/application.rb +78 -0
- data/lib/palco/base.rb +116 -0
- data/lib/palco/extension.rb +59 -0
- data/lib/palco/filebase.rb +68 -0
- data/lib/palco/gemspec.rb +31 -0
- data/lib/palco/license.rb +50 -0
- data/lib/palco/version.rb +3 -0
- data/palco.gemspec +30 -0
- data/spec/palco_base_spec.rb +60 -0
- data/spec/palco_generate_applications_spec.rb +43 -0
- data/spec/palco_generate_extensions_spec.rb +46 -0
- data/spec/spec_helper.rb +1 -0
- metadata +136 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2012, Paolo Perego - <thesp0nge@gmail.com>
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Palco
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
Palco is the Italian word means stage and it's supposed to be a
|
6
|
+
[Sinatra](http://sinatrarb.com) based application skelethon generator.
|
7
|
+
|
8
|
+
The idea is just to have a basic script to automate what I did everytime I need
|
9
|
+
to start a new Sinatra project.
|
10
|
+
Nothing but a simple template creator for my pourposes... opensourced just in
|
11
|
+
case someelse need it.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
To install palco you can use gem command to fetch the code from
|
16
|
+
[rubygems](http://rubygems.org).
|
17
|
+
|
18
|
+
```
|
19
|
+
gem install palco
|
20
|
+
```
|
21
|
+
|
22
|
+
This way you have a script named palco you can use it to barely generate your
|
23
|
+
Sinatra application skelethon.
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Using palco to generate [Sinatra extensions](http://www.sinatrarb.com/extensions.html):
|
28
|
+
|
29
|
+
```
|
30
|
+
palco -e my_great_extention
|
31
|
+
```
|
32
|
+
|
33
|
+
You can also create a Sinatra basic application skeleton in order to fire
|
34
|
+
rackup and start working:
|
35
|
+
|
36
|
+
```
|
37
|
+
palco -a my_app
|
38
|
+
```
|
39
|
+
|
40
|
+
And if you don't like your work... just destroy it (even a rm command is working here):
|
41
|
+
|
42
|
+
```
|
43
|
+
palco -D my_app
|
44
|
+
```
|
45
|
+
|
data/Rakefile
ADDED
data/bin/palco
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'palco'
|
4
|
+
require 'rainbow'
|
5
|
+
require 'getoptlong'
|
6
|
+
|
7
|
+
opts = GetoptLong.new(
|
8
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
9
|
+
[ '--version', '-v', GetoptLong::NO_ARGUMENT ],
|
10
|
+
[ '--extension', '-e', GetoptLong::NO_ARGUMENT ],
|
11
|
+
[ '--app', '-a', GetoptLong::NO_ARGUMENT],
|
12
|
+
[ '--destroy', '-D', GetoptLong::NO_ARGUMENT]
|
13
|
+
)
|
14
|
+
|
15
|
+
is_app = false
|
16
|
+
destroy = false
|
17
|
+
|
18
|
+
opts.each do |opt, arg|
|
19
|
+
case opt
|
20
|
+
when '--version'
|
21
|
+
puts Palco::VERSION
|
22
|
+
exit 0
|
23
|
+
when '--help'
|
24
|
+
puts 'usage: palco options name'
|
25
|
+
printf "options are:\n"
|
26
|
+
printf "\t-e creates a Sinatra extension\n"
|
27
|
+
printf "\t-a creates a Sinatra application\n"
|
28
|
+
printf "\t-D destroy a previously created project\n"
|
29
|
+
printf "\t-h shows this help\n"
|
30
|
+
printf "\t-v prints palco version\n"
|
31
|
+
exit 0
|
32
|
+
when '--app'
|
33
|
+
is_app = true
|
34
|
+
when '--destroy'
|
35
|
+
destroy = true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
name = ARGV.shift
|
40
|
+
|
41
|
+
if name.nil?
|
42
|
+
puts "missing argument".color(:red)
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
if destroy
|
47
|
+
printf "palco is destroying a stage named #{name}: ".color(:white)
|
48
|
+
base = Palco::Base.new(name)
|
49
|
+
if base.destroy
|
50
|
+
printf "success\n".color(:green)
|
51
|
+
else
|
52
|
+
printf "fail\n".color(:red)
|
53
|
+
end
|
54
|
+
|
55
|
+
exit 0
|
56
|
+
end
|
57
|
+
|
58
|
+
printf "palco is creating a stage named #{name} for a Sinatra ".color(:white)
|
59
|
+
if is_app
|
60
|
+
printf "application: ".color(:yellow)
|
61
|
+
stage = Palco::Application.new(name)
|
62
|
+
else
|
63
|
+
printf "extension: ".color(:blue)
|
64
|
+
stage = Palco::Extension.new(name)
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
if stage.generate
|
69
|
+
printf "success\n".color(:green)
|
70
|
+
else
|
71
|
+
printf "fail\n".color(:red)
|
72
|
+
end
|
data/lib/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# Palco API
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
In the lib directory you can find Palco API organized as follow:
|
6
|
+
* Palco::Base is the core API making all the work behind the scenes. In the
|
7
|
+
binary script it's used directly for destroying purposes since it doesn't
|
8
|
+
matter if we're talking about an extension or an application.
|
9
|
+
* Palco::Extension is a Palco::Base subclass dedicated to create Sinatra
|
10
|
+
extension with a filesystem scheme described
|
11
|
+
[here](http://www.sinatrarb.com/extensions.html). A gemspec file is also
|
12
|
+
provided if you want to pack you extension as a ruby gem.
|
13
|
+
* Palco::Application is the Palco::Base subclass dedicated to create Sinatra
|
14
|
+
application skeletons. Please note that I like most
|
15
|
+
[Sinatra Modular approach](http://www.sinatrarb.com/intro#Modular%20vs.%20Classic%20Style) so I
|
16
|
+
create the app this way with a config.ru but you can easly change it if you
|
17
|
+
want to serve your app in a classic style.
|
18
|
+
|
19
|
+
## Palco::Base API
|
20
|
+
|
21
|
+
### Creating a new palco
|
22
|
+
Creating a new _palco_ object it's easy. You just need a name and a list of
|
23
|
+
files or directories you want in the main dir.
|
24
|
+
|
25
|
+
You can extending Palco::Base to create layout even for non Sinatra application
|
26
|
+
but it's off topic here.
|
27
|
+
|
28
|
+
```
|
29
|
+
require 'palco'
|
30
|
+
|
31
|
+
base = Palco::Base.new('test_one',[{:name=>'README', :file=>true}, {:name=>'lib', :file=>false}]
|
32
|
+
```
|
33
|
+
|
34
|
+
Creating a new object this way you don't have a skeleton directory yet created
|
35
|
+
for you. You must call generate method to get the job done.
|
36
|
+
|
37
|
+
From now, you want a generic stage (it doesn't matter if for a Sinatra
|
38
|
+
application or your markdown based ebook you'r launching so far) called
|
39
|
+
**test_one** and in that named root directory you want a file named _README_
|
40
|
+
and an empty directory called _lib_.
|
41
|
+
|
42
|
+
Let's build the directories calling generate method.
|
43
|
+
|
44
|
+
```
|
45
|
+
if base.generate
|
46
|
+
puts "success"
|
47
|
+
else
|
48
|
+
puts "failure"
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
It returns a boolean telling if building was successful or not, so you can make
|
53
|
+
your own decision about it.
|
54
|
+
|
55
|
+
|
56
|
+
### Destroy a palco
|
57
|
+
|
58
|
+
You don't need your **test_one** stage anymore? It's easy to ask APIs to
|
59
|
+
destroy it using the destroy method.
|
60
|
+
|
61
|
+
```
|
62
|
+
if base.destroy
|
63
|
+
puts "success"
|
64
|
+
else
|
65
|
+
puts "failure"
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
Also the destroy methods return a boolean with the easy to guess meaning that
|
70
|
+
the stage has been destroyed or not.
|
71
|
+
|
72
|
+
You can also destroying a previously genereated stage with the following:
|
73
|
+
|
74
|
+
```
|
75
|
+
require 'palco'
|
76
|
+
|
77
|
+
base = Palco::Base.new('test_two')
|
78
|
+
base.destroy
|
79
|
+
```
|
80
|
+
|
81
|
+
Note here that we didn't pass any file list to Palco::Base contructor. The code
|
82
|
+
initializes the parameter to an empty array if no argument is provided.
|
83
|
+
|
84
|
+
```
|
85
|
+
def initialize(name=nil, items_list=[])
|
86
|
+
@project_name = name
|
87
|
+
@items_list = items_list
|
88
|
+
@generated = false
|
89
|
+
|
90
|
+
if @project_name.nil? or @items_list.size==0
|
91
|
+
@valid = false
|
92
|
+
else
|
93
|
+
@valid = true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
This way since I'm not interesting in generating files or directories I can let
|
99
|
+
my item lists array to be empty.
|
data/lib/palco.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
module Palco
|
2
|
+
class Application < Palco::Base
|
3
|
+
FILE_LIST = [
|
4
|
+
{:name=>'README', :file=>true},
|
5
|
+
{:name=>'LICENSE', :file=>true},
|
6
|
+
{:name=>'Gemfile', :file=>true},
|
7
|
+
{:name=>'app.rb', :file=>true},
|
8
|
+
{:name=>'config.ru', :file=>true},
|
9
|
+
{:name=>'conf', :file=>false},
|
10
|
+
{:name=>'lib', :file=>false},
|
11
|
+
{:name=>'lib/version.rb', :file=>true},
|
12
|
+
{:name=>'spec', :file=>false},
|
13
|
+
{:name=>'public', :file=>false},
|
14
|
+
{:name=>'views', :file=>false},
|
15
|
+
{:name=>'logs', :file=>false},
|
16
|
+
{:name=>'spec/spec_helper.rb', :file=>true},
|
17
|
+
|
18
|
+
]
|
19
|
+
|
20
|
+
# Public: creates a new Sinatra modular application skeleton.
|
21
|
+
#
|
22
|
+
# The directory layout is based only on my personal taste so feel free to
|
23
|
+
# override Palco:Base with your own personal template or even suggest me
|
24
|
+
# how to improve this one.
|
25
|
+
#
|
26
|
+
# What we absolutely need here is an app.rb file for the main code and a
|
27
|
+
# lib directory for other auxiliary helpers.
|
28
|
+
# We need a views directory for templates and a public directory for static
|
29
|
+
# assests.
|
30
|
+
#
|
31
|
+
# Since I love haml as template language I choose that as default.
|
32
|
+
#
|
33
|
+
# Example
|
34
|
+
# app = Palco::Application.new('a_new_app')
|
35
|
+
# app.generate
|
36
|
+
#
|
37
|
+
# Returns
|
38
|
+
# A new Sinatra modular application. Fire up rackup or shotgun and start
|
39
|
+
# hacking.
|
40
|
+
def initialize(name)
|
41
|
+
@r = name
|
42
|
+
list = FILE_LIST
|
43
|
+
|
44
|
+
list = list << {:name=>"lib/#{name}", :file=>false}
|
45
|
+
list = list << {:name=>"spec/#{name}_spec.rb", :file=>true}
|
46
|
+
|
47
|
+
super(name, list)
|
48
|
+
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate
|
53
|
+
super
|
54
|
+
license = Palco::License.new(@r)
|
55
|
+
license.create
|
56
|
+
|
57
|
+
file = Palco::FileBase.new(@r, "lib/#{@r}/version.rb")
|
58
|
+
file.file_content = "module #{@r.capitalize}\nVERSION=\"0.0.0\"\nend\n"
|
59
|
+
file.create
|
60
|
+
|
61
|
+
file = Palco::FileBase.new(@r, "spec/spec_helper.rb")
|
62
|
+
file.file_content = "require '#{@r}'\n"
|
63
|
+
file.create
|
64
|
+
|
65
|
+
|
66
|
+
file = Palco::FileBase.new(@r, "app.rb")
|
67
|
+
file.file_content = "require 'sinatra/base'\nclass #{@r.capitalize} < Sinatra::Base\n# ... app code here ... \n\n # start the server if execute this file directly\n run! if app_file == $0\nend\n"
|
68
|
+
file.create
|
69
|
+
|
70
|
+
file = Palco::FileBase.new(@r, "config.ru")
|
71
|
+
file.file_content = "require './app'\nlog = File.new(\"logs/#{@r}.log\", \"a\")\nSTDOUT.reopen(log)\nSTDERR.reopen(log)\nrun #{@r.capitalize}::App\n"
|
72
|
+
file.create
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
data/lib/palco/base.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
# Public: the base palco skelethon builder.
|
3
|
+
#
|
4
|
+
# Ideally it will never called directly but it will be subclassed by
|
5
|
+
# Palco::Extension and Palco::Application
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
#
|
9
|
+
# base = Palco::Base.new('a_test', [{:name=>'README', :file=>true}, {:name=>'lib', :file=>false}])
|
10
|
+
# base.generate
|
11
|
+
#
|
12
|
+
module Palco
|
13
|
+
class Base
|
14
|
+
|
15
|
+
# Public: creates a new base palco instance.
|
16
|
+
#
|
17
|
+
# The idea is that specialized classes extending Palco::Base will be aware
|
18
|
+
# about the list of files and directories to be created, meanwhile the
|
19
|
+
# Palco::Base takes this list without any clue about their meaning.
|
20
|
+
#
|
21
|
+
# name - the name of the Sinatra project
|
22
|
+
# items_list - an array containing a list of hashes with name of the file to
|
23
|
+
# be created and a second param telling the code code it the item is either
|
24
|
+
# a file or a directory.
|
25
|
+
#
|
26
|
+
# Example
|
27
|
+
#
|
28
|
+
# base = Palco::Base.new('test_one',[{:name=>'README', :file=>true}, {:name=>'lib', :file=>false}])
|
29
|
+
# Returns
|
30
|
+
# A new Palco::Base object
|
31
|
+
|
32
|
+
attr_reader :project_name
|
33
|
+
attr_reader :items_list
|
34
|
+
attr_reader :valid
|
35
|
+
attr_reader :generated
|
36
|
+
|
37
|
+
def initialize(name=nil, items_list=[])
|
38
|
+
@project_name = name
|
39
|
+
@items_list = items_list
|
40
|
+
@generated = false
|
41
|
+
|
42
|
+
if @project_name.nil? or @items_list.size==0
|
43
|
+
@valid = false
|
44
|
+
else
|
45
|
+
@valid = true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Public: generates the skelethon
|
50
|
+
#
|
51
|
+
# Example
|
52
|
+
# base = Palco::Base.new('test_one',[{:name=>'README', :file=>true}, {:name=>'lib', :file=>false}])
|
53
|
+
# base.generate
|
54
|
+
#
|
55
|
+
# Returns
|
56
|
+
# True if every item in the item list has been created of false otherwise.
|
57
|
+
#
|
58
|
+
def generate
|
59
|
+
if ! self.can_generate?
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
|
63
|
+
FileUtils.mkdir(File.join(Dir.pwd, @project_name))
|
64
|
+
|
65
|
+
@items_list.each do |item|
|
66
|
+
fullname = File.join(Dir.pwd, @project_name, item[:name])
|
67
|
+
isfile = item[:file]
|
68
|
+
if isfile
|
69
|
+
FileUtils.touch(fullname)
|
70
|
+
else
|
71
|
+
FileUtils.mkdir(fullname)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@generated = true
|
75
|
+
return true
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
# Public: destroy the skelethon removing all files and all directories.
|
80
|
+
# Also the base directory has been removed as well.
|
81
|
+
#
|
82
|
+
# Please note that you're not supposed to call destroy for a non generated
|
83
|
+
# skelethon. The method returns false in this case.
|
84
|
+
#
|
85
|
+
# Example
|
86
|
+
# base = Palco::Base.new('test_one',[{:name=>'README', :file=>true}, {:name=>'lib', :file=>false}])
|
87
|
+
# base.generate
|
88
|
+
# base.destroy
|
89
|
+
#
|
90
|
+
# Returns
|
91
|
+
# True if all items in the item list has been removed or false otherwise.
|
92
|
+
#
|
93
|
+
def destroy
|
94
|
+
if ! self.generated? and self.can_generate?
|
95
|
+
return false
|
96
|
+
end
|
97
|
+
FileUtils.rm_rf(@project_name)
|
98
|
+
@valid = false
|
99
|
+
@generated= false
|
100
|
+
true
|
101
|
+
end
|
102
|
+
|
103
|
+
def can_generate?
|
104
|
+
! File.directory?(File.join(Dir.pwd, @project_name))
|
105
|
+
end
|
106
|
+
|
107
|
+
def valid?
|
108
|
+
return self.valid
|
109
|
+
end
|
110
|
+
|
111
|
+
def generated?
|
112
|
+
return self.generated
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Palco
|
2
|
+
class Extension < Palco::Base
|
3
|
+
FILE_LIST = [
|
4
|
+
{:name=>'README', :file=>true},
|
5
|
+
{:name=>'LICENSE', :file=>true},
|
6
|
+
{:name=>'Rakefile', :file=>true},
|
7
|
+
{:name=>'lib', :file=>false},
|
8
|
+
{:name=>'lib/sinatra', :file=>false},
|
9
|
+
{:name=>'spec', :file=>false},
|
10
|
+
{:name=>'spec/spec_helper.rb', :file=>true},
|
11
|
+
{:name=>'LICENSE', :file=>true},
|
12
|
+
]
|
13
|
+
|
14
|
+
# Public: creates a new Sinatra Extension skeleton
|
15
|
+
#
|
16
|
+
# The idea is to pack the extension as a rubygem as described here:
|
17
|
+
# http://www.sinatrarb.com/extensions.html
|
18
|
+
#
|
19
|
+
# Example
|
20
|
+
# ext = Palco::Extension.new('testme')
|
21
|
+
# ext.generate
|
22
|
+
#
|
23
|
+
# Returns
|
24
|
+
# A new Sinatra extension directory read to be packed as a rubygem
|
25
|
+
|
26
|
+
def initialize(name)
|
27
|
+
@r = name
|
28
|
+
list = FILE_LIST
|
29
|
+
list = list << {:name=>"lib/sinatra/version.rb", :file=>true}
|
30
|
+
list = list << {:name=>"spec/sinatra_#{name}_spec.rb", :file=>true}
|
31
|
+
list = list << {:name=>"sinatra_#{name}.gemspec", :file=>true}
|
32
|
+
|
33
|
+
super(name, list)
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate
|
37
|
+
super
|
38
|
+
license = Palco::License.new(@r)
|
39
|
+
license.create
|
40
|
+
gemspec = Palco::Gemspec.new(@r)
|
41
|
+
gemspec.create
|
42
|
+
|
43
|
+
file = Palco::FileBase.new(@r, "lib/sinatra/version.rb")
|
44
|
+
file.file_content = "module #{@r.capitalize}\nVERSION=\"0.0.0\"\nend\n"
|
45
|
+
file.create
|
46
|
+
|
47
|
+
file = Palco::FileBase.new(@r, "spec/spec_helper.rb")
|
48
|
+
file.file_content = "require '#{@r}'\n"
|
49
|
+
file.create
|
50
|
+
|
51
|
+
file = Palco::FileBase.new(@r, "lib/sinatra/#{@r}.rb")
|
52
|
+
file.file_content ="require 'sinatra/base'\n\nmodule Sinatra\nmodule #{@r.capitalize}\nend\nregister #{@r}\nend\n"
|
53
|
+
file.create
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'git'
|
2
|
+
|
3
|
+
module Palco
|
4
|
+
|
5
|
+
# Public: this is a generic file class used to provide some common methods
|
6
|
+
# such as writing contents in a text file or reading or comparing a content.
|
7
|
+
class FileBase
|
8
|
+
|
9
|
+
|
10
|
+
attr_reader :root_dir
|
11
|
+
attr_reader :user_name
|
12
|
+
attr_reader :email
|
13
|
+
attr_reader :full_path_name
|
14
|
+
|
15
|
+
attr_accessor :file_content
|
16
|
+
|
17
|
+
def initialize(root_dir, name)
|
18
|
+
@full_path_name = File.join(Dir.pwd, root_dir, name)
|
19
|
+
conf = Git.global_config
|
20
|
+
@user_name = conf["user.name"]
|
21
|
+
@email = conf["user.email"]
|
22
|
+
@file_content = ""
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def exists?
|
27
|
+
File.exists?(@full_path_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def read
|
31
|
+
f= File.open(@full_path_name)
|
32
|
+
content = f.read
|
33
|
+
content
|
34
|
+
end
|
35
|
+
|
36
|
+
def write(content)
|
37
|
+
begin
|
38
|
+
f=File.open(@full_path_name, "w")
|
39
|
+
f.write(content)
|
40
|
+
f.close
|
41
|
+
true
|
42
|
+
rescue Exception
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def find(string)
|
49
|
+
text = self.read
|
50
|
+
text.include?(string)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Public: creates a new file.
|
54
|
+
#
|
55
|
+
# Please note that it's up to every subclass to fill the file_content
|
56
|
+
#
|
57
|
+
# Example
|
58
|
+
# file = Palco::File.new('test', 'a_file')
|
59
|
+
# a.create
|
60
|
+
#
|
61
|
+
# Returns
|
62
|
+
# Returns true if the file can be created with the proper content or
|
63
|
+
# false otherwise
|
64
|
+
def create
|
65
|
+
self.write(@file_content)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Palco
|
2
|
+
class Gemspec < Palco::FileBase
|
3
|
+
|
4
|
+
def initialize(root_dir)
|
5
|
+
super(root_dir, "sinatra_#{root_dir}.gemspec")
|
6
|
+
@file_content = "# -*- encoding: utf-8 -*-"
|
7
|
+
@file_content << "$:.push File.expand_path(\"../lib\", __FILE__)\n"
|
8
|
+
@file_content << "require \"palco/version\"\n"
|
9
|
+
|
10
|
+
@file_content << "Gem::Specification.new do |s|\n"
|
11
|
+
@file_content << "s.name = \"#{root_dir}\"\n"
|
12
|
+
@file_content << "s.version = #{root_dir.capitalize}::VERSION\n"
|
13
|
+
@file_content << "s.authors = [\"#{self.user_name}\"]\n"
|
14
|
+
@file_content << "s.email = [\"#{self.email}\"]\n"
|
15
|
+
@file_content << "s.homepage = \"add your project homepage\"\n"
|
16
|
+
@file_content << "s.summary = %q{write a great summary here}\n"
|
17
|
+
@file_content << "s.description = %q{write a great description here}\n"
|
18
|
+
@file_content << "\n"
|
19
|
+
@file_content << "s.rubyforge_project = \"#{root_dir}\"\n"
|
20
|
+
@file_content << "\n"
|
21
|
+
@file_content << "s.files = `git ls-files`.split(\"\\n\")\n"
|
22
|
+
@file_content << "s.test_files = `git ls-files -- {test,spec,features}/*`.split(\"\\n\")\n"
|
23
|
+
@file_content << "s.executables = `git ls-files -- bin/*`.split(\"\\n\").map{ |f| File.basename(f) }\n"
|
24
|
+
@file_content << "s.require_paths = [\"lib\"]\n"
|
25
|
+
@file_content << "# specify any dependencies here; for example:\n"
|
26
|
+
@file_content << "# s.add_development_dependency \"rspec\"\n"
|
27
|
+
@file_content << "end\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Palco
|
2
|
+
# Public: models the LICENSE file. Since I like it, I choose the new BSD
|
3
|
+
# License as reference.
|
4
|
+
#
|
5
|
+
# It's approved for opensource projects: http://www.opensource.org/licenses/BSD-3-Clause
|
6
|
+
#
|
7
|
+
# Information about author are retrieved using Git rubygem to global
|
8
|
+
# configuration.
|
9
|
+
#
|
10
|
+
# Examples:
|
11
|
+
# license = Palco::License.new('test')
|
12
|
+
# license.create #=> creates a test/LICENSE file containing the 3 clause BSD license
|
13
|
+
# license.new_bsd? #=> true
|
14
|
+
class License < Palco::FileBase
|
15
|
+
|
16
|
+
attr_reader :organization_name
|
17
|
+
|
18
|
+
def initialize(root_dir, organization_name="")
|
19
|
+
super(root_dir, "LICENSE")
|
20
|
+
@file_content = "Copyright (c) #{Time.now.year}, #{self.user_name} - <#{self.email}>\n"
|
21
|
+
@file_content << "All rights reserved.\n\n"
|
22
|
+
@file_content << "Redistribution and use in source and binary forms, with or without\n"
|
23
|
+
@file_content << "modification, are permitted provided that the following conditions are met:\n"
|
24
|
+
@file_content << " * Redistributions of source code must retain the above copyright\n"
|
25
|
+
@file_content << " notice, this list of conditions and the following disclaimer.\n"
|
26
|
+
@file_content << " * Redistributions in binary form must reproduce the above copyright\n"
|
27
|
+
@file_content << " notice, this list of conditions and the following disclaimer in the\n"
|
28
|
+
@file_content << " documentation and/or other materials provided with the distribution.\n"
|
29
|
+
@file_content << " * Neither the name of the #{@organization_name} nor the\n"
|
30
|
+
@file_content << " names of its contributors may be used to endorse or promote products\n"
|
31
|
+
@file_content << " derived from this software without specific prior written permission.\n\n"
|
32
|
+
@file_content << "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\n"
|
33
|
+
@file_content << "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
|
34
|
+
@file_content << "WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n"
|
35
|
+
@file_content << "DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY\n"
|
36
|
+
@file_content << "DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n"
|
37
|
+
@file_content << "(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n"
|
38
|
+
@file_content << "LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n"
|
39
|
+
@file_content << "ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
|
40
|
+
@file_content << "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n"
|
41
|
+
@file_content << "SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
|
42
|
+
|
43
|
+
@organization_name = organization_name
|
44
|
+
end
|
45
|
+
|
46
|
+
def new_bsd?
|
47
|
+
return self.find(@file_content)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/palco.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "palco/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "palco"
|
7
|
+
s.version = Palco::VERSION
|
8
|
+
s.authors = ["Paolo Perego"]
|
9
|
+
s.email = ["thesp0nge@gmail.com"]
|
10
|
+
s.homepage = "http://armoredcode.com"
|
11
|
+
s.summary = %q{Creates Sinatra application and extension directory layout}
|
12
|
+
s.description = %q{Creates Sinatra application and extension directory layout}
|
13
|
+
|
14
|
+
s.rubyforge_project = "palco"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "git"
|
24
|
+
s.add_development_dependency 'rake'
|
25
|
+
s.add_development_dependency 'rspec'
|
26
|
+
s.add_development_dependency 'rainbow'
|
27
|
+
|
28
|
+
s.add_runtime_dependency "rainbow"
|
29
|
+
s.add_runtime_dependency "git"
|
30
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Palco::Base package " do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@base = Palco::Base.new('test_one', [{:name=>'README', :file=>true}, {:name=>'a_directory', :file=>false}])
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:all) do
|
10
|
+
@base.destroy
|
11
|
+
end
|
12
|
+
|
13
|
+
it "must be well initialized" do
|
14
|
+
@base.project_name.should == "test_one"
|
15
|
+
@base.valid?.should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
it "creates a project named 'test_one'" do
|
20
|
+
@base.generate.should be_true
|
21
|
+
File.directory?("test_one").should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "creates a README file in 'test_one' directory" do
|
25
|
+
File.exists?("test_one/README").should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "creates a directory called 'a_directory' inside 'test_one'" do
|
29
|
+
File.directory?("test_one/a_directory").should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "removes all if destroy method has been called" do
|
33
|
+
@base.destroy
|
34
|
+
@base.valid?.should be_false
|
35
|
+
File.directory?("test_one").should be_false
|
36
|
+
File.exists?("test_one/README").should be_false
|
37
|
+
File.directory?("test_one/a_directory").should be_false
|
38
|
+
end
|
39
|
+
|
40
|
+
it "cannot remove a skelethon that it has not been generated before" do
|
41
|
+
@base = Palco::Base.new('test_two', [{:name=>'README', :file=>true}, {:name=>'a_directory', :file=>false}])
|
42
|
+
File.directory?("test_two").should be_false
|
43
|
+
File.exists?("test_two/README").should be_false
|
44
|
+
File.directory?("test_two/a_directory").should be_false
|
45
|
+
@base.destroy.should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "must provide an handy generated? handler telling that everything is ok" do
|
49
|
+
@base = Palco::Base.new('test_three', [{:name=>'README', :file=>true}, {:name=>'a_directory', :file=>false}])
|
50
|
+
@base.generated?.should be_false
|
51
|
+
@base.generate
|
52
|
+
File.directory?("test_three").should be_true
|
53
|
+
File.exists?("test_three/README").should be_true
|
54
|
+
File.directory?("test_three/a_directory").should be_true
|
55
|
+
@base.generated?.should be_true
|
56
|
+
@base.destroy
|
57
|
+
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "When palco it's used to generate Sinatra applications" do
|
4
|
+
before(:all) do
|
5
|
+
@extension = Palco::Application.new('test_app')
|
6
|
+
end
|
7
|
+
after (:all) do
|
8
|
+
@extension.destroy
|
9
|
+
end
|
10
|
+
it "it must generate a valid skeleton" do
|
11
|
+
@extension.valid?.should be_true
|
12
|
+
@extension.generated?.should be_false
|
13
|
+
@extension.generate
|
14
|
+
@extension.generated?.should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "it must create a LICENSE file in target dir" do
|
18
|
+
File.exists?("test_app/README").should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "it must create a Gemfile file in target dir" do
|
22
|
+
File.exists?("test_app/Gemfile").should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "it must create a app.rb file in target dir" do
|
26
|
+
File.exists?("test_app/app.rb").should be_true
|
27
|
+
end
|
28
|
+
it "it must create a config.ru file in target dir" do
|
29
|
+
File.exists?("test_app/config.ru").should be_true
|
30
|
+
end
|
31
|
+
it "it must create a lib directory in target dir" do
|
32
|
+
File.directory?("test_app/lib").should be_true
|
33
|
+
end
|
34
|
+
it "it must create a public directory in target dir" do
|
35
|
+
File.directory?("test_app/public").should be_true
|
36
|
+
end
|
37
|
+
it "it must create a views directory in target dir" do
|
38
|
+
File.directory?("test_app/views").should be_true
|
39
|
+
end
|
40
|
+
it "it must create a logs directory in target dir" do
|
41
|
+
File.directory?("test_app/logs").should be_true
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "When palco it's used to generate Sinatra extensions" do
|
4
|
+
before(:all) do
|
5
|
+
@extension = Palco::Extension.new('test_ext')
|
6
|
+
end
|
7
|
+
after (:all) do
|
8
|
+
@extension.destroy
|
9
|
+
end
|
10
|
+
it "it must generate a valid skeleton" do
|
11
|
+
@extension.valid?.should be_true
|
12
|
+
@extension.generated?.should be_false
|
13
|
+
@extension.generate
|
14
|
+
@extension.generated?.should be_true
|
15
|
+
end
|
16
|
+
|
17
|
+
it "it must create a README file in target dir" do
|
18
|
+
File.exists?("test_ext/README").should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "it must create a LICENSE file in target dir" do
|
22
|
+
File.exists?("test_ext/LICENSE").should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "it must create a gemspec to pack the extensiokn" do
|
26
|
+
File.exists?("test_ext/sinatra_test_ext.gemspec").should be_true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "Sinatra extension generated by palco" do
|
31
|
+
before(:all) do
|
32
|
+
@extension = Palco::Extension.new('test_ext')
|
33
|
+
end
|
34
|
+
after (:all) do
|
35
|
+
@extension.destroy
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must have a 3-clause or New BSD License" do
|
39
|
+
@extension.generate
|
40
|
+
license = Palco::License.new('test_ext')
|
41
|
+
license.new_bsd?.should be_true
|
42
|
+
spec = Palco::Gemspec.new('test_ext', 'sinatra_test_ext.gemspec')
|
43
|
+
spec.find("s.rubyforge_project = \"test_ext\"\n")
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'palco'
|
metadata
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: palco
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Paolo Perego
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-30 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: git
|
16
|
+
requirement: &70110997800060 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70110997800060
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70110997799640 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70110997799640
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70110997799220 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70110997799220
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rainbow
|
49
|
+
requirement: &70110997798800 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70110997798800
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rainbow
|
60
|
+
requirement: &70110997798380 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70110997798380
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: git
|
71
|
+
requirement: &70110997797960 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70110997797960
|
80
|
+
description: Creates Sinatra application and extension directory layout
|
81
|
+
email:
|
82
|
+
- thesp0nge@gmail.com
|
83
|
+
executables:
|
84
|
+
- palco
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files: []
|
87
|
+
files:
|
88
|
+
- .gitignore
|
89
|
+
- Gemfile
|
90
|
+
- LICENSE
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- bin/palco
|
94
|
+
- lib/README.md
|
95
|
+
- lib/palco.rb
|
96
|
+
- lib/palco/application.rb
|
97
|
+
- lib/palco/base.rb
|
98
|
+
- lib/palco/extension.rb
|
99
|
+
- lib/palco/filebase.rb
|
100
|
+
- lib/palco/gemspec.rb
|
101
|
+
- lib/palco/license.rb
|
102
|
+
- lib/palco/version.rb
|
103
|
+
- palco.gemspec
|
104
|
+
- spec/palco_base_spec.rb
|
105
|
+
- spec/palco_generate_applications_spec.rb
|
106
|
+
- spec/palco_generate_extensions_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
homepage: http://armoredcode.com
|
109
|
+
licenses: []
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
requirements: []
|
127
|
+
rubyforge_project: palco
|
128
|
+
rubygems_version: 1.8.10
|
129
|
+
signing_key:
|
130
|
+
specification_version: 3
|
131
|
+
summary: Creates Sinatra application and extension directory layout
|
132
|
+
test_files:
|
133
|
+
- spec/palco_base_spec.rb
|
134
|
+
- spec/palco_generate_applications_spec.rb
|
135
|
+
- spec/palco_generate_extensions_spec.rb
|
136
|
+
- spec/spec_helper.rb
|