ecic 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: a76ed0b791619e00df7b26769de0149cd2c50bf7
4
- data.tar.gz: 32bdd099afd3603acb07f92e3d65059693b4308c
2
+ SHA256:
3
+ metadata.gz: 2941906c52685bf8cdd8dd3c988cb33d954917ce1af810b636a6d05a4a7858c9
4
+ data.tar.gz: e09506b75b7baaeb904179df7fa2eeb529d71e6084c1d9e150145b40d8ec1f2c
5
5
  SHA512:
6
- metadata.gz: 00fb2b177b7d849519218ad947caad8885ee6024beed10ea01945bb9aeac43557c3faf3205a7f3012a873a6910ddf3cd7b59b24887e15f5d93d626d20f06a4c3
7
- data.tar.gz: 6b9e3d628bb5982c30cabc505be385a80a4bf2fd3ba0e47d4f597c170ce75fc098afe88f340d8378d514dc7e509e158835e63cb3811dfd0f671b065adf07903f
6
+ metadata.gz: a6cf0330473f92ece3ae09d5448255502e354fce068eba417c9eb8e0c1dc79a1c21791bca6e440cce409f5f58faf2ac9fe1558aa69ba30d4fa742ae4d493487e
7
+ data.tar.gz: 7403f3d664272bd3bf5a25a6bbba9c534f212a9425f360f5c3f7531d3787452b7c6c2391e45aff9a908ed417a6ff6492dbe8f3315d1cd75ed66e710a4bc8dfb5
@@ -0,0 +1,7 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
+
6
+ ## [0.1.0]
7
+ - Initial release.
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in ecic.gemspec
3
+ # Specify your gem dependencies in ecic.gemspec
4
4
  gemspec
5
5
 
6
- gem 'thor'
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
@@ -1,37 +1,64 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ecic (0.1.4)
4
+ ecic (0.1.0)
5
+ activesupport
6
+ colorize
7
+ rake
8
+ thor
5
9
 
6
10
  GEM
7
11
  remote: https://rubygems.org/
8
12
  specs:
13
+ activesupport (5.1.4)
14
+ concurrent-ruby (~> 1.0, >= 1.0.2)
15
+ i18n (~> 0.7)
16
+ minitest (~> 5.1)
17
+ tzinfo (~> 1.1)
18
+ byebug (10.0.0)
19
+ codeclimate-test-reporter (1.0.8)
20
+ simplecov (<= 0.13)
21
+ colorize (0.8.1)
22
+ concurrent-ruby (1.0.5)
9
23
  diff-lcs (1.3)
10
- rake (10.5.0)
11
- rspec (3.8.0)
12
- rspec-core (~> 3.8.0)
13
- rspec-expectations (~> 3.8.0)
14
- rspec-mocks (~> 3.8.0)
15
- rspec-core (3.8.0)
16
- rspec-support (~> 3.8.0)
17
- rspec-expectations (3.8.1)
24
+ docile (1.1.5)
25
+ i18n (0.9.4)
26
+ concurrent-ruby (~> 1.0)
27
+ json (2.1.0)
28
+ minitest (5.11.3)
29
+ rake (12.3.0)
30
+ rspec (3.7.0)
31
+ rspec-core (~> 3.7.0)
32
+ rspec-expectations (~> 3.7.0)
33
+ rspec-mocks (~> 3.7.0)
34
+ rspec-core (3.7.1)
35
+ rspec-support (~> 3.7.0)
36
+ rspec-expectations (3.7.0)
18
37
  diff-lcs (>= 1.2.0, < 2.0)
19
- rspec-support (~> 3.8.0)
20
- rspec-mocks (3.8.0)
38
+ rspec-support (~> 3.7.0)
39
+ rspec-mocks (3.7.0)
21
40
  diff-lcs (>= 1.2.0, < 2.0)
22
- rspec-support (~> 3.8.0)
23
- rspec-support (3.8.0)
41
+ rspec-support (~> 3.7.0)
42
+ rspec-support (3.7.1)
43
+ simplecov (0.13.0)
44
+ docile (~> 1.1.0)
45
+ json (>= 1.8, < 3)
46
+ simplecov-html (~> 0.10.0)
47
+ simplecov-html (0.10.2)
24
48
  thor (0.20.0)
49
+ thread_safe (0.3.6)
50
+ tzinfo (1.2.5)
51
+ thread_safe (~> 0.1)
25
52
 
26
53
  PLATFORMS
27
54
  ruby
28
55
 
29
56
  DEPENDENCIES
30
- bundler (~> 1.13)
57
+ bundler
58
+ byebug
59
+ codeclimate-test-reporter
31
60
  ecic!
32
- rake (~> 10.0)
33
- rspec (~> 3.0)
34
- thor
61
+ rspec
35
62
 
36
63
  BUNDLED WITH
37
- 1.13.5
64
+ 1.16.1
@@ -0,0 +1,19 @@
1
+ guard "bundler", cmd: "bundle" do
2
+ watch("Gemfile")
3
+ watch(/^.+\.gemspec/)
4
+ end
5
+
6
+ guard :rspec, cmd: "bundle exec rspec" do
7
+ require "guard/rspec/dsl"
8
+ dsl = Guard::RSpec::Dsl.new(self)
9
+
10
+ # RSpec files
11
+ rspec = dsl.rspec
12
+ watch(rspec.spec_helper) { rspec.spec_dir }
13
+ watch(rspec.spec_support) { rspec.spec_dir }
14
+ watch(rspec.spec_files)
15
+
16
+ # Ruby files
17
+ ruby = dsl.ruby
18
+ dsl.watch_spec_files_for(ruby.lib_files)
19
+ end
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Easy IC : open-source, cross-platform framework for developing digital ASIC and FPGA designs
1
+ # Easy IC
2
2
 
3
3
  ## NOTE: this project has just been started. Hence, the description below is what will come in the future, but none of the features have been implemented yet.
4
4
 
@@ -183,4 +183,12 @@ To install the ECIC framework onto your local machine, run `bundle exec rake ins
183
183
  -->
184
184
  ## Contributing
185
185
 
186
+ 1. Fork it
187
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
188
+ 3. Commit your changes (`git commit -am "Add some feature"`)
189
+ 4. Push to the branch (`git push origin my-new-feature`)
190
+ 5. Create new Pull Request
191
+
186
192
  Bug reports and pull requests are welcome on GitHub at https://github.com/ic-factory/ecic.
193
+
194
+
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
4
  task :default => :spec
5
+
6
+ RSpec::Core::RakeTask.new
@@ -13,14 +13,18 @@ Gem::Specification.new do |spec|
13
13
  spec.description = %q{This gem allows you to easily create a new ASIC/FPGA project with a file structure and support tools that ensures consistency between your projects and gets you up to speed in no time. To create a new project simply type 'ecic new PATH'.}
14
14
  spec.homepage = "https://github.com/ic-factory/ecic"
15
15
 
16
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
- f.match(%r{^(test|spec|features)/})
18
- end
16
+ spec.files = `git ls-files`.split($/)
19
17
  spec.bindir = "exe"
20
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
20
  spec.require_paths = ["lib"]
22
21
 
23
- spec.add_development_dependency "bundler", "~> 1.13"
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_development_dependency "rspec", "~> 3.0"
22
+ spec.add_dependency "thor"
23
+ spec.add_dependency "colorize"
24
+ spec.add_dependency "rake"
25
+ spec.add_dependency "activesupport"
26
+
27
+ spec.add_development_dependency "bundler"
28
+ spec.add_development_dependency "byebug"
29
+ spec.add_development_dependency "rspec"
26
30
  end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Trap ^C
4
+ Signal.trap("INT") {
5
+ puts "\nCtrl-C detected. Exiting..."
6
+ sleep 1
7
+ exit
8
+ }
9
+
10
+ $:.unshift(File.expand_path("../../lib", __FILE__))
11
+ require "ecic"
12
+ require "ecic/cli"
13
+
14
+ Ecic::CLI.start(ARGV)
@@ -13,99 +13,14 @@
13
13
  # If the user tries to call the 'generate' command outside a project,
14
14
  # an error message must be returned stating that this command can only be called from within a project.
15
15
 
16
+ $:.unshift(File.expand_path("../", __FILE__))
16
17
  require "ecic/version"
17
18
 
18
19
  module Ecic
19
- require 'yaml'
20
- require 'thor'
21
- require 'thor/group'
22
- require "ecic/project_generator"
23
- require "ecic/library_generator"
24
-
25
- def self.help_text
26
- YAML.load(File.read(File.expand_path("../../config/locales/help.en.yaml", __FILE__)))['help']
27
- end
28
-
29
- #TBA: Make a function that returns the root folder for the project
30
- def self.root
31
- File.expand_path("./tfj2")
32
- end
33
-
34
- class Generate < Thor
35
- #--------------------------------------------------------------------------
36
- # TESTBENCH generator:
37
- #--------------------------------------------------------------------------
38
- class_option :verbose, :type => :boolean
39
-
40
- desc "testbench NAME", Ecic::help_text['generators']['testbench']['short']
41
- long_desc Ecic::help_text['generators']['testbench']['long']
42
- option :type, :banner => 'vhdl|sv|uvm', :required => true, :desc => 'Speficy the testbench type (VHDL, SystemVerilog or UVM)'
43
- option :just_print, :type => :boolean, :aliases => '-n', :desc => "Don't actually run any commands; just print them."
44
- def testbench(name)
45
- puts "Implement a generator for creating a new testbench"
46
- end
47
-
48
- desc "library NAME...", Ecic::help_text['generators']['library']['short']
49
- long_desc Ecic::help_text['generators']['library']['long']
50
- option :just_print, :type => :boolean, :aliases => '-n', :desc => "Don't actually run any commands; just print them."
51
- # def library(names)
52
- def library(lib_name)
53
- generator = LibraryGenerator.new
54
- generator.destination_root = Ecic::root
55
- # names.each do |lib_name|
56
- generator.library_name = lib_name
57
- generator.invoke_all
58
- # end
59
- end
60
-
61
- end
62
-
63
- class Cli < Thor
64
-
65
- check_unknown_options!
66
-
67
- #Make sure to return non-zero value if an error is thrown.
68
- def self.exit_on_failure?
69
- true
70
- end
71
-
72
- class << self
73
- def help(shell, subcommand = false)
74
- shell.say "Usage: ecic COMMAND [ARGS]"
75
- shell.say ""
76
- super
77
- shell.say "To get more help on a specific command, try 'ecic help [COMMAND]'"
78
- end
79
- end
80
-
81
- #--------------------------------------------------------------------------
82
- # VERSION command:
83
- #--------------------------------------------------------------------------
84
- desc 'version', 'Display version'
85
- map %w[-v --version] => :version
86
- def version
87
- say "#{VERSION}"
88
- end
89
-
90
- #--------------------------------------------------------------------------
91
- # NEW command:
92
- #--------------------------------------------------------------------------
93
- long_desc Ecic::help_text['new']['long']
94
- desc "new PATH", Ecic::help_text['new']['short']
95
- option :verbose, :type => :boolean
96
- def new(path)
97
- path = File.expand_path(path)
98
- puts "Generating a new project in #{path}"
99
- generator = ProjectGenerator.new
100
- generator.destination_root = path
101
- generator.invoke_all
102
- #TBA: invoke installation by eg. calling 'bundler install' from within the generate project folder
103
-
104
- end
105
-
106
- desc "generate SUBCOMMAND ...ARGS", Ecic::help_text['generate']['short']
107
- subcommand "generate", Generate
108
-
109
- end
110
-
20
+ autoload :Help, "ecic/help"
21
+ autoload :Command, "ecic/command"
22
+ autoload :CLI, "ecic/cli"
23
+ autoload :Generate, "ecic/generate"
24
+ autoload :Completion, "ecic/completion"
25
+ autoload :Completer, "ecic/completer"
111
26
  end
@@ -0,0 +1,69 @@
1
+ module Ecic
2
+ class CLI < Command
3
+
4
+ class << self
5
+ def help(shell, subcommand = false)
6
+ shell.say "Usage: ecic COMMAND [ARGS]"
7
+ shell.say ""
8
+ super
9
+ shell.say "To get more help on a specific command, try 'ecic help [COMMAND]'"
10
+ end
11
+ end
12
+
13
+ check_unknown_options!
14
+
15
+ #Make sure to return non-zero value if an error is thrown.
16
+ def self.exit_on_failure?
17
+ true
18
+ end
19
+
20
+ #TBA: Make a function that returns the root folder for the project
21
+ def self.root
22
+ File.expand_path("./tfj2")
23
+ end
24
+
25
+ # class_option :verbose, type: :boolean
26
+ # class_option :noop, type: :boolean
27
+
28
+ #--------------------------------------------------------------------------
29
+ # NEW command:
30
+ #--------------------------------------------------------------------------
31
+ long_desc Help.text(:new)
32
+ desc "new PATH", Help.short_text(:new)
33
+ option :verbose, :type => :boolean
34
+ def new(path)
35
+ path = File.expand_path(path)
36
+ puts "Generating a new project in #{path}"
37
+ generator = ProjectGenerator.new
38
+ generator.destination_root = path
39
+ generator.invoke_all
40
+ #TBA: invoke installation by eg. calling 'bundler install' from within the generate project folder
41
+ end
42
+
43
+ desc "generate SUBCOMMAND ...ARGS", "sub subcommands"
44
+ long_desc Help.text(:generate)
45
+ subcommand "generate", Generate
46
+
47
+ desc "completion *PARAMS", "Print words for auto-completion"
48
+ long_desc Help.text("completion")
49
+ def completion(*params)
50
+ Completer.new(CLI, *params).run
51
+ end
52
+
53
+ desc "completion_script", "Generate script that can be eval to setup auto-completion", hide: true
54
+ long_desc Help.text("completion_script")
55
+ def completion_script
56
+ Completer::Script.generate
57
+ end
58
+
59
+ desc 'version', 'Display version'
60
+ map %w[-v --version] => :version
61
+ def version
62
+ say "#{VERSION}"
63
+ end
64
+ end
65
+ end
66
+
67
+
68
+
69
+
@@ -0,0 +1,47 @@
1
+ require "thor"
2
+
3
+ # Override thor's long_desc identation behavior
4
+ # https://github.com/erikhuda/thor/issues/398
5
+ class Thor
6
+ module Shell
7
+ class Basic
8
+ def print_wrapped(message, options = {})
9
+ message = "\n#{message}" unless message[0] == "\n"
10
+ stdout.puts message
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ module Ecic
17
+ class Command < Thor
18
+ class << self
19
+ def dispatch(m, args, options, config)
20
+ # Allow calling for help via:
21
+ # ecic command help
22
+ # ecic command -h
23
+ # ecic command --help
24
+ # ecic command -D
25
+ #
26
+ # as well thor's normal way:
27
+ #
28
+ # ecic help command
29
+ help_flags = Thor::HELP_MAPPINGS + ["help"]
30
+ if args.length > 1 && !(args & help_flags).empty?
31
+ args -= help_flags
32
+ args.insert(-2, "help")
33
+ end
34
+
35
+ # ecic version
36
+ # ecic --version
37
+ # ecic -v
38
+ version_flags = ["--version", "-v"]
39
+ if args.length == 1 && !(args & version_flags).empty?
40
+ args = ["version"]
41
+ end
42
+
43
+ super
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,161 @@
1
+ =begin
2
+ Code Explanation:
3
+
4
+ There are 3 types of things to auto-complete:
5
+
6
+ 1. command: the command itself
7
+ 2. parameters: command parameters.
8
+ 3. options: command options
9
+
10
+ Here's an example:
11
+
12
+ mycli hello name --from me
13
+
14
+ * command: hello
15
+ * parameters: name
16
+ * option: --from
17
+
18
+ When command parameters are done processing, the remaining completion words will be options. We can tell that the command params are completed based on the method arity.
19
+
20
+ ## Arity
21
+
22
+ For example, say you had a method for a CLI command with the following form:
23
+
24
+ ufo scale service count --cluster development
25
+
26
+ It's equivalent ruby method:
27
+
28
+ scale(service, count) = has an arity of 2
29
+
30
+ So typing:
31
+
32
+ ufo scale service count [TAB] # there are 3 parameters including the "scale" command according to Thor's CLI processing.
33
+
34
+ So the completion should only show options, something like this:
35
+
36
+ --noop --verbose --cluster
37
+
38
+ ## Splat Arguments
39
+
40
+ When the ruby method has a splat argument, it's arity is negative. Here are some example methods and their arities.
41
+
42
+ ship(service) = 1
43
+ scale(service, count) = 2
44
+ ships(*services) = -1
45
+ foo(example, *rest) = -2
46
+
47
+ Fortunately, negative and positive arity values are processed the same way. So we take simply take the absolute value of the arity and process it the same.
48
+
49
+ Here are some test cases, hit TAB after typing the command:
50
+
51
+ ecic completion
52
+ ecic completion hello
53
+ ecic completion hello name
54
+ ecic completion hello name --
55
+ ecic completion hello name --noop
56
+
57
+ ecic completion
58
+ ecic completion sub:goodbye
59
+ ecic completion sub:goodbye name
60
+
61
+ ## Subcommands and Thor::Group Registered Commands
62
+
63
+ Sometimes the commands are not simple thor commands but are subcommands or Thor::Group commands. A good specific example is the ufo tool.
64
+
65
+ * regular command: ufo ship
66
+ * subcommand: ufo docker
67
+ * Thor::Group command: ufo init
68
+
69
+ Auto-completion accounts for each of these type of commands.
70
+ =end
71
+ module Ufo
72
+ class Completer
73
+ autoload :Script, 'ecic/completer/script'
74
+
75
+ def initialize(command_class, *params)
76
+ @params = params
77
+ @current_command = @params[0]
78
+ @command_class = command_class # CLI initiall
79
+ end
80
+
81
+ def run
82
+ if subcommand?(@current_command)
83
+ subcommand_class = @command_class.subcommand_classes[@current_command]
84
+ @params.shift # destructive
85
+ Completer.new(subcommand_class, *@params).run # recursively use subcommand
86
+ return
87
+ end
88
+
89
+ # full command has been found!
90
+ unless found?(@current_command)
91
+ puts all_commands
92
+ return
93
+ end
94
+
95
+ # will only get to here if command aws found (above)
96
+ arity = @command_class.instance_method(@current_command).arity.abs
97
+ if @params.size > arity or thor_group_command?
98
+ puts options_completion
99
+ else
100
+ puts params_completion
101
+ end
102
+ end
103
+
104
+ def subcommand?(command)
105
+ @command_class.subcommands.include?(command)
106
+ end
107
+
108
+ # hacky way to detect that command is a registered Thor::Group command
109
+ def thor_group_command?
110
+ command_params(raw=true) == [[:rest, :args]]
111
+ end
112
+
113
+ def found?(command)
114
+ public_methods = @command_class.public_instance_methods(false)
115
+ command && public_methods.include?(command.to_sym)
116
+ end
117
+
118
+ # all top-level commands
119
+ def all_commands
120
+ commands = @command_class.all_commands.reject do |k,v|
121
+ v.is_a?(Thor::HiddenCommand)
122
+ end
123
+ commands.keys
124
+ end
125
+
126
+ def command_params(raw=false)
127
+ params = @command_class.instance_method(@current_command).parameters
128
+ # Example:
129
+ # >> Sub.instance_method(:goodbye).parameters
130
+ # => [[:req, :name]]
131
+ # >>
132
+ raw ? params : params.map!(&:last)
133
+ end
134
+
135
+ def params_completion
136
+ offset = @params.size - 1
137
+ offset_params = command_params[offset..-1]
138
+ command_params[offset..-1].first
139
+ end
140
+
141
+ def options_completion
142
+ used = ARGV.select { |a| a.include?('--') } # so we can remove used options
143
+
144
+ method_options = @command_class.all_commands[@current_command].options.keys
145
+ class_options = @command_class.class_options.keys
146
+
147
+ all_options = method_options + class_options + ['help']
148
+
149
+ all_options.map! { |o| "--#{o.to_s.gsub('_','-')}" }
150
+ filtered_options = all_options - used
151
+ filtered_options.uniq
152
+ end
153
+
154
+ # Useful for debugging. Using puts messes up completion.
155
+ def log(msg)
156
+ File.open("/tmp/complete.log", "a") do |file|
157
+ file.puts(msg)
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,6 @@
1
+ class Ecic::Completer::Script
2
+ def self.generate
3
+ bash_script = File.expand_path("script.sh", File.dirname(__FILE__))
4
+ puts "source #{bash_script}"
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ _ecic() {
2
+ COMPREPLY=()
3
+ local word="${COMP_WORDS[COMP_CWORD]}"
4
+ local words=("${COMP_WORDS[@]}")
5
+ unset words[0]
6
+ local completion=$(ecic completion ${words[@]})
7
+ COMPREPLY=( $(compgen -W "$completion" -- "$word") )
8
+ }
9
+
10
+ complete -F _ecic ecic
@@ -0,0 +1,15 @@
1
+ module Ecic
2
+ class Completion < Command
3
+ desc "script", "generates script that can be eval to setup auto-completion"
4
+ long_desc Help.text("completion:script")
5
+ def script
6
+ Completer::Script.generate
7
+ end
8
+
9
+ desc "completions *PARAMS", "prints words for auto-completion"
10
+ long_desc Help.text("completion:list")
11
+ def list(*params)
12
+ Completer.new(*params).run
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,30 @@
1
+ module Ecic
2
+ class Generate < Command
3
+
4
+ #--------------------------------------------------------------------------
5
+ # TESTBENCH generator:
6
+ #--------------------------------------------------------------------------
7
+ class_option :verbose, :type => :boolean
8
+
9
+ desc "testbench NAME", Help.short_text("generate:testbench")
10
+ long_desc Help.text("generate:testbench")
11
+ option :type, :banner => 'vhdl|sv|uvm', :required => true, :desc => 'Speficy the testbench type (VHDL, SystemVerilog or UVM)'
12
+ option :just_print, :type => :boolean, :aliases => '-n', :desc => "Don't actually run any commands; just print them."
13
+ def testbench(name)
14
+ puts "Implement a generator for creating a new testbench"
15
+ end
16
+
17
+ desc "library NAME...", Help.short_text("generate:library")
18
+ long_desc Help.text("generate:library")
19
+ option :just_print, :type => :boolean, :aliases => '-n', :desc => "Don't actually run any commands; just print them."
20
+ # def library(names)
21
+ def library(lib_name)
22
+ generator = LibraryGenerator.new
23
+ generator.destination_root = Ecic::root
24
+ # names.each do |lib_name|
25
+ generator.library_name = lib_name
26
+ generator.invoke_all
27
+ # end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,14 @@
1
+ module Ecic::Help
2
+ class << self
3
+ def text(namespaced_command)
4
+ path = namespaced_command.to_s.gsub(':','/')
5
+ path = File.expand_path("../help/#{path}.md", __FILE__)
6
+ IO.read(path) if File.exist?(path)
7
+ end
8
+ def short_text(namespaced_command)
9
+ path = namespaced_command.to_s.gsub(':','/')
10
+ path = File.expand_path("../help/#{path}_short.md", __FILE__)
11
+ IO.read(path) if File.exist?(path)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ Example:
2
+
3
+ ecic completion
4
+
5
+ Prints words for TAB auto-completion.
6
+
7
+ Examples:
8
+
9
+ ecic completion
10
+ ecic completion hello
11
+ ecic completion hello name
12
+
13
+ To enable TAB auto-completion, add the following to your profile:
14
+
15
+ eval $(ecic completion script)
16
+
17
+ Auto-completion example usage:
18
+
19
+ ecic [TAB]
20
+ ecic generate [TAB]
21
+ ecic generate design [TAB]
22
+ ecic generate design --[TAB]
@@ -0,0 +1,3 @@
1
+ To use, add the following to your ~/.bashrc or ~/.profile
2
+
3
+ eval $(ecic completion script)
@@ -0,0 +1,4 @@
1
+ Examples:
2
+
3
+ ecic generate library
4
+ ecic generate library NAME
@@ -0,0 +1 @@
1
+ Generate new library
@@ -0,0 +1,4 @@
1
+ Examples:
2
+
3
+ ecic generate testbench
4
+ ecic generate testbench NAME
@@ -0,0 +1 @@
1
+ Generate new testbench
@@ -0,0 +1,3 @@
1
+ Examples:
2
+
3
+ ecic new my_project
@@ -0,0 +1 @@
1
+ Create new project
@@ -1,3 +1,3 @@
1
1
  module Ecic
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ describe Ecic::CLI do
4
+ before(:all) do
5
+ @args = "--from Tung"
6
+ end
7
+
8
+ describe "ecic" do
9
+ it "hello" do
10
+ out = execute("exe/ecic hello world #{@args}")
11
+ expect(out).to include("from: Tung\nHello world")
12
+ end
13
+
14
+ it "goodbye" do
15
+ out = execute("exe/ecic sub goodbye world #{@args}")
16
+ expect(out).to include("from: Tung\nGoodbye world")
17
+ end
18
+
19
+ commands = {
20
+ "hell" => "hello",
21
+ "hello" => "name",
22
+ "hello -" => "--from",
23
+ "hello name" => "--from",
24
+ "hello name --" => "--from",
25
+ "sub goodb" => "goodbye",
26
+ "sub goodbye" => "name",
27
+ "sub goodbye name" => "--from",
28
+ "sub goodbye name --" => "--from",
29
+ "sub goodbye name --from" => "--help",
30
+ }
31
+ commands.each do |command, expected_word|
32
+ it "completion #{command}" do
33
+ out = execute("exe/ecic completion #{command}")
34
+ expect(out).to include(expected_word) # only checking for one word for simplicity
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ ENV["TEST"] = "1"
2
+
3
+ # CodeClimate test coverage: https://docs.codeclimate.com/docs/configuring-test-coverage
4
+ # require 'simplecov'
5
+ # SimpleCov.start
6
+
7
+ require "pp"
8
+ require "byebug"
9
+ root = File.expand_path("../", File.dirname(__FILE__))
10
+ require "#{root}/lib/ecic"
11
+
12
+ module Helper
13
+ def execute(cmd)
14
+ puts "Running: #{cmd}" if show_command?
15
+ out = `#{cmd}`
16
+ puts out if show_command?
17
+ out
18
+ end
19
+
20
+ # Added SHOW_COMMAND because DEBUG is also used by other libraries like
21
+ # bundler and it shows its internal debugging logging also.
22
+ def show_command?
23
+ ENV['DEBUG'] || ENV['SHOW_COMMAND']
24
+ end
25
+ end
26
+
27
+ RSpec.configure do |c|
28
+ c.include Helper
29
+ end
metadata CHANGED
@@ -1,68 +1,128 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ecic
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Torben Fox Jacobsen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-02 00:00:00.000000000 Z
11
+ date: 2018-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
13
69
  - !ruby/object:Gem::Dependency
14
70
  name: bundler
15
71
  requirement: !ruby/object:Gem::Requirement
16
72
  requirements:
17
- - - "~>"
73
+ - - ">="
18
74
  - !ruby/object:Gem::Version
19
- version: '1.13'
75
+ version: '0'
20
76
  type: :development
21
77
  prerelease: false
22
78
  version_requirements: !ruby/object:Gem::Requirement
23
79
  requirements:
24
- - - "~>"
80
+ - - ">="
25
81
  - !ruby/object:Gem::Version
26
- version: '1.13'
82
+ version: '0'
27
83
  - !ruby/object:Gem::Dependency
28
- name: rake
84
+ name: byebug
29
85
  requirement: !ruby/object:Gem::Requirement
30
86
  requirements:
31
- - - "~>"
87
+ - - ">="
32
88
  - !ruby/object:Gem::Version
33
- version: '10.0'
89
+ version: '0'
34
90
  type: :development
35
91
  prerelease: false
36
92
  version_requirements: !ruby/object:Gem::Requirement
37
93
  requirements:
38
- - - "~>"
94
+ - - ">="
39
95
  - !ruby/object:Gem::Version
40
- version: '10.0'
96
+ version: '0'
41
97
  - !ruby/object:Gem::Dependency
42
98
  name: rspec
43
99
  requirement: !ruby/object:Gem::Requirement
44
100
  requirements:
45
- - - "~>"
101
+ - - ">="
46
102
  - !ruby/object:Gem::Version
47
- version: '3.0'
103
+ version: '0'
48
104
  type: :development
49
105
  prerelease: false
50
106
  version_requirements: !ruby/object:Gem::Requirement
51
107
  requirements:
52
- - - "~>"
108
+ - - ">="
53
109
  - !ruby/object:Gem::Version
54
- version: '3.0'
110
+ version: '0'
55
111
  description: This gem allows you to easily create a new ASIC/FPGA project with a file
56
112
  structure and support tools that ensures consistency between your projects and gets
57
113
  you up to speed in no time. To create a new project simply type 'ecic new PATH'.
58
114
  email:
59
115
  - ecic@ic-factory.com
60
- executables: []
116
+ executables:
117
+ - ecic
61
118
  extensions: []
62
119
  extra_rdoc_files: []
63
120
  files:
121
+ - CHANGELOG.md
64
122
  - Gemfile
65
123
  - Gemfile.lock
124
+ - Guardfile
125
+ - LICENSE.txt
66
126
  - README.md
67
127
  - Rakefile
68
128
  - bin/console
@@ -71,12 +131,31 @@ files:
71
131
  - config/ecic.yaml
72
132
  - config/locales/help.en.yaml
73
133
  - ecic.gemspec
134
+ - exe/ecic
74
135
  - features_wishlist.md
75
136
  - lib/ecic.rb
137
+ - lib/ecic/cli.rb
138
+ - lib/ecic/command.rb
139
+ - lib/ecic/completer.rb
140
+ - lib/ecic/completer/script.rb
141
+ - lib/ecic/completer/script.sh
142
+ - lib/ecic/completion.rb
143
+ - lib/ecic/generate.rb
144
+ - lib/ecic/help.rb
145
+ - lib/ecic/help/completion.md
146
+ - lib/ecic/help/completion_script.md
147
+ - lib/ecic/help/generate/library.md
148
+ - lib/ecic/help/generate/library_short.md
149
+ - lib/ecic/help/generate/testbench.md
150
+ - lib/ecic/help/generate/testbench_short.md
151
+ - lib/ecic/help/new.md
152
+ - lib/ecic/help/new_short.md
76
153
  - lib/ecic/library_generator.rb
77
154
  - lib/ecic/project_generator.rb
78
155
  - lib/ecic/version.rb
79
156
  - notes.txt
157
+ - spec/lib/cli_spec.rb
158
+ - spec/spec_helper.rb
80
159
  - templates/project/Gemfile
81
160
  - templates/project/config/libraries.rb
82
161
  - templates/project/config/project.rb
@@ -103,9 +182,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
182
  version: '0'
104
183
  requirements: []
105
184
  rubyforge_project:
106
- rubygems_version: 2.6.7
185
+ rubygems_version: 2.7.7
107
186
  signing_key:
108
187
  specification_version: 4
109
188
  summary: 'Easy-IC : provides a framework for ASIC and FPGA projects that favors convention
110
189
  over configuration.'
111
- test_files: []
190
+ test_files:
191
+ - spec/lib/cli_spec.rb
192
+ - spec/spec_helper.rb