Skip to content

Commit

Permalink
Implement dsu project create
Browse files Browse the repository at this point in the history
  • Loading branch information
gangelo committed Jan 19, 2024
1 parent 5bb0b39 commit 707e219
Show file tree
Hide file tree
Showing 19 changed files with 512 additions and 99 deletions.
2 changes: 1 addition & 1 deletion current_project.bak
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": 20230613121411,
"project": "default"
"project_name": "default"
}
91 changes: 71 additions & 20 deletions lib/dsu/models/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

require_relative '../crud/json_file'
require_relative '../migration/version'
require_relative '../models/entry_group'
require_relative '../models/configuration'
require_relative '../services/project/hydrator_service'
require_relative '../support/descriptable'
require_relative '../support/fileable'
require_relative '../support/project_file_system'
require_relative '../validators/description_validator'
Expand All @@ -17,8 +18,9 @@ module Models
# This class represents a project. A project is a collection of entry groups.
class Project
include ActiveModel::Model
include Support::ProjectFileSystem
include Support::Descriptable
include Support::Fileable
include Support::ProjectFileSystem

VERSION = Migration::VERSION
MIN_PROJECT_NAME_LENGTH = 2
Expand Down Expand Up @@ -65,6 +67,20 @@ def create!
end
alias save! create!

def current_project?
project_name == self.class.current_project_name
end

def default!
return if default_project?

self.class.default!(project: self)
end

def default_project?
project_name == self.class.default_project_name
end

# def delete
# self.class.delete(project_name: project_name)
# end
Expand Down Expand Up @@ -110,9 +126,21 @@ def update!
self.class.update!(project_name: project_name, description: description, version: version, options: options)
end

def use!
return if current_project?

self.class.use!(project: self)
end

class << self
delegate :project_folder_for, to: Support::Fileable

def all
project_metadata.map do |metadata|
find(project_name: metadata[:project_name])
end
end

def create(project_name:, description: nil, options: {})
Models::Project.new(project_name: project_name, description: description, options: options).tap do |project|
project.validate!
Expand All @@ -131,15 +159,22 @@ def create!(project_name:, description: nil, options: {})
end

def current_project
current_project_file = Support::Fileable.current_project_file
Crud::JsonFile.read!(file_path: current_project_file).fetch(:project).tap do |project_name|
# description = "#{project_name.capitalize} project}"
# unless project_exist?(project_name: project_name)
# create!(project_name: project_name, description: description)
# end
find(project_name: current_project_name)
end

def default!(project:)
project.validate!

Models::Configuration.new.tap do |configuration|
configuration.default_project = project.project_name
configuration.save!
end
end

def default_project
find(project_name: default_project_name)
end

# def all
# entry_groups.filter_map do |file_path|
# entry_group_file_name = File.basename(file_path)
Expand Down Expand Up @@ -169,17 +204,17 @@ def current_project
# # superclass.delete!(file_path: project_folder_for(project_name: project_name))
# end

def project_exist?(project_name:)
Dir.exist?(project_folder_for(project_name: project_name))
end
alias project_persisted? project_exist?
# def project_exist?(project_name:)
# Dir.exist?(project_folder_for(project_name: project_name))
# end
# alias project_persisted? project_exist?

def file_exist?(project_name:)
return false unless project_exist?(project_name: project_name)
# def file_exist?(project_name:)
# return false unless project_exist?(project_name: project_name)

File.exist?(current_project_file_path_for(current_project_file: project_folder_for(project_name: project_name)))
end
alias file_persisted? file_exist?
# File.exist?(current_project_file_path_for(current_project_file: project_folder_for(project_name: project_name)))
# end
# alias file_persisted? file_exist?

# def entry_groups(between:)
# entry_group_times(between: between).filter_map do |time|
Expand All @@ -188,20 +223,29 @@ def file_exist?(project_name:)
# end

def find(project_name:)
unless project_exist?(project_name: project_name)
unless project_folder_exist?(project_name: project_name)
raise I18n.t('models.project.errors.does_not_exist', project_name: project_name)
end

project_file_path = current_project_file_path_for(current_project_file: current_project_file)
project_file_path = project_file_for(project_name: project_name)

unless file_exist?(project_name: project_name)
unless project_file_exist?(project_name: project_name)
raise I18n.t('models.project.errors.project_file_not_exist', project_file: project_file_path)
end

project_hash = Crud::JsonFile.read!(file_path: project_file_path)
Services::Project::HydratorService.new(project_hash: project_hash).call
end

def find_by_number(project_number:)
project = project_metadata.find do |metadata|
metadata[:project_number] == project_number
end
return unless project

find(project_name: project[:project_name])
end

def find_or_create(project_name:)
find_or_initialize(project_name: project_name).tap do |project|
project.write! unless project.persisted?
Expand Down Expand Up @@ -258,6 +302,13 @@ def update(project_name:, description:, version:, options:)
def update!(project_name:, description:, version:, options:)
end

def use!(project:)
project.validate!

current_project_hash = { version: project.version, project_name: project.project_name }
Crud::JsonFile.write!(file_data: current_project_hash, file_path: current_project_file)
end

private

def current_project_file_path_for(current_project_file:)
Expand Down
2 changes: 1 addition & 1 deletion lib/dsu/presenters/project/create_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def initialize(project_name:, description:, options: {})
@project = Models::Project.new(project_name: project_name, description: description, options: options)
end

def render(response:)
def respond(response:)
return false unless response

project.create!
Expand Down
70 changes: 70 additions & 0 deletions lib/dsu/presenters/project/use_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# frozen_string_literal: true

require_relative '../../models/project'
require_relative '../base_presenter_ex'

module Dsu
module Presenters
module Project
class UsePresenter < BasePresenterEx
def initialize(project_name_or_number:, options: {})
super(options: options)

@project_name_or_number = project_name_or_number
end

def respond(response:)
return false unless response

project.use!
end

def project
@project ||= if project_name?
Dsu::Models::Project.find(project_name: project_name)
elsif project_number?
Dsu::Models::Project.find_by_number(project_number: project_number)
elsif project_default?
Dsu::Models::Project.default_project
end
end

def project_does_not_exist?
!project.exist?
end

def project_errors?
project.invalid?
end

private

attr_reader :options, :project_name_or_number

def project_name?
!(project_number? || project_default?)
end

def project_number?
project_name_or_number =~ /\A\d+\z/
end

def project_default?
project_name_or_number.blank?
end

def project_name
return unless project_name?

project_name_or_number
end

def project_number
return -1 unless project_number?

project_name_or_number.to_i
end
end
end
end
end
19 changes: 11 additions & 8 deletions lib/dsu/subcommands/project.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# frozen_string_literal: true

require_relative '../presenters/project/create_presenter'
require_relative '../presenters/project/use_presenter'
require_relative '../views/project/create'
require_relative '../views/project/use'
require_relative '../views/shared/error'
require_relative 'base_subcommand'

Expand Down Expand Up @@ -29,7 +31,7 @@ def create
end

desc I18n.t('subcommands.project.delete.desc'), I18n.t('subcommands.project.delete.usage')
long_desc I18n.t('subcommands.liet.delete.long_desc')
long_desc I18n.t('subcommands.project.delete.long_desc')
option :project_name, type: :string, required: true, aliases: '-n', banner: 'PROJECT_NAME'
option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
def delete
Expand All @@ -38,15 +40,15 @@ def delete
end

desc I18n.t('subcommands.project.list.desc'), I18n.t('subcommands.project.list.usage')
long_desc I18n.t('subcommands.liet.list.long_desc')
long_desc I18n.t('subcommands.project.list.long_desc')
option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
def list
# Views::Import.new(presenter: all_presenter(import_file_path: options[:import_file],
# options: options)).render
end

desc I18n.t('subcommands.project.show.desc'), I18n.t('subcommands.project.show.usage')
long_desc I18n.t('subcommands.liet.show.long_desc')
long_desc I18n.t('subcommands.project.show.long_desc')
option :project_name, type: :string, required: true, aliases: '-n', banner: 'PROJECT_NAME'
option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
def show
Expand All @@ -55,12 +57,13 @@ def show
end

desc I18n.t('subcommands.project.use.desc'), I18n.t('subcommands.project.use.usage')
long_desc I18n.t('subcommands.liet.use.long_desc')
option :project_name, type: :string, required: true, aliases: '-n', banner: 'PROJECT_NAME'
long_desc I18n.t('subcommands.project.use.long_desc')
option :prompts, type: :hash, default: {}, hide: true, aliases: '-p'
def use
# Views::Import.new(presenter: all_presenter(import_file_path: options[:import_file],
# options: options)).render
def use(project_name_or_number = nil)
options = configuration.to_h.merge(self.options).with_indifferent_access
presenter = Presenters::Project::UsePresenter.new(project_name_or_number: project_name_or_number,
options: options)
Views::Project::Use.new(presenter: presenter, options: options).render
end
end
end
Expand Down
13 changes: 10 additions & 3 deletions lib/dsu/support/ask.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
# frozen_string_literal: true

require 'io/console'
require 'thor'

module Dsu
module Support
module Ask
def ask(prompt)
options = {}
Thor::LineEditor.readline(prompt, options)
def ask_while(prompt, options: {})
loop do
print prompt
char = $stdin.getch
puts char
return char if yield(char)

char
end
end

def yes?(prompt, options: {})
Expand Down
2 changes: 1 addition & 1 deletion lib/dsu/support/color_themable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module ColorThemable
def prompt_with_options(prompt:, options:)
# HACK: This module needs to be refactored to be more generic.
target_color_theme = defined?(color_theme) ? color_theme : self
options = "[#{options.join('/')}]"
options = "[#{options.join(',')}]"
"#{apply_theme(prompt, theme_color: target_color_theme.prompt)} " \
"#{apply_theme(options, theme_color: target_color_theme.prompt_options)}" \
"#{apply_theme('>', theme_color: target_color_theme.prompt)}"
Expand Down
2 changes: 1 addition & 1 deletion lib/dsu/support/command_hookable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def display_dsu_footer
private

def project
Models::Project.current_project
Models::Project.current_project_name
end

def suspend_header?(args, _options)
Expand Down
3 changes: 2 additions & 1 deletion lib/dsu/support/fileable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ def config_path
# Entries

def entries_folder
File.join(projects_folder, 'entries')
project_folder = project_folder_for(project_name: Models::Project.current_project_name)
File.join(project_folder, 'entries')
end

def entries_file_name(time:, file_name_format: nil)
Expand Down
Loading

0 comments on commit 707e219

Please sign in to comment.