devlogs 0.2.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ee70029616eb23078cfe60734052a855642617338f776543da002c18986cfad
4
- data.tar.gz: 8169a90b74e0524f6b9b0ebdb786ff0fb1df38e8d59c7d6bbdbbce7936d037d5
3
+ metadata.gz: 9df7671be5997a9e311b6a8c10863732b95fb3e6bdb89a7f5ba8476d3cec4653
4
+ data.tar.gz: af3731bb2c7134cea231b17a7c940d313d13f21c0721c720029e1084d706f0a4
5
5
  SHA512:
6
- metadata.gz: 3aba32f26e6905b876ad6e0777a86d29abfe1ea0642180fe1320ee82b20cc3a8efd2e22088d3b469149f920fa12808166ee7572b1f2207337afbf146bbac38cc
7
- data.tar.gz: 9fa406dae78b034c22c9db6f992e00a0255c920bb569f68fb4c5a20a295df8bcab8fad4f7f58f1d8a4f0870e05025f0d7b7c135bd50feea06e5b31ccf5b62fcf
6
+ metadata.gz: ffe4be66ace5c88074c0ce3e8a20e0f82a53162e59776be3bfdbf1d72c038d4d73365ca65bf91047b4730a64efeb548f3e1b7f8a8704a0f9554bc427ed0daa39
7
+ data.tar.gz: 9f3326e754283f25d307c598aa8824c53aa5686c112ebb9c9301ee7dc424710c572cac02275f72cf204e5e00677c92c03bd7e3f4ee157e7d585c9a3bcd2fc6c9
data/.gitignore CHANGED
@@ -10,4 +10,4 @@ __devlog
10
10
  *.gem
11
11
  __devlogs
12
12
  mirror
13
- _devlogs
13
+ .devlogs
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devlogs (0.2.0)
4
+ devlogs (1.0.0)
5
5
  rsync (~> 1.0, >= 1.0.9)
6
6
  thor (~> 1.2.1)
7
7
  tty-prompt (~> 0.23.1)
data/Makefile ADDED
@@ -0,0 +1,16 @@
1
+ PROJECT=devlogs
2
+
3
+ console:
4
+ @bundle exec bin/console
5
+
6
+ setup:
7
+ @bundle exec bin/setup
8
+
9
+ install:
10
+ @bundle exec rake install
11
+
12
+ release:
13
+ @bundle exec rake release
14
+
15
+ release.gh:
16
+ @gh release create
data/README.md CHANGED
@@ -23,12 +23,12 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
  ### Initialize
26
- Inside your project initialize the `_devlogs` repository:
26
+ Inside your project initialize the `.devlogs` repository:
27
27
  ```bash
28
28
  $ devlogs init
29
29
  ```
30
30
 
31
- Follow the prompts to setup the project configuration located in `_devlogs/.devlogs.config`.
31
+ Follow the prompts to setup the project configuration located in the _default_ `.devlogs/.devlogs.config`. (You can optionally set where you want to initialize the repository via --dirpath)
32
32
 
33
33
  You can setup a mirror directory path in the configuration stage to sync changes to another directory on your machine, for example to Obsidian.md.
34
34
 
@@ -36,7 +36,7 @@ Example:
36
36
 
37
37
  ```
38
38
  myproject
39
- _devlogs
39
+ .devlogs
40
40
  >> content
41
41
  ```
42
42
 
@@ -48,10 +48,10 @@ obsidianvault
48
48
  ```
49
49
 
50
50
  ### Creating entries
51
- Once you are done for the day or session run the `entry` command:
51
+ Once you are done for the day or session run the `new` command:
52
52
 
53
53
  ```bash
54
- devlogs entry
54
+ devlogs new
55
55
  ```
56
56
 
57
57
  Your editor will pop up and you can fill in cliff notes.
@@ -73,8 +73,6 @@ You can use the `last` command to retrieve the most recent entry
73
73
  devlogs last
74
74
  ```
75
75
 
76
- The `--open` command will cause the entry to be opened in a new default editor.
77
-
78
76
  ## Development
79
77
 
80
78
  After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/devlogs/cli.rb CHANGED
@@ -3,6 +3,9 @@
3
3
  require_relative "version"
4
4
  require_relative "repository"
5
5
  require_relative "editor"
6
+ require_relative "pager"
7
+ require_relative "prompt_utils"
8
+ require_relative "repository/initializer"
6
9
  require "thor"
7
10
 
8
11
  module Devlogs
@@ -10,6 +13,8 @@ module Devlogs
10
13
  # The CLI devlogs CLI
11
14
  #
12
15
  class CLI < Thor
16
+ include PromptUtils
17
+
13
18
  package_name "devlogs"
14
19
 
15
20
  # Returns exit with non zero status when an exception occurs
@@ -29,16 +34,19 @@ module Devlogs
29
34
  # Initializes a +devlogs+ repository with a configuration
30
35
  #
31
36
  desc "init", "Initialize a developer logs for project"
32
- method_options force: :boolean, alias: :string
37
+ method_options force: :boolean
38
+ method_options dirpath: :string
33
39
  def init
34
40
  puts "Creating devlogs repository"
35
41
 
36
- Repository::Initialize.run(
37
- { force: options.force? },
38
- File.join(".", "_devlogs")
42
+ Repository::Initializer.run(
43
+ {
44
+ force: options.force?,
45
+ dirpath: options.dirpath,
46
+ },
39
47
  )
40
48
 
41
- puts "Created devlogs"
49
+ puts "Created devlogs repository"
42
50
  end
43
51
 
44
52
  #
@@ -60,19 +68,42 @@ module Devlogs
60
68
  # Creates a devlogs entry in the repository and syncs changes
61
69
  # to the mirrored directory if set
62
70
  #
63
- desc "entry", "Create a new devlogs entry" # [4]
64
- def entry
71
+ desc "new", "Create a new devlogs entry" # [4]
72
+ def new
65
73
  puts "Creating new entry..."
66
74
  repo.create
67
75
 
68
76
  repo.sync
69
77
  end
70
78
 
79
+ #
80
+ # Lists repository logs
81
+ #
82
+ desc "ls", "Lists the repository logs and allows you to select"
83
+ def ls
84
+ entries = repo.ls
85
+
86
+ if entries.size < 1
87
+ puts "No logs present in this repository"
88
+ exit 0
89
+ end
90
+
91
+ # Use the file names as visible keys for the prompt
92
+ entry_names = entries.map { |e| File.basename(e) }
93
+
94
+ # Build the TTY:Prompt
95
+ result = build_select_prompt(data: entry_names, text: "Select a log entry...")
96
+
97
+ # Open in paging program
98
+ Pager.open(entries[result])
99
+ end
100
+
71
101
  private
72
102
 
73
103
  # Helper method for repository loading
74
104
  #
75
105
  def repo
106
+ # FIXME: Need to add in path specification here
76
107
  @repo ||= Repository.load
77
108
  end
78
109
  end
@@ -1,7 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "./executable.rb"
4
+
3
5
  # Wrapper for terminal editor
4
- class Editor
6
+ class Editor < Executable
5
7
  def initialize
6
8
  @program = ENV["EDITOR"]
7
9
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Executable
4
+ def initialize
5
+ raise NotImplementedError, "Abstract class"
6
+ end
7
+
8
+ # Opens the file contained at the path
9
+ def open(path)
10
+ command = "#{@program} #{path}"
11
+
12
+ system command
13
+ end
14
+
15
+ class << self
16
+ # Opens the file at +path+ using system editor
17
+ def open(path)
18
+ session = new
19
+
20
+ session.open(path)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Devlogs
4
+ def self.lib_root
5
+ File.join(File.dirname(__dir__), "devlogs")
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "erb"
4
+
5
+ #
6
+ # LogTemplate is a class that represents the rendered log template
7
+ #
8
+ class LogTemplate
9
+ attr_reader :time
10
+
11
+ TIME_FORMAT_TEXT_ENTRY = "%m-%d-%Y %k:%M"
12
+
13
+ def initialize(template_file_path)
14
+ @time = Time.new.strftime(TIME_FORMAT_TEXT_ENTRY)
15
+ @template_file_path = template_file_path
16
+ end
17
+
18
+ #
19
+ # Runs the ERB rendering using the provided template file template_file_path
20
+ #
21
+ # @returns [String]
22
+ #
23
+ def render
24
+ erb = ERB.new(File.read(@template_file_path))
25
+ erb.result(get_binding)
26
+ end
27
+
28
+ # rubocop:disable
29
+ #
30
+ # For ERB
31
+ #
32
+ def get_binding
33
+ binding
34
+ end
35
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Wrapper for terminal reader
4
+ require_relative "./executable.rb"
5
+
6
+ # Wrapper for terminal pager
7
+ class Pager < Executable
8
+ def initialize
9
+ @program = ENV["PAGER"]
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tty-prompt"
4
+
5
+ #
6
+ # Utility module for tty-prompt library
7
+ #
8
+ module PromptUtils
9
+ #
10
+ # Builds a basic select prompt using the provided data
11
+ #
12
+ # @param data [Array<String>]
13
+ #
14
+ # @returns String
15
+ #
16
+ def build_select_prompt(data:, text:)
17
+ ttyprompt = TTY::Prompt.new
18
+
19
+ ttyprompt.select(text) do |menu|
20
+ data.each_with_index do |d, index|
21
+ menu.choice d, index
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The repository's configuration values located in the yml file
4
+ class Repository
5
+ class Config
6
+ # FIXME: Need to figure out file path
7
+ attr_reader :name, :description, :mirror, :file_path, :template_file_path
8
+
9
+ # Configuration associated with the Mirror
10
+ MirrorConfig = Struct.new(:use_mirror, :path, keyword_init: true)
11
+
12
+ def initialize(path, opts = {})
13
+ @file_path = path
14
+ @template_file_path = opts[:template_file_path]
15
+ @name = opts[:name]
16
+ @description = opts[:description]
17
+ @mirror = MirrorConfig.new(opts[:mirror])
18
+ end
19
+
20
+ # Returns whether or not the devlogs repository is configured to mirror
21
+ #
22
+ # @returns [Boolean]
23
+ def mirror?
24
+ @mirror.use_mirror
25
+ end
26
+
27
+ # Ensures no weird double trailing slash path values
28
+ def path(with_trailing: false)
29
+ if with_trailing
30
+ @file_path[-1] == "/" ? @path_value : @path_value + "/"
31
+ else
32
+ @file_path
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "rsync"
5
+
6
+ require_relative "config"
7
+
8
+ # A per repository configuration storage directory
9
+ class Repository
10
+ class ConfigStore
11
+ attr_reader :dir, :values
12
+
13
+ CONFIG_FILE = ".devlogs.config.yml"
14
+
15
+ # TODO: should be part of configuration
16
+ TEMPLATE_FILE = ".log_template.erb.md"
17
+ DEFAULT_DIRECTORY_PATH = "."
18
+ DEFAULT_DIRECTORY_NAME = ".devlogs"
19
+
20
+ def initialize(dir: File.join(DEFAULT_DIRECTORY_PATH, DEFAULT_DIRECTORY_NAME))
21
+ @dir = dir
22
+ end
23
+
24
+ def values
25
+ @values ||= load_values_from_config_file
26
+ end
27
+
28
+ def file_path
29
+ File.join(@dir, CONFIG_FILE)
30
+ end
31
+
32
+ def template_file_path
33
+ File.join(@dir, TEMPLATE_FILE)
34
+ end
35
+
36
+ class << self
37
+ def load_from(path = File.join(DEFAULT_DIRECTORY_PATH, DEFAULT_DIRECTORY_NAME))
38
+ exists = File.exist?(path)
39
+
40
+ raise "no repository found #{path}" unless exists
41
+
42
+ new(dir: path)
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def load_values_from_config_file
49
+ yml = YAML.load_file(File.join(file_path))
50
+
51
+ Repository::Config.new(file_path, yml)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "config_store"
4
+
5
+ # Initialize is an execution object which initializes a Repository on the
6
+ # filesystem
7
+ class Repository
8
+ class Initializer
9
+ INFO_FILE_SUFFIX = "devlogs.info.md"
10
+ LOG_TEMPLATE_FILE_NAME = "__log_template.erb.md"
11
+
12
+ # Creates a new devlogs repository at the provided path
13
+ def self.run(opts = {})
14
+ new_config = if opts[:dirpath]
15
+ Repository::ConfigStore.new(dir: opts[:dirpath])
16
+ else
17
+ Repository::ConfigStore.new
18
+ end
19
+
20
+ exists = File.exist?(new_config.file_path)
21
+
22
+ if exists && !opts[:force]
23
+ puts "Log repository already exists in #{new_config.file_path}. Aborting..."
24
+ raise RuntimeError
25
+ end
26
+
27
+ results = prompt_for_info
28
+
29
+ # Create the new_config directory
30
+ FileUtils.mkdir_p(new_config.dir)
31
+
32
+ # Create new_config file
33
+ File.open(new_config.file_path, "w") do |f|
34
+ f.write results.to_yaml
35
+ end
36
+
37
+ # Replace spaces in project name with underscores
38
+ sanitized_project_name = results[:name].gsub(/ /, "_").downcase
39
+
40
+ # Create the info file
41
+ info_file_name = "#{sanitized_project_name}.devlogs.info.md"
42
+ info_file = File.join(new_config.dir, info_file_name)
43
+
44
+ File.open(info_file, "w") do |f|
45
+ f.puts "# #{results[:name]}"
46
+ f.puts (results[:desc]).to_s
47
+ end
48
+
49
+ # Copy the default template file inside the gem into the repository
50
+ default_template_path = get_template_path
51
+
52
+ new_config_template_file_path = File.join(new_config.dir, Repository::ConfigStore::TEMPLATE_FILE)
53
+
54
+ FileUtils.cp(default_template_path, new_config_template_file_path)
55
+ end
56
+
57
+ # Creates an interactive prompt for user input
58
+ #
59
+ # @returns [Hash]
60
+ def self.prompt_for_info
61
+ prompt = TTY::Prompt.new
62
+
63
+ prompt.collect do |_p|
64
+ # Project name
65
+ key(:name).ask("What is the project name?") do |q|
66
+ q.required true
67
+ end
68
+
69
+ # Project description
70
+ key(:desc).ask("What is the project description?") do |q|
71
+ q.required true
72
+ end
73
+
74
+ key(:mirror) do
75
+ key(:use_mirror).ask("Do you want to mirror these logs?", convert: :boolean)
76
+ key(:path).ask("Path to mirror directory: ")
77
+ end
78
+ end
79
+ end
80
+
81
+ # Gets the template file path embedded in the gem from the library root
82
+ def self.get_template_path
83
+ File.join(Devlogs.lib_root, "templates", LOG_TEMPLATE_FILE_NAME)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rsync"
4
+
5
+ # FIXME: Create module
6
+ class Repository
7
+ #
8
+ # SyncManager is an abstraction class for managing any necessity to sync
9
+ # files on the file system using Rsync.
10
+ #
11
+ class SyncManager
12
+ #
13
+ # @param config_store [Repository::ConfigStore]
14
+ #
15
+ def initialize(config_store)
16
+ @config_store = config_store
17
+ end
18
+
19
+ # Run rsync with -a to copy directories recursively
20
+
21
+ # Use trailing slash to avoid sub-directory
22
+ # See rsync manual page
23
+ #
24
+ # @throws Error if sync fails
25
+ def run
26
+ dest_path = @config_store.values.mirror.path
27
+ src_path = config_store_path_with_trailing
28
+
29
+ runner.run("-av", src_path, dest_path) do |result|
30
+ if result.success?
31
+ puts "Mirror sync complete."
32
+ result.changes.each do |change|
33
+ puts "#{change.filename} (#{change.summary})"
34
+ end
35
+ else
36
+ raise "Failed to sync: #{result.error}"
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ #
44
+ # Utility method for getting access to the runner program
45
+ # @returns [Rsync]
46
+ #
47
+ def runner
48
+ @runner ||= Rsync
49
+ end
50
+
51
+ # Depending on the runner (Rsync) program,
52
+ # you may need a trailing slash on the directory path
53
+ #
54
+ # @returns [String]
55
+ def config_store_path_with_trailing
56
+ @config_store.dir[-1] == "/" ? @config_store.dir : @config_store.dir + "/"
57
+ end
58
+ end
59
+ end
@@ -2,55 +2,50 @@
2
2
 
3
3
  require "fileutils"
4
4
  require "tty-prompt"
5
- require "yaml"
6
- require "rsync"
7
5
  require "pry"
8
6
  require "time"
7
+
8
+ require_relative "repository/config_store"
9
9
  require_relative "editor"
10
+ require_relative "repository/sync_manager"
11
+ require_relative "log_template"
10
12
 
11
13
  # Repostiroy is an accessor object for the devlogs directory
12
14
  class Repository
13
- CONFIG_FILE = ".devlogs.config.yml"
14
-
15
- # TODO: should be part of configuration
16
- DEFAULT_LOG_SUFFIX = "devlogs.md"
17
- DEFAULT_DIRECTORY_PATH = "."
18
- DEFAULT_DIRECTORY_NAME = "_devlogs"
19
-
20
15
  # Example: 11-22-2022_1343
21
- DEFAULT_TIME_FORMAT_FILE_PREFIX = "%m-%d-%Y__%kh%Mm"
22
- DEFAULT_TIME_FORMAT_TEXT_ENTRY = "%m-%d-%Y %k:%M"
16
+ TIME_FORMAT_FILE_PREFIX = "%m-%d-%Y__%kh%Mm"
17
+
18
+ LOG_FILE_SUFFIX = "log.md"
19
+ ISSUE_FILE_PREFIX = "iss"
23
20
 
24
21
  VALID_DIRECTION = %i[asc desc].freeze
25
22
 
26
- # Initializes a _devlogs repository with the supplied configuration
27
- # @param repo_config [Repository::Config]
23
+ # Initializes a .devlogs repository with the supplied configuration
28
24
  #
29
- def initialize(repo_config)
30
- @config = repo_config
25
+ def initialize(repo_config_store)
26
+ @config_store = repo_config_store
27
+ @repo_config = @config_store.values
31
28
  end
32
29
 
33
- # Creates a new _devlogs entry for recording session completion
30
+ # Creates a new .devlogs entry for recording session completion
34
31
  #
35
32
  # @returns nil
36
33
  def create
37
34
  time = Time.new
38
- prefix = time.strftime(DEFAULT_TIME_FORMAT_FILE_PREFIX)
35
+ time_prefix = time.strftime(TIME_FORMAT_FILE_PREFIX)
36
+
37
+ entry_file_name = "#{time_prefix}_#{LOG_FILE_SUFFIX}"
39
38
 
40
- entry_file_name = "#{prefix}_#{DEFAULT_LOG_SUFFIX}"
39
+ # FIXME: Need to figure out file path
40
+ entry_file_path = File.join(@config_store.dir, entry_file_name)
41
41
 
42
- entry_file_path = File.join(@config.path, entry_file_name)
42
+ # FIXME: Need to figure out file path
43
+ template = LogTemplate.new(@config_store.template_file_path)
43
44
 
44
45
  unless File.exist?(entry_file_path)
45
46
  # Add default boiler plate if the file does not exist yet
46
47
  File.open(entry_file_path, "w") do |f|
47
- f.write <<~ENDOFFILE
48
- # #{time.strftime(DEFAULT_TIME_FORMAT_TEXT_ENTRY)}
49
- Tags: #dev, #log
50
-
51
- What did you do today?
52
-
53
- ENDOFFILE
48
+ f.write template.render
54
49
  end
55
50
  end
56
51
 
@@ -64,30 +59,14 @@ class Repository
64
59
  #
65
60
  # @returns nil
66
61
  def sync
67
- if @config.mirror?
68
- # Run rsync with -a to copy directories recursively
69
-
70
- # Use trailing slash to avoid sub-directory
71
- # See rsync manual page
72
-
73
- Rsync.run("-av", @config.path(with_trailing: true), @config.mirror.path) do |result|
74
- if result.success?
75
- puts "Mirror sync complete."
76
- result.changes.each do |change|
77
- puts "#{change.filename} (#{change.summary})"
78
- end
79
- else
80
- raise "Failed to sync: #{result.error}"
81
- end
82
- end
83
- end
62
+ sync_manager.run if @repo_config.mirror?
84
63
  end
85
64
 
86
65
  # Lists the files in the repository
87
66
  def ls(direction = :desc)
88
67
  raise ArgumentError, "Must be one of: " + VALID_DIRECTION unless VALID_DIRECTION.include?(direction.to_sym)
89
68
 
90
- Dir.glob(File.join(@config.path, "*_#{DEFAULT_LOG_SUFFIX}")).sort_by do |fpath|
69
+ Dir.glob(File.join(@config_store.dir, "*_#{LOG_FILE_SUFFIX}")).sort_by do |fpath|
91
70
  # The date is joined by two underscores to the suffix
92
71
  date, = File.basename(fpath).split("__")
93
72
 
@@ -107,129 +86,16 @@ class Repository
107
86
  #
108
87
  # @returns [Repository]
109
88
  #
110
- def load(path = File.join(DEFAULT_DIRECTORY_PATH, DEFAULT_DIRECTORY_NAME))
111
- exists = File.exist?(path)
112
-
113
- raise "no repository found #{path}" unless exists
114
-
115
- cfg = YAML.load_file(File.join(path, CONFIG_FILE))
116
-
117
- cfg[:path] = path
89
+ def load(path = File.join(Repository::ConfigStore::DEFAULT_DIRECTORY_PATH, Repository::ConfigStore::DEFAULT_DIRECTORY_NAME))
90
+ store = Repository::ConfigStore.load_from(path)
118
91
 
119
- repo_config = Config.hydrate(cfg)
120
-
121
- new(repo_config)
92
+ new(store)
122
93
  end
123
94
  end
124
95
 
125
- # Config is a configuration data object for storing Repository configuration
126
- # in memory for access.
127
- class Config
128
- attr_reader :name, :description, :mirror, :path_value
129
-
130
- # Configuration associated with the Mirror
131
- MirrorConfig = Struct.new(:use_mirror, :path, keyword_init: true)
132
-
133
- def initialize(name, desc, mirror, p)
134
- @name = name
135
- @description = desc
136
- @mirror = MirrorConfig.new(mirror)
137
- @path_value = p
138
- end
139
-
140
- # Returns whether or not the devlogs repository is configured to mirror
141
- #
142
- # @returns [Boolean]
143
- def mirror?
144
- @mirror.use_mirror
145
- end
146
-
147
- def path(with_trailing: false)
148
- if with_trailing
149
- @path_value[-1] == "/" ? @path_value : @path_value + "/"
150
- else
151
- @path_value
152
- end
153
- end
96
+ private
154
97
 
155
- # Utility method to build a configuration from a Hash
156
- #
157
- # @returns [Repository::Config]
158
- def self.hydrate(cfg)
159
- new(cfg[:name], cfg[:description], cfg[:mirror], cfg[:path])
160
- end
161
- end
162
-
163
- # Initialize is an execution object which initializes a Repository on the
164
- # filesystem
165
- class Initialize
166
- # Creates a new devlogs repository at the provided path
167
- def self.run(opts = {}, path = File.join(DEFAULT_DIRECTORY_PATH, DEFAULT_DIRECTORY_NAME))
168
- exists = File.exist?(path)
169
-
170
- if exists && !opts[:force]
171
- puts "Log repository already exists in #{path}. Aborting..."
172
- raise RuntimeError
173
- end
174
-
175
- results = prompt_for_info
176
-
177
- FileUtils.mkdir_p(path)
178
- config_file = File.join(path, CONFIG_FILE)
179
-
180
- # Replace spaces in project name with underscores
181
- sanitized_project_name = results[:name].gsub(/ /, "_").downcase
182
-
183
- info_file_name = "#{sanitized_project_name}_devlogs.info.md"
184
- info_file = File.join(path, info_file_name)
185
-
186
- # Create config file
187
- File.open(config_file, "w") do |f|
188
- f.write results.to_yaml
189
- end
190
-
191
- # Create the info file
192
- File.open(info_file, "w") do |f|
193
- f.puts "# #{results[:name]}"
194
- f.puts (results[:desc]).to_s
195
- end
196
-
197
- # Git ignore if specified
198
- if results[:gitignore]
199
- gitignore = File.join(path, ".gitignore")
200
-
201
- File.open(gitignore, "a") do |f|
202
- f.puts DEFAULT_DIRECTORY_NAME
203
- end
204
- end
205
- end
206
-
207
- # Creates an interactive prompt for user input
208
- #
209
- # @returns [Hash]
210
- def self.prompt_for_info
211
- prompt = TTY::Prompt.new
212
-
213
- prompt.collect do |_p|
214
- # Project name
215
- key(:name).ask("What is the project name?") do |q|
216
- q.required true
217
- end
218
-
219
- # Project description
220
- key(:desc).ask("What is the project description?") do |q|
221
- q.required true
222
- end
223
-
224
- key(:mirror) do
225
- key(:use_mirror).ask("Do you want to mirror these logs?", convert: :boolean)
226
- key(:path).ask("Path to mirror directory: ")
227
- end
228
-
229
- key(:gitignore).ask("Do you want to gitignore the devlogs repository?") do |q|
230
- q.required true
231
- end
232
- end
233
- end
98
+ def sync_manager
99
+ @sync_manager ||= Repository::SyncManager.new(@config_store)
234
100
  end
235
101
  end
@@ -0,0 +1,5 @@
1
+ # LOG: <%= @time %>
2
+ Tags: #dev, #log
3
+
4
+ What did you do today?
5
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Devlogs
4
- VERSION = "0.2.0"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/devlogs.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "devlogs/gem"
3
4
  require_relative "devlogs/cli"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devlogs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - aquaflamingo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-27 00:00:00.000000000 Z
11
+ date: 2022-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rsync
@@ -86,6 +86,7 @@ files:
86
86
  - Gemfile
87
87
  - Gemfile.lock
88
88
  - LICENSE.txt
89
+ - Makefile
89
90
  - README.md
90
91
  - Rakefile
91
92
  - bin/console
@@ -96,7 +97,17 @@ files:
96
97
  - lib/devlogs.rb
97
98
  - lib/devlogs/cli.rb
98
99
  - lib/devlogs/editor.rb
100
+ - lib/devlogs/executable.rb
101
+ - lib/devlogs/gem.rb
102
+ - lib/devlogs/log_template.rb
103
+ - lib/devlogs/pager.rb
104
+ - lib/devlogs/prompt_utils.rb
99
105
  - lib/devlogs/repository.rb
106
+ - lib/devlogs/repository/config.rb
107
+ - lib/devlogs/repository/config_store.rb
108
+ - lib/devlogs/repository/initializer.rb
109
+ - lib/devlogs/repository/sync_manager.rb
110
+ - lib/devlogs/templates/__log_template.erb.md
100
111
  - lib/devlogs/version.rb
101
112
  homepage: http://github.com/aquaflamingo/devlogs
102
113
  licenses: