k_type 0.0.2 → 0.0.3
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 +4 -4
- data/README.md +65 -12
- data/STORIES.md +45 -0
- data/USAGE.md +72 -0
- data/lib/k_type.rb +2 -0
- data/lib/k_type/layered_folders.rb +104 -0
- data/lib/k_type/named_folders.rb +116 -0
- data/lib/k_type/version.rb +1 -1
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d66f0d61fe53fe8c595df611b7581323c24ed589ad520cfd3cbbe77aa91c4d39
|
4
|
+
data.tar.gz: 8ca31c3c74b48018bb824d20599a05a93b265c74e6e21edee483e51d3ac8fb9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de645c9b8d6298e938b0e5c4d5534f02fd5a9bcc62fa4da2f360769aa8436ba8ebd9c47a0195ff72908de96f68b309e1bdc6e9704fe41f3c4c1a0c1567663d01
|
7
|
+
data.tar.gz: e7b85f1b1c32117e0ef0d23973663b417792aac8f11e13916fe9b998bef8387b51c86b1202335c9697f9d3bbeb29034b2e47ba95622aa3a8b922688f9951e231
|
data/README.md
CHANGED
@@ -26,36 +26,89 @@ gem install k_type
|
|
26
26
|
|
27
27
|
### Main Story
|
28
28
|
|
29
|
-
|
29
|
+
As a Platform, I need DRY/SRP types, so that the system maintains loose coupling
|
30
30
|
|
31
31
|
See all [stories](./STORIES.md)
|
32
32
|
|
33
|
-
|
34
33
|
## Usage
|
35
34
|
|
36
35
|
See all [usage examples](./USAGE.md)
|
37
36
|
|
37
|
+
### Basic Example
|
38
38
|
|
39
|
+
#### Layered Folder
|
39
40
|
|
40
|
-
|
41
|
+
Layered folders allow files to be found in any of the searchable folders, it uses a `LIFO` stack ("Last-In, First-Out")
|
41
42
|
|
42
|
-
|
43
|
+
```ruby
|
44
|
+
base_folder = '/dev'
|
45
|
+
|
46
|
+
app_template_folder = File.join(base_folder, 'app-template')
|
47
|
+
domain_template_folder = File.join(base_folder, 'domain-template')
|
48
|
+
global_template_folder = File.join(base_folder, 'global-template')
|
49
|
+
|
50
|
+
folders = KType::LayeredFolders.new
|
51
|
+
|
52
|
+
folders.add(:fallback, '~/x')
|
53
|
+
folders.add(:global, global_template_folder)
|
54
|
+
folders.add(:domain, domain_template_folder)
|
55
|
+
folders.add(:app, app_template_folder)
|
56
|
+
folders.add(:app_abc, :app, 'a', 'b', 'c')
|
57
|
+
|
58
|
+
# Find a file in one of the following folders, searches in the following order (LIFO)
|
59
|
+
#
|
60
|
+
# "/dev/app-template/a/b/c"
|
61
|
+
# "/dev/app-template"
|
62
|
+
# "/dev/domain-template"
|
63
|
+
# "/dev/global-template"
|
64
|
+
# "/Users/username/x"
|
65
|
+
folders.find_file('template1.txt')
|
66
|
+
|
67
|
+
# Get the folder that the file is found in
|
68
|
+
#
|
69
|
+
folders.find_file_folder('template1.txt') # > /dev/app-template
|
70
|
+
```
|
43
71
|
|
44
|
-
|
45
|
-
|
72
|
+
#### Named Folder
|
73
|
+
|
74
|
+
Named folders allow folders to be stored with easy to remember names and alias's
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
folders = KType::NamedFolders.new
|
78
|
+
|
79
|
+
folders.add(:app, '/dev/MyApp')
|
80
|
+
folders.add(:config, :app, 'config')
|
81
|
+
folders.add(:docs, '~/documentation')
|
82
|
+
|
83
|
+
# Creates named folders
|
84
|
+
#
|
85
|
+
# "/dev/MyApp"
|
86
|
+
# "/dev/MyApp/config"
|
87
|
+
# "/Users/username/documentation"
|
88
|
+
|
89
|
+
# Get filename
|
90
|
+
|
91
|
+
folders.get_filename(:app, 'Program.cs') # > '/dev/MyApp/Program.cs'
|
92
|
+
|
93
|
+
folders.get_filename(:config, 'webpack.json') # > '/dev/MyApp/config/webpack.json'
|
94
|
+
|
95
|
+
folders.get_filename(:app, 'Models', 'Person.cs') # > '/dev/MyApp/Models/Person.cs'
|
96
|
+
|
97
|
+
# Get folder
|
98
|
+
|
99
|
+
folders.get(:config) # > '/dev/MyApp/config'
|
46
100
|
```
|
47
101
|
|
48
|
-
|
102
|
+
## Development
|
49
103
|
|
50
|
-
|
104
|
+
Checkout the repo
|
51
105
|
|
52
106
|
```bash
|
53
|
-
|
54
|
-
|
55
|
-
Aaa::Bbb::Program.execute()
|
56
|
-
# => ""
|
107
|
+
git clone klueless-io/k_type
|
57
108
|
```
|
58
109
|
|
110
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
111
|
+
|
59
112
|
`k_type` is setup with Guard, run `guard`, this will watch development file changes and run tests automatically, if successful, it will then run rubocop for style quality.
|
60
113
|
|
61
114
|
To release a new version, update the version number in `version.rb`, build the gem and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
data/STORIES.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# K Type
|
2
|
+
|
3
|
+
> K Type provides base types for KlueLess code generation
|
4
|
+
|
5
|
+
As a Platform, I need DRY/SRP types, so that the system maintains loose coupling
|
6
|
+
|
7
|
+
## Development radar
|
8
|
+
|
9
|
+
### Stories next on list
|
10
|
+
|
11
|
+
As a Platform, I need DRY/SRP types, so that the system maintains loose coupling
|
12
|
+
|
13
|
+
- Add NamedFolders
|
14
|
+
- Add LayeredFolders
|
15
|
+
|
16
|
+
## Stories and tasks
|
17
|
+
|
18
|
+
### Tasks - completed
|
19
|
+
|
20
|
+
Setup RubyGems and RubyDoc
|
21
|
+
|
22
|
+
- Build and deploy gem to [rubygems.org](https://rubygems.org/gems/k_type)
|
23
|
+
- Attach documentation to [rubydoc.info](https://rubydoc.info/github/to-do-/k_type/master)
|
24
|
+
|
25
|
+
Setup project management, requirement and SCRUM documents
|
26
|
+
|
27
|
+
- Setup readme file
|
28
|
+
- Setup user stories and tasks
|
29
|
+
- Setup a project backlog
|
30
|
+
- Setup an examples/usage document
|
31
|
+
|
32
|
+
Setup GitHub Action (test and lint)
|
33
|
+
|
34
|
+
- Setup Rspec action
|
35
|
+
- Setup RuboCop action
|
36
|
+
|
37
|
+
Setup new Ruby GEM
|
38
|
+
|
39
|
+
- Build out a standard GEM structure
|
40
|
+
- Add automated semantic versioning
|
41
|
+
- Add Rspec unit testing framework
|
42
|
+
- Add RuboCop linting
|
43
|
+
- Add Guard for automatic watch and test
|
44
|
+
- Add GitFlow support
|
45
|
+
- Add GitHub Repository
|
data/USAGE.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# K Type
|
2
|
+
|
3
|
+
> K Type provides base types for KlueLess code generation
|
4
|
+
|
5
|
+
As a Platform, I need DRY/SRP types, so that the system maintains loose coupling
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
### Sample Classes
|
10
|
+
|
11
|
+
#### Layered Folder
|
12
|
+
|
13
|
+
Layered folders allow files to be found in any of the searchable folders, it uses a `LIFO` stack ("Last-In, First-Out")
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
base_folder = '/dev'
|
17
|
+
|
18
|
+
app_template_folder = File.join(base_folder, 'app-template')
|
19
|
+
domain_template_folder = File.join(base_folder, 'domain-template')
|
20
|
+
global_template_folder = File.join(base_folder, 'global-template')
|
21
|
+
|
22
|
+
folders = KType::LayeredFolders.new
|
23
|
+
|
24
|
+
folders.add(:fallback, '~/x')
|
25
|
+
folders.add(:global, global_template_folder)
|
26
|
+
folders.add(:domain, domain_template_folder)
|
27
|
+
folders.add(:app, app_template_folder)
|
28
|
+
folders.add(:app_abc, :app, 'a', 'b', 'c')
|
29
|
+
|
30
|
+
# Find a file in one of the following folders, searches in the following order (LIFO)
|
31
|
+
#
|
32
|
+
# "/dev/app-template/a/b/c"
|
33
|
+
# "/dev/app-template"
|
34
|
+
# "/dev/domain-template"
|
35
|
+
# "/dev/global-template"
|
36
|
+
# "/Users/username/x"
|
37
|
+
folders.find_file('template1.txt')
|
38
|
+
|
39
|
+
# Get the folder that the file is found in
|
40
|
+
#
|
41
|
+
folders.find_file_folder('template1.txt') # > /dev/app-template
|
42
|
+
```
|
43
|
+
|
44
|
+
#### Named Folder
|
45
|
+
|
46
|
+
Named folders allow folders to be stored with easy to remember names and alias's
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
folders = KType::NamedFolders.new
|
50
|
+
|
51
|
+
folders.add(:app, '/dev/MyApp')
|
52
|
+
folders.add(:config, :app, 'config')
|
53
|
+
folders.add(:docs, '~/documentation')
|
54
|
+
|
55
|
+
# Creates named folders
|
56
|
+
#
|
57
|
+
# "/dev/MyApp"
|
58
|
+
# "/dev/MyApp/config"
|
59
|
+
# "/Users/username/documentation"
|
60
|
+
|
61
|
+
# Get filename
|
62
|
+
|
63
|
+
folders.get_filename(:app, 'Program.cs') # > '/dev/MyApp/Program.cs'
|
64
|
+
|
65
|
+
folders.get_filename(:config, 'webpack.json') # > '/dev/MyApp/config/webpack.json'
|
66
|
+
|
67
|
+
folders.get_filename(:app, 'Models', 'Person.cs') # > '/dev/MyApp/Models/Person.cs'
|
68
|
+
|
69
|
+
# Get folder
|
70
|
+
|
71
|
+
folders.get(:config) # > '/dev/MyApp/config'
|
72
|
+
```
|
data/lib/k_type.rb
CHANGED
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KType
|
4
|
+
#
|
5
|
+
# Named folders makes sense for generated/output folders because you may want
|
6
|
+
# more than one type of location to generate output.
|
7
|
+
#
|
8
|
+
# Don't confuse multiple named output folders with sub-paths, when you want to
|
9
|
+
# build up a file name in a child folder, you can do that as part of building
|
10
|
+
# the filename.
|
11
|
+
#
|
12
|
+
# The idea behind named folders is for when you have two or more totally different
|
13
|
+
# outputs that (may live in the a similar location) or live in different locations.
|
14
|
+
|
15
|
+
# Layered folders allow files to be found in any of the searchable folders
|
16
|
+
#
|
17
|
+
# They derive from and thus work just like named folders in that they allow folders
|
18
|
+
# to be stored with easy to remember names/alias's.
|
19
|
+
#
|
20
|
+
# Where they differ is that they are retrieved in preferential search order that is
|
21
|
+
# by default (First In, Last Out) priority aka a Stack (Last In, First Out) or
|
22
|
+
# optionally over ridden via the search_order method
|
23
|
+
#
|
24
|
+
# Layered folders makes sense for use with template files and source data/model
|
25
|
+
# where you can have specific usage files available and if they are not found then
|
26
|
+
# you can use fall-back files in other folders.
|
27
|
+
#
|
28
|
+
# example:
|
29
|
+
# folders = LayeredFolders.new
|
30
|
+
# folders.add(:global , '~/global_templates')
|
31
|
+
# folders.add(:domain , '/my-project/domain_templates')
|
32
|
+
# folders.add(:app , '/my-project/my-app/.templates')
|
33
|
+
#
|
34
|
+
# # Find a file and folder will in folders in this order
|
35
|
+
# # app_templates, then domain_templates and then finally global templates
|
36
|
+
# # ['/my-project/my-app/.templates', '/my-project/domain_templates', '~/global_templates']
|
37
|
+
# #
|
38
|
+
# # Find a file called template1.txt and return its fully-qualified path
|
39
|
+
# folders.find_file('template1.txt')
|
40
|
+
#
|
41
|
+
# # As above, but returns the folder only, file name and sub-paths are ignored
|
42
|
+
# folders.find_file_folder('template1.txt')
|
43
|
+
# folders.find_file_folder('abc/xyz/deep-template.txt')
|
44
|
+
#
|
45
|
+
# # If an additional folder is added, say in child configuration that is designed
|
46
|
+
# # to override some of the global templates, then you can run a search_order
|
47
|
+
# # method to re-order the templates
|
48
|
+
#
|
49
|
+
# folders.add(:global_shim , '~/global_templates_shim')
|
50
|
+
# folders.search_order(:app, :domain, :global_shim, :global)
|
51
|
+
#
|
52
|
+
# class Builder < KType::BaseBuilder
|
53
|
+
class LayeredFolders < KType::NamedFolders
|
54
|
+
attr_reader :ordered_keys
|
55
|
+
attr_reader :ordered_folders
|
56
|
+
|
57
|
+
def initialize
|
58
|
+
super()
|
59
|
+
|
60
|
+
@ordered_keys = []
|
61
|
+
@ordered_folders = []
|
62
|
+
end
|
63
|
+
|
64
|
+
def initialize_copy(orig)
|
65
|
+
super(orig)
|
66
|
+
|
67
|
+
@ordered_keys = orig.ordered_keys.clone
|
68
|
+
@ordered_folders = orig.ordered_folders.clone
|
69
|
+
end
|
70
|
+
|
71
|
+
def add(folder_key, *folder_parts)
|
72
|
+
folder = super(folder_key, *folder_parts)
|
73
|
+
|
74
|
+
ordered_keys.prepend(folder_key)
|
75
|
+
ordered_folders.prepend(folder)
|
76
|
+
|
77
|
+
folder
|
78
|
+
end
|
79
|
+
|
80
|
+
# File name or array of sub-paths plus file
|
81
|
+
#
|
82
|
+
# Return the folder that a file is found in
|
83
|
+
def find_file(file_parts)
|
84
|
+
folder = find_file_folder(file_parts)
|
85
|
+
folder.nil? ? nil : File.join(folder, file_parts)
|
86
|
+
end
|
87
|
+
|
88
|
+
# File name or array of sub-paths plus file
|
89
|
+
#
|
90
|
+
# Return the folder that a file is found in
|
91
|
+
def find_file_folder(file_parts)
|
92
|
+
ordered_folders.find { |folder| File.exist?(File.join(folder, file_parts)) }
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_h
|
96
|
+
{
|
97
|
+
ordered: {
|
98
|
+
keys: ordered_keys,
|
99
|
+
folders: ordered_folders
|
100
|
+
}
|
101
|
+
}.merge(@folders)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module KType
|
4
|
+
# Named folders allow folders to be stored with easy to remember names/alias's
|
5
|
+
# Secondarily, you can also build up file names based on these named folders.
|
6
|
+
#
|
7
|
+
# Named folders makes sense for generated/output folders because you may want
|
8
|
+
# more than one type of location to generate output.
|
9
|
+
#
|
10
|
+
# Don't confuse multiple named output folders with sub-paths, when you want to
|
11
|
+
# build up a file name in a child folder, you can do that as part of building
|
12
|
+
# the filename.
|
13
|
+
#
|
14
|
+
# The idea behind named folders is for when you have two or more totally different
|
15
|
+
# outputs that (may live in the a similar location) or live in different locations.
|
16
|
+
# Samples:
|
17
|
+
# name: :code - generating source code into a project
|
18
|
+
# name: :slide - generating slide deck into a documentation folder
|
19
|
+
# name: :webpack - folder where you might generate webpack files, e.g. webpack.config.*.json
|
20
|
+
#
|
21
|
+
# example:
|
22
|
+
# folders = NamedFolders.new
|
23
|
+
# folders.add(:csharp , '~/dev/csharp/cool-project')
|
24
|
+
# folders.add(:package_json , :csharp)
|
25
|
+
# folders.add(:webpack , folders.join(:csharp, 'config'))
|
26
|
+
# folders.add(:builder , folders.join(:csharp, 'builder'))
|
27
|
+
# folders.add(:slides , '~/doc/csharp/cool-project')
|
28
|
+
#
|
29
|
+
# puts folders.get(:builder)
|
30
|
+
#
|
31
|
+
# puts folders.get_filename(:csharp, 'Program.cs')
|
32
|
+
# puts folders.get_filename(:csharp, 'Models/Order.cs')
|
33
|
+
# puts folders.get_filename(:csharp, 'Models', 'Order.cs')
|
34
|
+
#
|
35
|
+
# Do I need to support :default?
|
36
|
+
class NamedFolders
|
37
|
+
attr_reader :folders
|
38
|
+
|
39
|
+
attr_reader :current
|
40
|
+
|
41
|
+
def initialize
|
42
|
+
@folders = {}
|
43
|
+
@current = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize_copy(orig)
|
47
|
+
super(orig)
|
48
|
+
|
49
|
+
@folders = orig.folders.clone
|
50
|
+
end
|
51
|
+
|
52
|
+
def current=(folder_key)
|
53
|
+
guard_folder_key(folder_key)
|
54
|
+
@current = folder_key
|
55
|
+
end
|
56
|
+
|
57
|
+
# Add support for file_parts
|
58
|
+
def add(folder_key, *folder_parts)
|
59
|
+
# get a predefined folder by symbol
|
60
|
+
folder = join_folder_parts(folder_parts)
|
61
|
+
if folder.is_a?(Symbol)
|
62
|
+
folder = get(folder)
|
63
|
+
elsif folder.start_with?('~')
|
64
|
+
folder = File.expand_path(folder)
|
65
|
+
end
|
66
|
+
|
67
|
+
@current = folder_key if @current.nil?
|
68
|
+
folders[folder_key] = folder
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get a folder
|
72
|
+
def get(folder_key)
|
73
|
+
guard_folder_key(folder_key)
|
74
|
+
folders[folder_key]
|
75
|
+
end
|
76
|
+
|
77
|
+
# Join the lookup folder key with the subpath folder parts (optionally + filename) and return the folder or filename
|
78
|
+
#
|
79
|
+
# Return fully qualified filename
|
80
|
+
def join(folder_key, *file_folder_parts)
|
81
|
+
folder = get(folder_key)
|
82
|
+
|
83
|
+
File.join(folder, file_folder_parts)
|
84
|
+
end
|
85
|
+
# Get a file name using the lookup folder key and the file name or array of sub-paths plus filename
|
86
|
+
alias get_filename join
|
87
|
+
|
88
|
+
def folder_keys
|
89
|
+
@folders.keys
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_h
|
93
|
+
@folders
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def join_folder_parts(folder_parts)
|
99
|
+
raise KType::Error, 'No folder part provided' if folder_parts.nil? || folder_parts.length.zero?
|
100
|
+
|
101
|
+
# If only one part, and that can be a folder or :folder_key, then just return it
|
102
|
+
return folder_parts.first if folder_parts.length == 1
|
103
|
+
|
104
|
+
folder_parts = folder_parts.map.with_index do |folder_part, index|
|
105
|
+
folder_part = get(folder_part) if index.zero? && folder_part.is_a?(Symbol)
|
106
|
+
folder_part
|
107
|
+
end
|
108
|
+
|
109
|
+
File.join(folder_parts)
|
110
|
+
end
|
111
|
+
|
112
|
+
def guard_folder_key(folder_key)
|
113
|
+
raise KType::Error, "Folder not found, this folder key not found: #{folder_key}" unless folders.key?(folder_key)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/lib/k_type/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: k_type
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Cruwys
|
@@ -27,6 +27,8 @@ files:
|
|
27
27
|
- LICENSE.txt
|
28
28
|
- README.md
|
29
29
|
- Rakefile
|
30
|
+
- STORIES.md
|
31
|
+
- USAGE.md
|
30
32
|
- bin/console
|
31
33
|
- bin/k
|
32
34
|
- bin/kgitsync
|
@@ -36,6 +38,8 @@ files:
|
|
36
38
|
- hooks/update-version
|
37
39
|
- k_type.gemspec
|
38
40
|
- lib/k_type.rb
|
41
|
+
- lib/k_type/layered_folders.rb
|
42
|
+
- lib/k_type/named_folders.rb
|
39
43
|
- lib/k_type/version.rb
|
40
44
|
homepage: http://appydave.com/gems/k-type
|
41
45
|
licenses:
|