richcss 0.1.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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +76 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/richcss +5 -0
- data/bin/setup +7 -0
- data/exe/richcss +5 -0
- data/lib/richcss/cli.rb +105 -0
- data/lib/richcss/generator/routes.scss +18 -0
- data/lib/richcss/generators.rb +109 -0
- data/lib/richcss/manager.rb +213 -0
- data/lib/richcss/part.rb +119 -0
- data/lib/richcss/resolver.rb +27 -0
- data/lib/richcss/richcss_specification_provider.rb +75 -0
- data/lib/richcss/richcss_test_specification.rb +22 -0
- data/lib/richcss/richcss_ui.rb +34 -0
- data/lib/richcss/version.rb +3 -0
- data/lib/richcss.rb +15 -0
- data/richcss.gemspec +31 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 09d0e0a3a4e317c7dafce1aa4d3c1fc5cd2b6e1f
|
4
|
+
data.tar.gz: 411df6d822124af8ec79443d4afc5c48131518fe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2877d5bea707c176149564ba298572015a8c13e0bb754bdceaaf475f2ce524fe537b0ea00181cce8aae4455f2a49e888038d126ba3d82a0837fcf87e46ce991a
|
7
|
+
data.tar.gz: ff506b25f7dcec0ad306896a2462c2b489081b1353415dbdf6f8b47f56beecfaed9d31ae2de5c367ab194f8d1592237b21379bf0114ef0f8f5e6c829df01fed3
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 TODO: Write your name
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Richcss-cli
|
2
|
+
|
3
|
+
Richcss CLI is a tool to manage your CSS using the RichCSS framework.
|
4
|
+
It also includes a package manager to help install and create your own RichCSS parts for others to use.
|
5
|
+
|
6
|
+
Both CSS and SASS are supported.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'richcss'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install richcss
|
23
|
+
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
### Using RichCSS in your project
|
28
|
+
|
29
|
+
To start, in the directory where you want to put all your CSS, run
|
30
|
+
|
31
|
+
$ richcss init
|
32
|
+
|
33
|
+
to create the skeleton structure. Currently, only CSS is supported by `init`.
|
34
|
+
|
35
|
+
#### Using RichCSS parts
|
36
|
+
|
37
|
+
In the directory created using `richcss init`, you can install third-party parts using
|
38
|
+
|
39
|
+
$ richcss install <PART> [VERSION]
|
40
|
+
|
41
|
+
The version is optional and will default to the latest version of that part.
|
42
|
+
|
43
|
+
### Creating your own RichCSS Part
|
44
|
+
|
45
|
+
Generate the necessary files for your Part with
|
46
|
+
|
47
|
+
$ richcss part init <PART_NAME>
|
48
|
+
|
49
|
+
#### Publishing your Part for others to use
|
50
|
+
|
51
|
+
Before releasing your Part to the public, you may run
|
52
|
+
|
53
|
+
$ richcss part check [PART_PATH]
|
54
|
+
|
55
|
+
to make sure everything is valid. Then publish it to CSSParts with
|
56
|
+
|
57
|
+
$ richcss part push <PART_NAME>
|
58
|
+
|
59
|
+
|
60
|
+
## Development
|
61
|
+
|
62
|
+
After checking out the repo, run `bundle install` to install dependencies.
|
63
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
64
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
65
|
+
which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
66
|
+
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
|
70
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/fdp-A4/richcss-cli
|
71
|
+
|
72
|
+
|
73
|
+
## License
|
74
|
+
|
75
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
76
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "richcss"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/richcss
ADDED
data/bin/setup
ADDED
data/exe/richcss
ADDED
data/lib/richcss/cli.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'richcss'
|
3
|
+
|
4
|
+
module RichcssCLI
|
5
|
+
class Part < Thor
|
6
|
+
desc "init <PART_NAME>", "Generate a skeleton directory for your new Rich CSS part"
|
7
|
+
# part_name
|
8
|
+
# |--- lib
|
9
|
+
# | |--- elements
|
10
|
+
# | | |--- ...
|
11
|
+
# | |--- box
|
12
|
+
# | | |--- ...
|
13
|
+
# |--- part_name.spec
|
14
|
+
# |--- README.md
|
15
|
+
def init(part)
|
16
|
+
Richcss::Generators::PartTemplate.start([part])
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "check [PART_PATH]", "Validate folder/file structure of the Rich CSS part, optionally passing in a path"
|
20
|
+
def check(part_dir_name=nil)
|
21
|
+
part_path = "#{Dir.pwd}" + "/" + "#{part_dir_name}" || Dir.pwd
|
22
|
+
result = Richcss::Manager.check(part_path)
|
23
|
+
Dir.chdir(part_path)
|
24
|
+
if !result.nil?
|
25
|
+
puts result
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
|
29
|
+
partPathSplit = part_path.split("/")
|
30
|
+
partName = partPathSplit[partPathSplit.length - 1]
|
31
|
+
|
32
|
+
puts "Passed all validation checks, part: #{partName} is ready for upload!"
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "push <PART_PATH>", "Attempt to upload a new Rich CSS part to our servers"
|
37
|
+
def push(part_dir_name=nil)
|
38
|
+
part_path = "#{Dir.pwd}" + "/" + "#{part_dir_name}" || Dir.pwd
|
39
|
+
if check(part_dir_name)
|
40
|
+
Richcss::Manager.upload(part_path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Cli < Thor
|
46
|
+
desc "init", "Initialize current directory to follow the Rich CSS framework"
|
47
|
+
# elements
|
48
|
+
# |--- ...
|
49
|
+
# box
|
50
|
+
# |--- ...
|
51
|
+
# parts
|
52
|
+
# |--- ...
|
53
|
+
def init()
|
54
|
+
Richcss::Generators::Template.start()
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "install <PART> [VERSION]", "Install the part requested into the Parts directory"
|
58
|
+
def install(part_name, part_version='')
|
59
|
+
installed_parts = Richcss::Part.get_or_create_partfile()
|
60
|
+
if part_version.eql?('')
|
61
|
+
RestClient.get("http://www.cssparts.com/api/part/#{part_name}") { |response, request, result, &block|
|
62
|
+
if response.code == 200
|
63
|
+
body = JSON.parse(response.to_str)
|
64
|
+
part_version = body["version"]
|
65
|
+
elsif response.code == 400
|
66
|
+
puts "Part: #{part_name} cannot be found."
|
67
|
+
return
|
68
|
+
else
|
69
|
+
puts "Error #{response.code} retrieving Part: #{part_name}"
|
70
|
+
return
|
71
|
+
end
|
72
|
+
}
|
73
|
+
else
|
74
|
+
RestClient.get("http://www.cssparts.com/api/part/#{part_name}", {:params => {'version' => part_version}}) { |response, request, result, &block|
|
75
|
+
if response.code == 400
|
76
|
+
puts "Part: #{part_name} #{part_version} does not exist."
|
77
|
+
return
|
78
|
+
elsif response.code != 200
|
79
|
+
puts "Error #{response.code} retrieving Part: #{part_name} #{part_version}"
|
80
|
+
return
|
81
|
+
end
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
if installed_parts.key?(part_name) and installed_parts[part_name].eql?(part_version)
|
86
|
+
puts "Part #{part_name} v#{part_version} is already installed!"
|
87
|
+
return
|
88
|
+
end
|
89
|
+
|
90
|
+
partfileList = ''
|
91
|
+
dep_list = Richcss::Part.resolve_dependencies(part_name, part_version, installed_parts)
|
92
|
+
dep_list.each do |dep|
|
93
|
+
Richcss::Part.fetch(dep.name, dep.version)
|
94
|
+
partfileList << dep.name << " " << dep.version.to_s << "\n"
|
95
|
+
end
|
96
|
+
|
97
|
+
File.open('parts/Partfile', 'wb') do |f|
|
98
|
+
f.write(partfileList)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
desc "part", "Commands for creating and uploading your own Rich CSS parts"
|
103
|
+
subcommand "part", Part
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/* Import all your CSS files here */
|
2
|
+
|
3
|
+
/* Box CSS */
|
4
|
+
@import 'box/blocks.scss';
|
5
|
+
@import 'box/main.scss';
|
6
|
+
@import 'box/positioning.scss';
|
7
|
+
|
8
|
+
/* Element CSS */
|
9
|
+
@import 'elements/buttons.scss';
|
10
|
+
@import 'elements/colors.scss';
|
11
|
+
@import 'elements/features.scss';
|
12
|
+
@import 'elements/fonts.scss';
|
13
|
+
@import 'elements/images.scss';
|
14
|
+
@import 'elements/inputs.scss';
|
15
|
+
@import 'elements/lists.scss';
|
16
|
+
|
17
|
+
/* Parts CSS */
|
18
|
+
@import 'parts/parts.scss';
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'thor/group'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Richcss
|
5
|
+
module Generators
|
6
|
+
class Template < Thor::Group
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
def self.source_root
|
10
|
+
File.dirname(__FILE__) + "/generator"
|
11
|
+
end
|
12
|
+
|
13
|
+
def init
|
14
|
+
@groups = ['box', 'elements', 'parts']
|
15
|
+
@boxFiles = ['blocks', 'main', 'positioning']
|
16
|
+
@elementFiles = ['button', 'colors', 'features', 'fonts', 'images', 'inputs', 'lists']
|
17
|
+
@partFiles = ['Partfile']
|
18
|
+
end
|
19
|
+
|
20
|
+
def create_folders
|
21
|
+
@groups.each do |g|
|
22
|
+
empty_directory("#{g}") unless Dir.exists?("#{g}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_css_files
|
27
|
+
# TODO: add choice of CSS or SCSS files to generate
|
28
|
+
# TODO: Make it not hardcode box/elements
|
29
|
+
extension = ".css"
|
30
|
+
# extension = ".css.scss"
|
31
|
+
@boxFiles.each do |filename|
|
32
|
+
create_file "box/#{filename}#{extension}" unless File.file?("box/#{filename}#{extension}")
|
33
|
+
end
|
34
|
+
|
35
|
+
@elementFiles.each do |filename|
|
36
|
+
create_file "elements/#{filename}#{extension}" unless File.file?("elements/#{filename}#{extension}")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_partfile
|
41
|
+
create_file "parts/Partfile" unless File.file?("parts/Partfile")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class PartTemplate < Thor::Group
|
46
|
+
include Thor::Actions
|
47
|
+
|
48
|
+
argument :part_name, :type => :array
|
49
|
+
# argument :part, :type => :array
|
50
|
+
# argument :part_name, :type => :string
|
51
|
+
|
52
|
+
def self.source_root
|
53
|
+
File.dirname(__FILE__) + "/generator"
|
54
|
+
end
|
55
|
+
|
56
|
+
def init
|
57
|
+
@name = part_name.first
|
58
|
+
@groups = ['box', 'elements']
|
59
|
+
@boxFiles = ['blocks', 'main', 'positioning']
|
60
|
+
@elementFiles = ['button', 'colors', 'features', 'fonts', 'images', 'inputs', 'lists']
|
61
|
+
end
|
62
|
+
|
63
|
+
def create_folders
|
64
|
+
empty_directory(@name) unless Dir.exists?(@name)
|
65
|
+
empty_directory("#{@name}/lib") unless Dir.exists?("#{@name}/lib")
|
66
|
+
@groups.each do |g|
|
67
|
+
empty_directory("#{@name}/lib/#{g}") unless Dir.exists?("#{@name}/lib/#{g}")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_css_files
|
72
|
+
# TODO: add choice of CSS or SCSS files to generate
|
73
|
+
# TODO: Make it not hardcode box/elements
|
74
|
+
extension = ".css"
|
75
|
+
# extension = ".css.scss"
|
76
|
+
@boxFiles.each do |filename|
|
77
|
+
create_file "#{@name}/lib/box/#{filename}#{extension}" unless File.file?("#{@name}/lib/box/#{filename}#{extension}")
|
78
|
+
end
|
79
|
+
|
80
|
+
@elementFiles.each do |filename|
|
81
|
+
create_file "#{@name}/lib/elements/#{filename}#{extension}" unless File.file?("#{@name}/lib/elements/#{filename}#{extension}")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_files
|
86
|
+
create_file "#{@name}/README.md" unless File.file?("#{@name}/README.md")
|
87
|
+
|
88
|
+
if !File.file?("#{@name}/#{@name.downcase}.spec")
|
89
|
+
create_file "#{@name}/#{@name.downcase}.spec"
|
90
|
+
# Write JSON to Test.Spec
|
91
|
+
specs = {
|
92
|
+
"name" => "#{@name}",
|
93
|
+
"authors" => "AUTHOR_NAME",
|
94
|
+
"email" => "AUTHOR_EMAIL",
|
95
|
+
"description" => "DESCRIPTION",
|
96
|
+
"version" => "0.0.0",
|
97
|
+
"homepage" => "GITHUB_REPO_URL",
|
98
|
+
"dependencies" => {
|
99
|
+
"DEPENDECY_NAME" => "DEPENDECY_VERSION"
|
100
|
+
}
|
101
|
+
}
|
102
|
+
File.open("#{@name}/#{@name.downcase}.spec","w") do |f|
|
103
|
+
f.write(JSON.pretty_generate(specs))
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require 'richcss'
|
2
|
+
require 'rest-client'
|
3
|
+
require 'json'
|
4
|
+
require 'active_model'
|
5
|
+
require 'email_validator'
|
6
|
+
|
7
|
+
module Richcss
|
8
|
+
class Manager
|
9
|
+
# Checks if the folder has the required format for uploading
|
10
|
+
def self.check(check_dir)
|
11
|
+
Dir.chdir(check_dir)
|
12
|
+
|
13
|
+
# LEVEL 1
|
14
|
+
# Find the spec file and the part name
|
15
|
+
part_name = ''
|
16
|
+
specFilePath = ''
|
17
|
+
Dir.glob("*.spec").each do |f|
|
18
|
+
part_name = File.basename(f, '.spec')
|
19
|
+
specFilePath = "#{check_dir}/#{f}"
|
20
|
+
end
|
21
|
+
if part_name.empty?
|
22
|
+
return "Rich CSS spec file not found"
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if readme exists
|
26
|
+
if !File.file?("#{check_dir}/README.md")
|
27
|
+
return "README.md file not found"
|
28
|
+
end
|
29
|
+
|
30
|
+
if !Dir.exist?('lib')
|
31
|
+
return "lib folder not found"
|
32
|
+
end
|
33
|
+
|
34
|
+
# LEVEL 2 / LIB
|
35
|
+
Dir.chdir('lib')
|
36
|
+
groups = ['box', 'elements']
|
37
|
+
|
38
|
+
groups.each do |g|
|
39
|
+
if !Dir.exist?(g)
|
40
|
+
return "#{g} folder not found in lib"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# LEVEL 3 BOX/ELEMENTS/PARTS
|
45
|
+
# TODO: Don't do this hardcoded for box/elements, use like some hashmap or something..
|
46
|
+
boxFiles = ['blocks', 'main', 'positioning']
|
47
|
+
elementFiles = ['button', 'colors', 'features', 'fonts', 'images', 'inputs', 'lists']
|
48
|
+
validExtensions = ['.css', '.css.scss']
|
49
|
+
|
50
|
+
fileCount = 0
|
51
|
+
Dir.foreach('box') do |filename|
|
52
|
+
next if filename == '.' or filename == '..'
|
53
|
+
boxFiles.each do |b|
|
54
|
+
validExtensions.each do |ext|
|
55
|
+
if filename == "#{b}#{ext}"
|
56
|
+
fileCount += 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if fileCount < boxFiles.size
|
63
|
+
return "Missing css files in box folder, required #{boxFiles}"
|
64
|
+
end
|
65
|
+
|
66
|
+
fileCount = 0
|
67
|
+
Dir.foreach('elements') do |filename|
|
68
|
+
next if filename == '.' or filename == '..'
|
69
|
+
elementFiles.each do |b|
|
70
|
+
validExtensions.each do |ext|
|
71
|
+
if filename == "#{b}#{ext}"
|
72
|
+
fileCount += 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
if fileCount < elementFiles.size
|
79
|
+
return "Missing css files in elements folder, required #{elementFiles}"
|
80
|
+
end
|
81
|
+
|
82
|
+
# SPEC FILE CHECK
|
83
|
+
specFile = "#{part_name}.spec"
|
84
|
+
|
85
|
+
begin
|
86
|
+
jsonData = File.read(specFilePath)
|
87
|
+
hash = JSON.parse(jsonData)
|
88
|
+
rescue
|
89
|
+
return "Invalid Json format in #{specFile}"
|
90
|
+
end
|
91
|
+
|
92
|
+
defaultSpecs = {
|
93
|
+
"authors" => "AUTHOR_NAME",
|
94
|
+
"email" => "AUTHOR_EMAIL",
|
95
|
+
"description" => "DESCRIPTION",
|
96
|
+
"homepage" => "GITHUB_REPO_URL"
|
97
|
+
}
|
98
|
+
requiredSpecs = ['name', 'authors', 'email', 'description', 'version', 'homepage', 'dependencies']
|
99
|
+
|
100
|
+
# Ensure each spec exist
|
101
|
+
requiredSpecs.each do |spec|
|
102
|
+
if hash[spec].nil? && spec != 'dependencies'
|
103
|
+
return "Missing \"#{spec}\" definition in #{specFile}"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Check for default entries
|
108
|
+
defaultSpecs.keys.each do |spec|
|
109
|
+
if hash[spec] == defaultSpecs[spec]
|
110
|
+
return "Default value for \"#{spec}\" in #{specFile} is being used, please change it to a valid entry"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Check email
|
115
|
+
if !EmailValidator.valid?(hash[requiredSpecs[2]])
|
116
|
+
return "Email address is invalid"
|
117
|
+
end
|
118
|
+
|
119
|
+
# Check Part_Name
|
120
|
+
if (hash[requiredSpecs[0]] != part_name)
|
121
|
+
return "Invalid part name: \"#{hash[requiredSpecs[0]]}\" in #{specFile}, should be \"#{part_name}\""
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
# Check if github url exist
|
126
|
+
uri = URI.parse(hash[requiredSpecs[5]])
|
127
|
+
|
128
|
+
http_object = Net::HTTP.new(uri.host, uri.port)
|
129
|
+
http_object.use_ssl = true if uri.scheme == 'https'
|
130
|
+
begin
|
131
|
+
http_object.start do |http|
|
132
|
+
request = Net::HTTP::Get.new uri.request_uri
|
133
|
+
http.read_timeout = 500
|
134
|
+
http.request request do |response|
|
135
|
+
case response
|
136
|
+
when Net::HTTPNotFound then
|
137
|
+
return "Could not access GitHub url, please use a public repository"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
rescue
|
142
|
+
return "Invalid URL for homepage"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Check for version
|
146
|
+
begin
|
147
|
+
resp = RestClient.get "http://www.cssparts.com/api/part/#{part_name}"
|
148
|
+
if resp.code == 200
|
149
|
+
body = JSON.parse(resp.to_str)
|
150
|
+
current_version = body["version"]
|
151
|
+
part_version = hash[requiredSpecs[4]]
|
152
|
+
if Gem::Version.new(current_version) >= Gem::Version.new(part_version)
|
153
|
+
return "Part version: \"#{part_version}\" in #{specFile} must be greater than existing version: \"#{current_version}\""
|
154
|
+
end
|
155
|
+
end
|
156
|
+
rescue RestClient::ExceptionWithResponse => e
|
157
|
+
end
|
158
|
+
|
159
|
+
# Check dependency existance
|
160
|
+
dependencies = hash[requiredSpecs[6]]
|
161
|
+
if dependencies.nil? || dependencies.empty?
|
162
|
+
return nil
|
163
|
+
end
|
164
|
+
|
165
|
+
begin
|
166
|
+
dependencies = dependencies.to_a.map { |x| "#{x[0]}=#{x[1].to_s}" }.join("&")
|
167
|
+
resp = RestClient.get "http://www.cssparts.com/api/validateDependencies/#{dependencies}"
|
168
|
+
rescue RestClient::ExceptionWithResponse => e
|
169
|
+
return e.response
|
170
|
+
end
|
171
|
+
|
172
|
+
return nil
|
173
|
+
end
|
174
|
+
|
175
|
+
# Fetch url and download the part
|
176
|
+
def self.getPartData(part_name)
|
177
|
+
begin
|
178
|
+
resp = RestClient.get "http://www.cssparts.com/api/part/#{part_name}"
|
179
|
+
if resp.code == 200
|
180
|
+
body = JSON.parse(resp.to_str)
|
181
|
+
return body
|
182
|
+
else
|
183
|
+
puts "Error: Part #{name} cannot be found."
|
184
|
+
end
|
185
|
+
rescue RestClient::ExceptionWithResponse => e
|
186
|
+
puts e.response
|
187
|
+
end
|
188
|
+
return nil
|
189
|
+
end
|
190
|
+
|
191
|
+
def self.upload(part_path)
|
192
|
+
partPathSplit = part_path.split("/")
|
193
|
+
partName = partPathSplit[partPathSplit.length - 1]
|
194
|
+
|
195
|
+
if !File.file?("#{part_path}/#{partName}.spec")
|
196
|
+
puts "#{part_path}/#{partName}.spec file not found"
|
197
|
+
return
|
198
|
+
end
|
199
|
+
|
200
|
+
specs = File.read("#{part_path}/#{partName}.spec")
|
201
|
+
specsJson = JSON.parse(specs)
|
202
|
+
|
203
|
+
begin
|
204
|
+
puts RestClient.post "http://www.cssparts.com/api/upload", :name => partName, :description => specsJson["description"],
|
205
|
+
:version => specsJson["version"], :authors => specsJson["authors"], :email => specsJson["email"], :homepage => specsJson["homepage"],
|
206
|
+
:dependencies => specsJson["dependencies"]
|
207
|
+
rescue RestClient::ExceptionWithResponse => e
|
208
|
+
puts e.response
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
end
|
213
|
+
end
|
data/lib/richcss/part.rb
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'rest-client'
|
3
|
+
require 'uri'
|
4
|
+
require 'zipruby'
|
5
|
+
|
6
|
+
module Richcss
|
7
|
+
class Part
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
# placeholder for latest version is blank
|
11
|
+
def self.resolve_dependencies(part_name, version, installed={})
|
12
|
+
dep_list = Richcss::Resolver.start(part_name, version, installed)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.get_or_create_partfile()
|
16
|
+
if !Dir.exists?('parts')
|
17
|
+
FileUtils.mkdir_p('parts')
|
18
|
+
end
|
19
|
+
|
20
|
+
parts = Hash.new
|
21
|
+
Dir.chdir('parts') do
|
22
|
+
part_file = "Partfile"
|
23
|
+
|
24
|
+
begin
|
25
|
+
File.open(part_file, "r") do |f|
|
26
|
+
f.each_line do |line|
|
27
|
+
part, version = line.split(" ")
|
28
|
+
parts[part] = version
|
29
|
+
end
|
30
|
+
end
|
31
|
+
rescue
|
32
|
+
File.new(part_file, "w")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
return parts
|
37
|
+
end
|
38
|
+
|
39
|
+
# Fetch url and download the part
|
40
|
+
def self.fetch(part_name, version)
|
41
|
+
puts "Fetching part #{part_name}"
|
42
|
+
|
43
|
+
begin
|
44
|
+
resp = RestClient.get "http://www.cssparts.com/api/part/#{part_name}"
|
45
|
+
if resp.code == 200
|
46
|
+
body = JSON.parse(resp.to_str)
|
47
|
+
homepage = body["homepage"]
|
48
|
+
homepage.slice! "https:\/\/github.com\/"
|
49
|
+
homepage = homepage.split("\/")
|
50
|
+
repo_owner = homepage[0]
|
51
|
+
repo_name = homepage[1]
|
52
|
+
jsonResponse = JSON.parse(Net::HTTP.get(URI("https://api.github.com/repos/#{repo_owner}/#{repo_name}/releases/tags/v#{body["version"]}")))
|
53
|
+
downloadLink = jsonResponse["zipball_url"]
|
54
|
+
install(part_name, body["version"], downloadLink)
|
55
|
+
else
|
56
|
+
puts "Error: Part #{name} cannot be found."
|
57
|
+
end
|
58
|
+
rescue RestClient::ExceptionWithResponse => e
|
59
|
+
puts e.response
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Install this part
|
64
|
+
def self.install(part_name, version, resource)
|
65
|
+
uri = URI.parse(resource)
|
66
|
+
|
67
|
+
http_object = Net::HTTP.new(uri.host, uri.port)
|
68
|
+
http_object.use_ssl = true if uri.scheme == 'https'
|
69
|
+
begin
|
70
|
+
http_object.start do |http|
|
71
|
+
request = Net::HTTP::Get.new uri.request_uri
|
72
|
+
http.read_timeout = 500
|
73
|
+
http.request request do |response|
|
74
|
+
case response
|
75
|
+
when Net::HTTPRedirection then
|
76
|
+
location = response['location']
|
77
|
+
install(part_name, version, location)
|
78
|
+
else
|
79
|
+
puts "Installing part..."
|
80
|
+
|
81
|
+
if !Dir.exists?('parts')
|
82
|
+
FileUtils.mkdir_p('parts')
|
83
|
+
end
|
84
|
+
|
85
|
+
Dir.chdir('parts') do
|
86
|
+
if Dir.exists?(part_name)
|
87
|
+
FileUtils.remove_dir(part_name)
|
88
|
+
end
|
89
|
+
Zip::Archive.open_buffer(response.body) do |ar|
|
90
|
+
#save the directory name for rename later
|
91
|
+
oldDirName = ar.get_name(0)
|
92
|
+
|
93
|
+
ar.each do |zf|
|
94
|
+
if zf.directory?
|
95
|
+
FileUtils.mkdir_p(zf.name)
|
96
|
+
else
|
97
|
+
dirname = File.dirname(zf.name)
|
98
|
+
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
|
99
|
+
open(zf.name, 'wb') do |f|
|
100
|
+
f << zf.read
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
FileUtils.mv oldDirName, part_name
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
RestClient.post "http://www.cssparts.com/api/part/downloaded", :name => part_name, :version => version
|
113
|
+
rescue Exception => e
|
114
|
+
puts e
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'molinillo'
|
2
|
+
require 'version_kit'
|
3
|
+
|
4
|
+
module Richcss
|
5
|
+
class Resolver
|
6
|
+
|
7
|
+
def self.start(part_name, version, installed = {})
|
8
|
+
requirements = [VersionKit::Dependency.new(part_name, version)]
|
9
|
+
installed.each do | p, v |
|
10
|
+
requirements.push(VersionKit::Dependency.new(p, v))
|
11
|
+
end
|
12
|
+
@resolver = Molinillo::Resolver.new(RichSpecificationProvider.new(part_name, version), RichUI.new)
|
13
|
+
@base_dg = Molinillo::DependencyGraph.new
|
14
|
+
dg = @resolver.resolve(requirements, @base_dg)
|
15
|
+
puts "Succesfully resolved dependencies:\n"
|
16
|
+
dg.map(&:payload).flatten
|
17
|
+
rescue Molinillo::VersionConflict => e
|
18
|
+
puts e
|
19
|
+
rescue Molinillo::CircularDependencyError => e
|
20
|
+
names = e.dependencies.sort_by(&:name).map {|d| "gem '#{d.name}'" }
|
21
|
+
puts "Your RichCSS part requires parts that depend" \
|
22
|
+
" on each other, creating an circular loop. Please remove" \
|
23
|
+
" #{names.count > 1 ? "either " : ""}#{names.join(" or ")}" \
|
24
|
+
" and try again."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'version_kit'
|
2
|
+
require 'molinillo'
|
3
|
+
|
4
|
+
module Richcss
|
5
|
+
class RichSpecificationProvider
|
6
|
+
attr_accessor :specs
|
7
|
+
attr_accessor :part_name
|
8
|
+
attr_accessor :version
|
9
|
+
|
10
|
+
include Molinillo::SpecificationProvider
|
11
|
+
|
12
|
+
def initialize(name, version)
|
13
|
+
self.part_name = name
|
14
|
+
self.version = version
|
15
|
+
response = RestClient.get "http://www.cssparts.com/api/part/#{name}/dependency", {:params => {'version' => version}}
|
16
|
+
if response.code == 200
|
17
|
+
self.specs = JSON.load(response.body).reduce(Hash.new([])) do |specs_by_name, (dep_name, dep_versions)|
|
18
|
+
specs_by_name.tap do |specs|
|
19
|
+
specs[dep_name] = dep_versions.map { |s| Richcss::TestSpecification.new s }.sort_by(&:version)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def requirement_satisfied_by?(requirement, _activated, spec)
|
26
|
+
requirement.satisfied_by?(spec.version)
|
27
|
+
end
|
28
|
+
|
29
|
+
def search_for(dependency)
|
30
|
+
@search_for ||= {}
|
31
|
+
@search_for[dependency] ||= begin
|
32
|
+
pre_release = dependency_pre_release?(dependency)
|
33
|
+
specs[dependency.name].select do |spec|
|
34
|
+
(pre_release ? true : !spec.version.pre_release?) &&
|
35
|
+
dependency.satisfied_by?(spec.version)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def name_for(dependency)
|
41
|
+
dependency.name
|
42
|
+
end
|
43
|
+
|
44
|
+
def name_for_explicit_dependency_source
|
45
|
+
'Partfile'
|
46
|
+
end
|
47
|
+
|
48
|
+
def name_for_locking_dependency_source
|
49
|
+
'Partfile.lock'
|
50
|
+
end
|
51
|
+
|
52
|
+
def dependencies_for(dependency)
|
53
|
+
dependency.dependencies
|
54
|
+
end
|
55
|
+
|
56
|
+
def sort_dependencies(dependencies, activated, conflicts)
|
57
|
+
dependencies.sort_by do |d|
|
58
|
+
[
|
59
|
+
activated.vertex_named(d.name).payload ? 0 : 1,
|
60
|
+
dependency_pre_release?(d) ? 0 : 1,
|
61
|
+
conflicts[d.name] ? 0 : 1,
|
62
|
+
activated.vertex_named(d.name).payload ? 0 : search_for(d).count,
|
63
|
+
]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def dependency_pre_release?(dependency)
|
70
|
+
dependency.requirement_list.requirements.any? do |r|
|
71
|
+
VersionKit::Version.new(r.reference_version).pre_release?
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Richcss
|
2
|
+
class TestSpecification
|
3
|
+
attr_accessor :name, :version, :dependencies
|
4
|
+
def initialize(hash)
|
5
|
+
self.name = hash['name']
|
6
|
+
self.version = VersionKit::Version.new(hash['version'])
|
7
|
+
self.dependencies = hash['dependencies'].map do |(name, requirement)|
|
8
|
+
VersionKit::Dependency.new(name, requirement.split(',').map(&:chomp))
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
name == other.name &&
|
14
|
+
version == other.version &&
|
15
|
+
dependencies == other.dependencies
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
"#{name} (#{version})"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'molinillo'
|
2
|
+
|
3
|
+
module Richcss
|
4
|
+
class RichUI
|
5
|
+
include Molinillo::UI
|
6
|
+
# Conveys debug information to the user.
|
7
|
+
#
|
8
|
+
# @param [Integer] depth the current depth of the resolution process.
|
9
|
+
# @return [void]
|
10
|
+
def debug(depth = 0)
|
11
|
+
if debug?
|
12
|
+
debug_info = yield
|
13
|
+
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
14
|
+
STDERR.puts debug_info.split("\n").map {|s| " " * depth + s }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def debug?
|
19
|
+
ENV["DEBUG_RESOLVER"] || ENV["DEBUG_RESOLVER_TREE"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def before_resolution
|
23
|
+
Bundler.ui.info "Resolving dependencies...", false
|
24
|
+
end
|
25
|
+
|
26
|
+
def after_resolution
|
27
|
+
Bundler.ui.info ""
|
28
|
+
end
|
29
|
+
|
30
|
+
def indicate_progress
|
31
|
+
Bundler.ui.info ".", false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/richcss.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'richcss/version'
|
2
|
+
|
3
|
+
module Richcss
|
4
|
+
autoload :Generators, 'richcss/generators'
|
5
|
+
autoload :Part, 'richcss/part'
|
6
|
+
autoload :Manager, 'richcss/manager'
|
7
|
+
autoload :Resolver, 'richcss/resolver'
|
8
|
+
autoload :RichSpecificationProvider, 'richcss/richcss_specification_provider'
|
9
|
+
autoload :RichUI, 'richcss/richcss_ui'
|
10
|
+
autoload :TestSpecification, 'richcss/richcss_test_specification'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# TODO
|
14
|
+
end
|
15
|
+
end
|
data/richcss.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'richcss/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "richcss"
|
8
|
+
spec.version = Richcss::VERSION
|
9
|
+
spec.authors = ["Nicholas Lo, Gabriel Cheng, Bill Xu, Jonathan Lai, David Zhu"]
|
10
|
+
spec.email = ["richcssa4@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{This is a command line package manager for the RichCSS framework}
|
13
|
+
spec.homepage = "https://github.com/fdp-A4/richcss-cli"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = "richcss"
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
|
26
|
+
spec.add_dependency "thor"
|
27
|
+
spec.add_dependency "molinillo"
|
28
|
+
spec.add_dependency "rest-client"
|
29
|
+
spec.add_dependency "zipruby"
|
30
|
+
spec.add_dependency "email_validator"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: richcss
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicholas Lo, Gabriel Cheng, Bill Xu, Jonathan Lai, David Zhu
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-03-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
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
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: molinillo
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rest-client
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: zipruby
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: email_validator
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description:
|
140
|
+
email:
|
141
|
+
- richcssa4@gmail.com
|
142
|
+
executables:
|
143
|
+
- richcss
|
144
|
+
extensions: []
|
145
|
+
extra_rdoc_files: []
|
146
|
+
files:
|
147
|
+
- ".gitignore"
|
148
|
+
- ".rspec"
|
149
|
+
- Gemfile
|
150
|
+
- LICENSE.txt
|
151
|
+
- README.md
|
152
|
+
- Rakefile
|
153
|
+
- bin/console
|
154
|
+
- bin/richcss
|
155
|
+
- bin/setup
|
156
|
+
- exe/richcss
|
157
|
+
- lib/richcss.rb
|
158
|
+
- lib/richcss/cli.rb
|
159
|
+
- lib/richcss/generator/routes.scss
|
160
|
+
- lib/richcss/generators.rb
|
161
|
+
- lib/richcss/manager.rb
|
162
|
+
- lib/richcss/part.rb
|
163
|
+
- lib/richcss/resolver.rb
|
164
|
+
- lib/richcss/richcss_specification_provider.rb
|
165
|
+
- lib/richcss/richcss_test_specification.rb
|
166
|
+
- lib/richcss/richcss_ui.rb
|
167
|
+
- lib/richcss/version.rb
|
168
|
+
- richcss.gemspec
|
169
|
+
homepage: https://github.com/fdp-A4/richcss-cli
|
170
|
+
licenses:
|
171
|
+
- MIT
|
172
|
+
metadata: {}
|
173
|
+
post_install_message:
|
174
|
+
rdoc_options: []
|
175
|
+
require_paths:
|
176
|
+
- lib
|
177
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
178
|
+
requirements:
|
179
|
+
- - ">="
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
requirements: []
|
188
|
+
rubyforge_project:
|
189
|
+
rubygems_version: 2.2.2
|
190
|
+
signing_key:
|
191
|
+
specification_version: 4
|
192
|
+
summary: This is a command line package manager for the RichCSS framework
|
193
|
+
test_files: []
|