notes_cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 73fe7f6770836515148031d07002166d3db2635f94508eb90f33757cceb8ecd6
4
+ data.tar.gz: 7eb9ee91974caa8b8f103da40c38b289f02b10d37a1a1244013790e0ce67294c
5
+ SHA512:
6
+ metadata.gz: 55c0ead38e7df4e746efe2cab82041ae226d4f444bd8ace2ec89d10ca861a1077a9057e245ffdb0146ec78277c7fef4b220de73c3a59a9f29f6a0b98b3ffe803
7
+ data.tar.gz: 531023291b416aa26e2c50e00c4fe37beba81cc99738ab33b5bf5b997ced661ab079777d0855b5952935e0474667472705b343dc46eb88d49c1d98a98ad0dac9
@@ -0,0 +1,3 @@
1
+ config.yml
2
+ coverage
3
+ lib/config.yml
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
@@ -0,0 +1,70 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ notes_cli (0.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.0)
10
+ byebug (11.1.3)
11
+ coderay (1.1.2)
12
+ diff-lcs (1.3)
13
+ docile (1.3.2)
14
+ fakefs (1.2.2)
15
+ method_source (1.0.0)
16
+ parallel (1.19.1)
17
+ parser (2.7.1.2)
18
+ ast (~> 2.4.0)
19
+ pry (0.13.1)
20
+ coderay (~> 1.1)
21
+ method_source (~> 1.0)
22
+ pry-byebug (3.9.0)
23
+ byebug (~> 11.0)
24
+ pry (~> 0.13.0)
25
+ rainbow (3.0.0)
26
+ rexml (3.2.4)
27
+ rspec (3.9.0)
28
+ rspec-core (~> 3.9.0)
29
+ rspec-expectations (~> 3.9.0)
30
+ rspec-mocks (~> 3.9.0)
31
+ rspec-core (3.9.2)
32
+ rspec-support (~> 3.9.3)
33
+ rspec-expectations (3.9.2)
34
+ diff-lcs (>= 1.2.0, < 2.0)
35
+ rspec-support (~> 3.9.0)
36
+ rspec-mocks (3.9.1)
37
+ diff-lcs (>= 1.2.0, < 2.0)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-support (3.9.3)
40
+ rubocop (0.84.0)
41
+ parallel (~> 1.10)
42
+ parser (>= 2.7.0.1)
43
+ rainbow (>= 2.2.2, < 4.0)
44
+ rexml
45
+ rubocop-ast (>= 0.0.3)
46
+ ruby-progressbar (~> 1.7)
47
+ unicode-display_width (>= 1.4.0, < 2.0)
48
+ rubocop-ast (0.0.3)
49
+ parser (>= 2.7.0.1)
50
+ ruby-progressbar (1.10.1)
51
+ simplecov (0.18.5)
52
+ docile (~> 1.1)
53
+ simplecov-html (~> 0.11)
54
+ simplecov-html (0.12.2)
55
+ unicode-display_width (1.7.0)
56
+
57
+ PLATFORMS
58
+ ruby
59
+
60
+ DEPENDENCIES
61
+ fakefs
62
+ notes_cli!
63
+ pry
64
+ pry-byebug
65
+ rspec
66
+ rubocop
67
+ simplecov
68
+
69
+ BUNDLED WITH
70
+ 1.17.2
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Joeffrey Lamy
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.
@@ -0,0 +1,103 @@
1
+ # Getting started
2
+
3
+ Tell notes_cli where your notes will be stored.
4
+ ```bash
5
+ notes --notes_folder path/to/where/you/will/store/notes
6
+ ```
7
+
8
+ Define your first workspace.
9
+ ```bash
10
+ notes -w workspace_name
11
+ ```
12
+
13
+ # DSL
14
+ ## Notes folder
15
+ Where you will store all notes, including your workspaces and notebooks as the top layers.
16
+
17
+ ## Workspace
18
+ Where you will store notebooks.
19
+
20
+ ## Notebook
21
+ Where you will store notes.
22
+
23
+ ## Example
24
+ Basic case scenario, where:
25
+ - `notes_folder` is where we decided to store notes
26
+ - `personal_projects` and `work` are workspaces
27
+ - `social_media_apps` and `features` are notebooks
28
+ - `twitter_clone.md` and `requirements.md` are notes
29
+
30
+ ```bash
31
+ notes_folder/
32
+ ├── personal_projects
33
+ │   └── social_media_apps
34
+ │   └── twitter_clone.md
35
+ └── work
36
+ └── features
37
+ └── voice_chat
38
+ └── requirements.md
39
+ ```
40
+
41
+ # Usage
42
+ ## Check
43
+ Checking which workspace you are currently in
44
+ ```bash
45
+ notes
46
+ 'Current workspace is ...'
47
+ ```
48
+
49
+ ## Create
50
+ ### Create a note in the current workspace
51
+ ```bash
52
+ notes -n notebook note_title
53
+ ```
54
+
55
+ ### Creating a note in a nested notebook
56
+ ```bash
57
+ notes -n path/to/notebook note_title
58
+ ```
59
+ ```bash
60
+ # e.g
61
+ notes -n saving_the_world/doing_charity_work list_of_charities
62
+
63
+ # will produce
64
+ notes_folder/
65
+ ├── personal_projects
66
+ │   ├── saving_the_world
67
+ │   │   └── doing_charity_work
68
+ │   │   └── list_of_charities.md
69
+ │   └── social_media_apps
70
+ │   └── twitter_clone.md
71
+ └── work
72
+ └── features
73
+ └── voice_chat
74
+ └── requirements.md
75
+ ```
76
+
77
+ ## Delete
78
+ Delete a note
79
+ ```bash
80
+ notes -d notebook note_title
81
+ ```
82
+
83
+ ## List
84
+ Listing all notebooks in your workspace
85
+ ```bash
86
+ notes -l .
87
+ ```
88
+
89
+ Listing all notes in a given notebook
90
+ ```bash
91
+ notes -l notebook
92
+ ```
93
+
94
+ ## Switch
95
+ Switching workspace
96
+ ```bash
97
+ notes -w workspace_name
98
+ ```
99
+
100
+ Switching workspace and creating a note there
101
+ ```bash
102
+ notes -w workspace_name -n notebook note_title
103
+ ```
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'notes_cli'
Binary file
Binary file
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NotesCli
4
+ ROOTH_PATH = __dir__
5
+ LIBRARY = File.join(ROOTH_PATH, 'notes_cli')
6
+ CONFIG_PATH = File.join(LIBRARY, 'config.yml')
7
+ end
8
+
9
+ require 'pry'
10
+ require 'pry-byebug'
11
+ require 'yaml'
12
+ require 'fileutils'
13
+ require 'optparse'
14
+ require File.join(NotesCli::LIBRARY, 'modules', 'modules')
15
+ require File.join(NotesCli::LIBRARY, 'models', 'workspace')
16
+ require File.join(NotesCli::LIBRARY, 'services', 'services')
17
+ require File.join(NotesCli::LIBRARY, 'controllers', 'option_parser')
18
+ require File.join(NotesCli::LIBRARY, 'version')
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ workspace = Workspace.new
4
+
5
+ if ARGV.empty?
6
+ ARGV << '--which_workspace'
7
+ ARGV << 'any_character'
8
+ end
9
+
10
+ OptionParser.new do |opt|
11
+ opt.on('-n --new_note TITLE PATH/TO/FILE') { |option| workspace.create_note(option, ARGV) }
12
+
13
+ opt.on('-d --delete_note TITLE PATH/TO/FILE ') { |option| workspace.delete_note(option, ARGV) }
14
+
15
+ opt.on('-l --list_notes TITLE PATH/TO/NOTEBOOK') do |option|
16
+ workspace.list_notes(option)
17
+ end
18
+
19
+ opt.on('-w --workspace WORKSPACE') do |option|
20
+ puts "Switched to #{option} wokspace" if workspace.switch(option)
21
+ end
22
+
23
+ opt.on('--notes_folder PATH/TO/FOLDER') do |option|
24
+ workspace.update_entry('notes_folder', option)
25
+ end
26
+
27
+ opt.on('--which_workspace ANY_CHARACTER') do |_option|
28
+ puts "Current workspace is #{workspace.current_workspace}"
29
+ end
30
+ end.parse!
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Workspace
4
+ include Modules::ResourceUtils
5
+
6
+ def initialize
7
+ FileUtils.touch(NotesCli::CONFIG_PATH) unless File.file?(NotesCli::CONFIG_PATH)
8
+ end
9
+
10
+ def create_note(notebook, title)
11
+ NoteCreator.new(notebook, title, notebook_path(notebook), workspace_path).call
12
+ end
13
+
14
+ def delete_note(notebook, title)
15
+ NoteDeleter.new(notebook, title, notebook_path(notebook), workspace_path).call
16
+ end
17
+
18
+ def list_notes(notebook)
19
+ NoteLister.new(notebook).call
20
+ end
21
+
22
+ def switch(workspace)
23
+ return unless workspace_exists?(workspace) || create?('workspace')
24
+
25
+ update_entry('workspace', workspace)
26
+ end
27
+
28
+ def update_entry(key, value)
29
+ current_config = config
30
+ current_config ? current_config[key] = value.strip.chomp : current_config = { key => value }
31
+ File.open(NotesCli::CONFIG_PATH, 'w') { |file| file.truncate(0) }
32
+ File.open(NotesCli::CONFIG_PATH, 'r+') do |f|
33
+ YAML.dump(current_config, f)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(NotesCli::LIBRARY, 'modules', 'resource_utils')
4
+
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Modules
4
+ module ResourceUtils
5
+ def config
6
+ YAML.safe_load(File.read(NotesCli::CONFIG_PATH))
7
+ end
8
+
9
+ def notebook_exists?(notebook)
10
+ Dir.exist?(File.join(notes_folder, current_workspace, notebook))
11
+ end
12
+
13
+ def workspace_exists?(workspace)
14
+ Dir.exist?(File.join(notes_folder, workspace))
15
+ end
16
+
17
+ def create?(resource)
18
+ puts "This #{resource} does not currently exist and will be created, "\
19
+ 'do you wish to continue? [y/N]'
20
+ STDIN.gets.chomp == 'y'
21
+ end
22
+
23
+ def current_workspace
24
+ return config['workspace'] if config && config['workspace']
25
+
26
+ raise StandardError, 'Please set your workspace'
27
+ end
28
+
29
+ def notes_folder
30
+ return config['notes_folder'] if config && config['notes_folder']
31
+
32
+ raise StandardError, 'Please set your notes_folder'
33
+ end
34
+
35
+ def notebook_path(notebook)
36
+ @notebook_path ||= File.join(notes_folder, current_workspace, notebook)
37
+ end
38
+
39
+ def workspace_path
40
+ File.join(notes_folder, current_workspace)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NoteCreator
4
+ include Modules::ResourceUtils
5
+
6
+ def initialize(notebook, title, notebook_path, workspace_path)
7
+ @notebook = notebook
8
+ @title = title.join('_')
9
+ @notebook_path = notebook_path
10
+ @workspace_path = workspace_path
11
+ end
12
+
13
+ def call
14
+ return unless notebook_exists?(@notebook) || create?('notebook')
15
+
16
+ handle_errors
17
+ create_note
18
+ notify
19
+ end
20
+
21
+ private
22
+
23
+ def handle_errors
24
+ raise ArgumentError, 'no notebook specified' if !@notebook || @notebook.empty?
25
+ raise ArgumentError, 'no note title specified' if !@title || @title.empty?
26
+ end
27
+
28
+ def create_note
29
+ FileUtils.mkdir_p(@notebook_path)
30
+ FileUtils.cd(@notebook_path)
31
+ FileUtils.touch("#{@title}.md")
32
+ FileUtils.cd(@workspace_path)
33
+ end
34
+
35
+ def notify
36
+ puts File.basename(@workspace_path)
37
+ puts '----------------'
38
+ puts "Added '#{@title}' to your #{@notebook} notebook"
39
+ puts File.join(@notebook_path, "#{@title}.md")
40
+ end
41
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NoteDeleter
4
+ include Modules::ResourceUtils
5
+
6
+ def initialize(notebook, title, notebook_path, workspace_path)
7
+ @notebook = notebook
8
+ @title = title.join('_')
9
+ @notebook_path = notebook_path
10
+ @workspace_path = workspace_path
11
+ end
12
+
13
+ def call
14
+ handle_errors
15
+ delete_note
16
+ notify
17
+ end
18
+
19
+ private
20
+
21
+ def handle_errors
22
+ raise ArgumentError, 'no notebook specified' if !@notebook || @notebook.empty?
23
+ raise ArgumentError, 'no note title specified' if !@title || @title.empty?
24
+ raise ArgumentError, 'notebook does not exist' unless notebook_exists?(@notebook)
25
+ end
26
+
27
+ def delete_note
28
+ FileUtils.cd(@notebook_path)
29
+ FileUtils.rm("#{@title}.md")
30
+ FileUtils.cd(@workspace_path)
31
+ end
32
+
33
+ def notify
34
+ puts current_workspace.to_s
35
+ puts '----------------'
36
+ puts "Deleted '#{@title}' from your #{@notebook} notebook"
37
+ end
38
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NoteLister
4
+ include Modules::ResourceUtils
5
+
6
+ def initialize(notebook)
7
+ @notebook = notebook
8
+ end
9
+
10
+ def call
11
+ handle_errors
12
+ return list if entries.any?
13
+
14
+ empty_notebook_notification
15
+ end
16
+
17
+ def handle_errors
18
+ raise StandardError, 'no such notebook' unless notebook_exists?(@notebook)
19
+ end
20
+
21
+ def list
22
+ max_spacing = entries.keys.max_by(&:length).size
23
+ entries.each do |k, v|
24
+ spacing = ' ' * (max_spacing - k.length)
25
+ puts "#{k} #{spacing} #{v}"
26
+ end
27
+ end
28
+
29
+ def entries
30
+ @entries ||= {}.tap do |entries|
31
+ Dir.glob(File.join(notes_folder, current_workspace, @notebook, '/*')).sort.each do |path|
32
+ entries[File.basename(path)] = path
33
+ end
34
+ end
35
+ end
36
+
37
+ def empty_notebook_notification
38
+ puts File.basename(current_workspace)
39
+ puts '----------------'
40
+ puts "#{@notebook} is empty"
41
+ end
42
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.join(NotesCli::LIBRARY, 'services', 'note_creator')
4
+ require File.join(NotesCli::LIBRARY, 'services', 'note_deleter')
5
+ require File.join(NotesCli::LIBRARY, 'services', 'note_lister')
@@ -0,0 +1,3 @@
1
+ module NotesCli
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,31 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'notes_cli/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'notes_cli'
7
+ s.version = NotesCli::VERSION
8
+ s.date = '2020-07-04'
9
+ s.summary = 'Easy note management from the command line'
10
+ s.description = %q{
11
+ Easily create, delete and list all your notes.
12
+ NotesCli lets you create workspaces and notebooks in which you can store notes.
13
+ Notes are created as md files for ease of storing code snippets.
14
+ }.strip.gsub(/\s+/, ' ')
15
+ s.authors = ['Joeffrey Lamy']
16
+ s.email = 'joeffreylamy41@gmail.com'
17
+ s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
18
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
20
+ s.executables << 'notes'
21
+ s.require_paths = ['lib']
22
+ s.homepage =
23
+ 'https://rubygems.org/gems/notes_cli'
24
+ s.license = 'MIT'
25
+ s.add_development_dependency 'fakefs', '~> 0.5'
26
+ s.add_development_dependency 'pry', '~> 0.12'
27
+ s.add_development_dependency 'pry-byebug', '~> 3.9'
28
+ s.add_development_dependency 'rspec', '~> 3.9'
29
+ s.add_development_dependency 'rubocop', '~> 0.86'
30
+ s.add_development_dependency 'simplecov', '~> 0.18'
31
+ end
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: notes_cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Joeffrey Lamy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-07-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fakefs
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.12'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '0.86'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.86'
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.18'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.18'
97
+ description: Easily create, delete and list all your notes. NotesCli lets you create
98
+ workspaces and notebooks in which you can store notes. Notes are created as md files
99
+ for ease of storing code snippets.
100
+ email: joeffreylamy41@gmail.com
101
+ executables:
102
+ - notes
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - ".rspec"
108
+ - Gemfile
109
+ - Gemfile.lock
110
+ - LICENSE.txt
111
+ - README.md
112
+ - bin/notes
113
+ - config.db
114
+ - config.yml.db
115
+ - lib/notes_cli.rb
116
+ - lib/notes_cli/controllers/option_parser.rb
117
+ - lib/notes_cli/models/workspace.rb
118
+ - lib/notes_cli/modules/modules.rb
119
+ - lib/notes_cli/modules/resource_utils.rb
120
+ - lib/notes_cli/services/note_creator.rb
121
+ - lib/notes_cli/services/note_deleter.rb
122
+ - lib/notes_cli/services/note_lister.rb
123
+ - lib/notes_cli/services/services.rb
124
+ - lib/notes_cli/version.rb
125
+ - notes_cli.gemspec
126
+ homepage: https://rubygems.org/gems/notes_cli
127
+ licenses:
128
+ - MIT
129
+ metadata: {}
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ requirements: []
145
+ rubygems_version: 3.1.4
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Easy note management from the command line
149
+ test_files: []