kommen-freckle-cmd 0.0.1

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.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-12-07
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008, 2009 Dieter Komendera
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,20 @@
1
+ History.txt
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ PostInstall.txt
5
+ README.rdoc
6
+ Rakefile
7
+ bin/freckle
8
+ freckle-cmd.gemspec
9
+ lib/freckle.rb
10
+ lib/freckle/app_config.rb
11
+ lib/freckle/cli.rb
12
+ lib/freckle/entry.rb
13
+ lib/freckle/project.rb
14
+ script/console
15
+ script/destroy
16
+ script/generate
17
+ test/entry_test.rb
18
+ test/project_test.rb
19
+ test/test_freckle_cli.rb
20
+ test/test_helper.rb
data/PostInstall.txt ADDED
@@ -0,0 +1,16 @@
1
+
2
+ To use the command line tool which comes with this gem, place a file .freckle.yml with following content into your home directory:
3
+
4
+ freckle:
5
+ subdomain: <your freckle subodmain>
6
+ authtoken: <your freckle api auth token>
7
+ user: <your freckle user name>
8
+
9
+ Then you can start tracking time from your command line:
10
+
11
+ freckle -t 2h -p ProjectX -d "Implementing a command line tool"
12
+
13
+ For more information you can run
14
+
15
+ freckle -h
16
+
data/README.rdoc ADDED
@@ -0,0 +1,34 @@
1
+ = freckle
2
+
3
+ http://letsfreckle.com
4
+
5
+ == DESCRIPTION:
6
+
7
+ Command line tool to track time with freckle (http://letsfreckle.com)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ == SYNOPSIS:
12
+
13
+ freckle -t 2h -p ProjectX -d "tag1, description for the entry"
14
+
15
+ == REQUIREMENTS:
16
+
17
+ * an active freckle account
18
+ * a valid .freckle.yml file in your home directory (see INSTALL section below)
19
+ * json and activeresource gems installed
20
+
21
+ == INSTALL:
22
+
23
+ sudo gem install kommen-freckle --source http://gems.github.com
24
+
25
+ Place a file .freckle.yml with following content into your home directory:
26
+
27
+ freckle:
28
+ subdomain: <your freckle subodmain>
29
+ authtoken: <your freckle api auth token>
30
+ user: <your freckle user name>
31
+
32
+ == LICENSE:
33
+
34
+ The freckle gem is licensed under the terms of the MIT License, see the included MIT-LICENSE file.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ %w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
2
+ require File.dirname(__FILE__) + '/lib/freckle'
3
+
4
+ # Generate all the Rake tasks
5
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
6
+ $hoe = Hoe.new('freckle-cmd', Freckle::VERSION) do |p|
7
+ p.developer('Dieter Komendera', 'dieter@abloom.at')
8
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
9
+ p.post_install_message = 'PostInstall.txt'
10
+ p.rubyforge_name = p.name
11
+
12
+ p.extra_deps = [
13
+ ['json', '>= 1.1.3'],
14
+ ['activeresource', '>= 2.2.2']
15
+ ]
16
+ p.extra_dev_deps = [
17
+ ['newgem', ">= #{::Newgem::VERSION}"],
18
+ ['activesupport', '>= 2.2.2']
19
+ ]
20
+
21
+ p.clean_globs |= %w[**/.DS_Store tmp *.log]
22
+ path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
23
+ p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
24
+ p.rsync_args = '-av --delete --ignore-errors'
25
+ end
26
+
27
+ require 'newgem/tasks' # load /tasks/*.rake
28
+ Dir['tasks/**/*.rake'].each { |t| load t }
29
+
data/bin/freckle ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Created by Dieter Komendera on 2008-12-7.
4
+ # Copyright (c) 2008, 2009. All rights reserved.
5
+
6
+ require File.expand_path(File.dirname(__FILE__) + "/../lib/freckle")
7
+
8
+ require "freckle/cli"
9
+
10
+ Freckle::CLI.execute(STDOUT, ARGV)
data/lib/freckle.rb ADDED
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Freckle
5
+ VERSION = '0.0.1'
6
+ end
@@ -0,0 +1,14 @@
1
+ module Freckle
2
+
3
+ class AppConfig
4
+ @@global_config = {
5
+ 'host' => 'letsfreckle.com',
6
+ 'port' => 80
7
+ }.merge(File.open(File.expand_path("~/.freckle.yml")) { |yf| YAML::load(yf)['freckle'] })
8
+
9
+ def self.method_missing(method_symbol, *arguments)
10
+ method_name = method_symbol.to_s
11
+ @@global_config.has_key?(method_name) ? @@global_config[method_name] : super
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,47 @@
1
+ require 'rubygems'
2
+ require 'optparse'
3
+ require 'yaml'
4
+ require 'json'
5
+ require 'activeresource'
6
+ require 'freckle/app_config'
7
+ require 'freckle/entry'
8
+ require 'freckle/project'
9
+
10
+ module Freckle
11
+ class CLI
12
+ def self.execute(stdout, arguments=[])
13
+
14
+ options = {}
15
+ entry_attributes = {}
16
+
17
+ parser = OptionParser.new do |opts|
18
+ opts.banner = <<-BANNER.gsub(/^ /,'')
19
+ This is a commandline interface for tracking time with freckle.
20
+
21
+ Usage: #{File.basename($0)} [options]
22
+
23
+ Options are:
24
+ BANNER
25
+ opts.separator ""
26
+
27
+ opts.on("-t", "--time=TIME", "required") { |arg| entry_attributes[:minutes] = arg }
28
+ opts.on("-p", "--project=PROJECT") { |arg| options[:project_name] = arg }
29
+ opts.on("-d", "--description=DESCRIPTION") { |arg| entry_attributes[:description] = arg }
30
+ opts.on("-D", "--date=DATE", "default: Today") { |arg| entry_attributes[:date] = arg }
31
+
32
+ opts.on("-h", "--help",
33
+ "Show this help message.") { stdout.puts opts; exit }
34
+ opts.parse!(arguments)
35
+ end
36
+
37
+ entry = Freckle::Entry.new(entry_attributes.merge(:user => Freckle::AppConfig.user))
38
+ entry.project_name = options[:project_name] if options[:project_name]
39
+ if entry.save
40
+ puts "time entry saved"
41
+ else
42
+ puts "failed to save entry."
43
+ entry.errors.full_messages.each { |msg| puts msg }
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+
2
+ module Freckle
3
+
4
+ class Entry < ActiveResource::Base
5
+ self.site = "http://#{Freckle::AppConfig.subdomain}.#{Freckle::AppConfig.host}:#{Freckle::AppConfig.port}/api/"
6
+
7
+ TIME_REGEXP = /^[0-9]{0,3}[:,.]?[0-9]{0,2}(m|min|mins|minute|minutes|h|hr|hrs|hour|hours|d|day|days)?$/
8
+
9
+ attr_accessor :project
10
+
11
+ def self.headers
12
+ @headers ||= { 'X_FRECKLETOKEN' => Freckle::AppConfig.authtoken }
13
+ end
14
+
15
+ def attributes
16
+ { :date => Date.today, :project_id => project ? project.id : nil }.merge(@attributes || {})
17
+ end
18
+
19
+ def project_name=(name)
20
+ self.project = Project.find_or_create_by_name(name)
21
+ end
22
+
23
+ def save
24
+ valid? ? super : false
25
+ end
26
+
27
+ def valid?
28
+ validate
29
+ super
30
+ end
31
+
32
+ protected
33
+
34
+ def validate
35
+ if minutes && !(minutes =~ TIME_REGEXP)
36
+ errors.add('minutes', 'has invalid format')
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module Freckle
3
+
4
+ class Project < ActiveResource::Base
5
+ self.site = "http://#{Freckle::AppConfig.subdomain}.#{Freckle::AppConfig.host}:#{Freckle::AppConfig.port}/api/"
6
+
7
+ def self.headers
8
+ @headers ||= { 'X_FRECKLETOKEN' => Freckle::AppConfig.authtoken }
9
+ end
10
+
11
+ def self.find_or_create_by_name(name)
12
+ raise "Invalid Argument: Name can't be blank." if name.nil? || name.empty?
13
+ find(:first, :params => { :name => name }) || create(:name => name)
14
+ end
15
+ end
16
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/freckle.rb'}"
9
+ puts "Loading freckle gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,57 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+
3
+ class Freckle::ProjectTest < Test::Unit::TestCase
4
+
5
+ class Freckle::Project
6
+ def self.headers
7
+ { 'X_FRECKLETOKEN' => '123' }
8
+ end
9
+ end
10
+
11
+ def setup
12
+ @entry = Freckle::Entry.new
13
+ @projects = [{ :id => 1, :name => "Test1" }].to_xml(:root => "projects")
14
+ ActiveResource::HttpMock.respond_to do |mock|
15
+ mock.get "/api/projects.xml?name=Test1", { 'X_FRECKLETOKEN' => '123' }, @projects
16
+ end
17
+ end
18
+
19
+ def test_should_have_today_as_default_date
20
+ assert_equal Date.today, @entry.attributes[:date]
21
+ end
22
+
23
+ def test_should_allow_default_date_to_be_overwritten
24
+ assert_equal '2009/11/10', Freckle::Entry.new({ :date => '2009/11/10' }).date
25
+ end
26
+
27
+ def test_attribute_project_id_when_entry_has_project
28
+ @entry.project = Freckle::Project.new(:id => 1, :name => 'Test1')
29
+ assert_equal 1, @entry.attributes[:project_id]
30
+ end
31
+
32
+ def test_attribute_project_id_when_entry_has_no_project
33
+ assert_nil @entry.attributes[:project_id]
34
+ end
35
+
36
+ def test_set_project_name_should_assing_project
37
+ @entry.project_name = 'Test1'
38
+ assert_equal 1, @entry.attributes[:project_id]
39
+ end
40
+
41
+ def test_minute_validation
42
+ ['2h', '100', '50min'].each do |min|
43
+ entry = Freckle::Entry.new(:minutes => min)
44
+ assert entry.valid?
45
+ end
46
+
47
+ ['2ah', '1x0', '50)min'].each do |min|
48
+ entry = Freckle::Entry.new(:minutes => min)
49
+ assert !entry.valid?
50
+ end
51
+ end
52
+
53
+ def test_entry_does_not_get_saved_when_invalid
54
+ entry = Freckle::Entry.new(:minutes => 'invalid')
55
+ assert !entry.save
56
+ end
57
+ end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+
3
+ class Freckle::ProjectTest < Test::Unit::TestCase
4
+
5
+ class Freckle::Project
6
+ def self.headers
7
+ { 'X_FRECKLETOKEN' => '123' }
8
+ end
9
+ end
10
+
11
+ def setup
12
+ @projects = [{ :id => 1, :name => "Test1" }].to_xml(:root => "projects")
13
+ @project = { :id => 2, :name => "Test2" }.to_xml(:root => "project")
14
+ @no_projects = [].to_xml(:root=> 'projects')
15
+ ActiveResource::HttpMock.respond_to do |mock|
16
+ mock.post "/api/projects.xml", { 'X_FRECKLETOKEN' => '123' }, @project, 201, "Location" => "/api/projects/1.xml"
17
+ mock.get "/api/projects.xml?name=Test1", { 'X_FRECKLETOKEN' => '123' }, @projects
18
+ mock.get "/api/projects.xml?name=Test2", { 'X_FRECKLETOKEN' => '123' }, @no_projects
19
+ end
20
+ end
21
+
22
+ def test_finding_project_by_name
23
+ project = Freckle::Project.find(:first, :params => { :name => 'Test1' })
24
+ assert_equal "Test1", project.name
25
+ end
26
+
27
+ def test_create_project
28
+ project = Freckle::Project.create(:name => 'Test2')
29
+ assert_equal 2, project.id
30
+ end
31
+
32
+ def test_find_or_create_by_name_should_find_existing_project
33
+ project = Freckle::Project.find_or_create_by_name('Test1')
34
+ assert_equal 1, project.id
35
+ end
36
+
37
+ def test_find_or_create_by_name_should_create_non_existing_project
38
+ project = Freckle::Project.find_or_create_by_name('Test2')
39
+ assert_equal 2, project.id
40
+ end
41
+ end
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), "test_helper.rb")
2
+ require 'freckle/cli'
3
+
4
+ class TestFreckleCli < Test::Unit::TestCase
5
+ def setup
6
+ @stdout_io = StringIO.new
7
+ Freckle::CLI.execute(@stdout_io, [])
8
+ @stdout_io.rewind
9
+ @stdout = @stdout_io.read
10
+ end
11
+
12
+ def test_not_print_default_output
13
+ assert_no_match(/To update this executable/, @stdout)
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'rubygems'
4
+ require 'active_support'
5
+ require 'active_resource/http_mock'
6
+
7
+ require File.dirname(__FILE__) + '/../lib/freckle'
8
+ require File.dirname(__FILE__) + '/../lib/freckle/cli'
9
+
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kommen-freckle-cmd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dieter Komendera
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-13 00:00:00 -08:00
13
+ default_executable: freckle
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: json
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.3
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: activeresource
26
+ version_requirement:
27
+ version_requirements: !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ version: 2.2.2
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: newgem
35
+ version_requirement:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.2.3
41
+ version:
42
+ - !ruby/object:Gem::Dependency
43
+ name: activesupport
44
+ version_requirement:
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 2.2.2
50
+ version:
51
+ - !ruby/object:Gem::Dependency
52
+ name: hoe
53
+ version_requirement:
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 1.8.0
59
+ version:
60
+ description: Command line tool to track time with freckle (http://letsfreckle.com)
61
+ email:
62
+ - dieter@abloom.at
63
+ executables:
64
+ - freckle
65
+ extensions: []
66
+
67
+ extra_rdoc_files:
68
+ - History.txt
69
+ - Manifest.txt
70
+ - PostInstall.txt
71
+ - README.rdoc
72
+ files:
73
+ - History.txt
74
+ - MIT-LICENSE
75
+ - Manifest.txt
76
+ - PostInstall.txt
77
+ - README.rdoc
78
+ - Rakefile
79
+ - bin/freckle
80
+ - freckle.gemspec
81
+ - lib/freckle.rb
82
+ - lib/freckle/app_config.rb
83
+ - lib/freckle/cli.rb
84
+ - lib/freckle/entry.rb
85
+ - lib/freckle/project.rb
86
+ - script/console
87
+ - script/destroy
88
+ - script/generate
89
+ - test/entry_test.rb
90
+ - test/project_test.rb
91
+ - test/test_freckle_cli.rb
92
+ - test/test_helper.rb
93
+ has_rdoc: true
94
+ homepage: http://letsfreckle.com
95
+ post_install_message: PostInstall.txt
96
+ rdoc_options:
97
+ - --main
98
+ - README.rdoc
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: "0"
106
+ version:
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: "0"
112
+ version:
113
+ requirements: []
114
+
115
+ rubyforge_project: freckle-cmd
116
+ rubygems_version: 1.2.0
117
+ signing_key:
118
+ specification_version: 2
119
+ summary: Command line tool to track time with freckle (http://letsfreckle.com)
120
+ test_files:
121
+ - test/test_freckle_cli.rb
122
+ - test/test_helper.rb