stickyflag 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/.gitignore +7 -0
  2. data/.rspec +4 -0
  3. data/.simplecov +9 -0
  4. data/.travis.yml +13 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE.md +7 -0
  7. data/README.md +49 -0
  8. data/Rakefile +19 -0
  9. data/TODO.md +3 -0
  10. data/bin/stickyflag +6 -0
  11. data/features/clear.feature +14 -0
  12. data/features/clear_quietly.feature +23 -0
  13. data/features/configuration.feature +14 -0
  14. data/features/get.feature +14 -0
  15. data/features/get_quietly.feature +23 -0
  16. data/features/set.feature +14 -0
  17. data/features/set_quietly.feature +22 -0
  18. data/features/step_definitions/configuration_steps.rb +31 -0
  19. data/features/step_definitions/database_steps.rb +41 -0
  20. data/features/step_definitions/pending_steps.rb +5 -0
  21. data/features/step_definitions/tag_steps.rb +62 -0
  22. data/features/support/cukegem.rb +82 -0
  23. data/features/support/env.rb +37 -0
  24. data/features/tags.feature +18 -0
  25. data/features/unset.feature +14 -0
  26. data/features/unset_quietly.feature +23 -0
  27. data/lib/stickyflag/configuration.rb +66 -0
  28. data/lib/stickyflag/database.rb +162 -0
  29. data/lib/stickyflag/external_cmds.rb +64 -0
  30. data/lib/stickyflag/patches/tempfile_encoding.rb +22 -0
  31. data/lib/stickyflag/patches/tmpnam.rb +38 -0
  32. data/lib/stickyflag/paths.rb +47 -0
  33. data/lib/stickyflag/tag_factory.rb +108 -0
  34. data/lib/stickyflag/tags/c.rb +25 -0
  35. data/lib/stickyflag/tags/mmd.rb +168 -0
  36. data/lib/stickyflag/tags/pdf.rb +119 -0
  37. data/lib/stickyflag/tags/png.rb +61 -0
  38. data/lib/stickyflag/tags/source_code.rb +99 -0
  39. data/lib/stickyflag/tags/tex.rb +25 -0
  40. data/lib/stickyflag/version.rb +12 -0
  41. data/lib/stickyflag.rb +253 -0
  42. data/spec/spec_helper.rb +22 -0
  43. data/spec/stickyflag/configuration_spec.rb +132 -0
  44. data/spec/stickyflag/database_spec.rb +331 -0
  45. data/spec/stickyflag/external_cmds_spec.rb +175 -0
  46. data/spec/stickyflag/patches/tempfile_encoding_spec.rb +26 -0
  47. data/spec/stickyflag/patches/tmpnam_spec.rb +35 -0
  48. data/spec/stickyflag/paths_spec.rb +29 -0
  49. data/spec/stickyflag/tag_factory_spec.rb +185 -0
  50. data/spec/stickyflag/tags/c_spec.rb +14 -0
  51. data/spec/stickyflag/tags/mmd_spec.rb +40 -0
  52. data/spec/stickyflag/tags/pdf_spec.rb +39 -0
  53. data/spec/stickyflag/tags/png_spec.rb +6 -0
  54. data/spec/stickyflag/tags/tex_spec.rb +6 -0
  55. data/spec/stickyflag_spec.rb +482 -0
  56. data/spec/support/examples/c_all_comments.c +3 -0
  57. data/spec/support/examples/c_no_tags.c +5 -0
  58. data/spec/support/examples/c_with_tag.c +6 -0
  59. data/spec/support/examples/mmd_all_meta.mmd +6 -0
  60. data/spec/support/examples/mmd_crazy_keys.mmd +8 -0
  61. data/spec/support/examples/mmd_crazy_tags.mmd +9 -0
  62. data/spec/support/examples/mmd_no_tags.mmd +1 -0
  63. data/spec/support/examples/mmd_with_tag.mmd +3 -0
  64. data/spec/support/examples/pdf_no_tags.pdf +0 -0
  65. data/spec/support/examples/pdf_with_tag.pdf +0 -0
  66. data/spec/support/examples/png_no_tags.png +0 -0
  67. data/spec/support/examples/png_with_tag.png +0 -0
  68. data/spec/support/examples/tex_no_tags.tex +10 -0
  69. data/spec/support/examples/tex_with_tag.tex +11 -0
  70. data/spec/support/examples/untaggable.txt +0 -0
  71. data/spec/support/examples.rb +32 -0
  72. data/spec/support/run_with_args.rb +36 -0
  73. data/spec/support/silence_stream.rb +12 -0
  74. data/spec/support/tag_handler_behavior.rb +125 -0
  75. data/stickyflag.gemspec +48 -0
  76. metadata +399 -0
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ Gemfile.lock
2
+
3
+ pkg
4
+ spec/coverage
5
+ tmp
6
+
7
+ *.gem
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require thor
2
+ --require spec_helper
3
+ --colour
4
+ --order random
data/.simplecov ADDED
@@ -0,0 +1,9 @@
1
+ SimpleCov.start do
2
+ coverage_dir '/spec/coverage'
3
+ add_filter '/spec/'
4
+
5
+ add_group 'Frontend', 'bin'
6
+ add_group 'Library code', 'lib'
7
+ add_group 'File taggers', 'lib/tags'
8
+ add_group 'Core patches', 'lib/patches'
9
+ end
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ before_install:
3
+ - sudo apt-get update -qq
4
+ - sudo apt-get install -qq pdftk
5
+ script: "bundle exec rake"
6
+
7
+ env:
8
+ - CI=true
9
+ rvm:
10
+ - 1.9.3
11
+ - 1.8.7
12
+ - ree
13
+ - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2012 Charles H. Pence
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,49 @@
1
+
2
+ # StickyFlag
3
+
4
+ *file tagging for everyone*
5
+
6
+ ## What does it do?
7
+
8
+ Filesystems are great. Most of our file organization tasks can be performed by arranging things in hierarchical directories. But every once in a while, you have an organization problem that can really only be resolved with categories that *cut across* these hierarchical structures. What if you want everything related to Project X, including its code, meeting notes about it, photos you took of it, and so on? The code is in your development directory, meeting notes in a meetings directory, and photos in an images directory.
9
+
10
+ StickyFlag solves this problem. It lets you set tags on all your files, and then search across all those files quickly, by storing tags in a database. But it doesn't just keep the tags in the database -- it saves the tags *directly into the files.* So your tags stick with your files, even if your StickyFlag database becomes corrupted, or you want to sync your files via Dropbox over to a different machine.
11
+
12
+ ## TL;DR
13
+
14
+ * Set tags on a wide variety of files
15
+ * Save those tags *in the files themselves*
16
+ * Also save those tags in a database for searching
17
+
18
+ ## What can it tag?
19
+
20
+ StickyFlag can currently tag:
21
+
22
+ * MultiMarkdown files
23
+ * PDF files (with `pdftk` installed; see below)
24
+ * PNG files
25
+ * Source code (C/C++, TeX)
26
+
27
+ ## What else does it need?
28
+
29
+ If you're going to tag PDF files, you need to install [pdftk,](http://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/) which is available for Windows, Mac OS X, and Linux (licensed under the GPL).
30
+
31
+ ## How do I get it?
32
+
33
+ `gem install stickyflag`
34
+
35
+ ## How do I use it?
36
+
37
+ * `stickyflag get [FILE] [...]`: Query the tags from a list of files
38
+ * `stickyflag set [FILE] [TAG]`: Set the given tag on the given file
39
+ * `stickyflag unset [FILE] [TAG]`: Remove the given tag from the given file
40
+ * `stickyflag clear [FILE]`: Remove all the tags from the given file
41
+ * `stickyflag update`: Refresh the information in the tag database from your files on disk
42
+ * `stickyflag tags`: Print a list of all the tags currently in use in all of your files
43
+ * `stickyflag find [TAG] [...]`: List all files that are tagged with *all* of the listed tags
44
+
45
+ `stickyflag update` will run from the current directory, or can run from a user-specified "root" directory, which can be set via calling `stickyflag config`. `stickyflag config` can also be used to set a couple of other configuration values, like the path to your `pdftk` executable.
46
+
47
+ ## Who did this?
48
+
49
+ StickyFlag is authored by [Charles Pence](http://charlespence.net) and released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ require 'cucumber'
8
+ require 'cucumber/rake/task'
9
+ Cucumber::Rake::Task.new(:features) do |t|
10
+ t.cucumber_opts = 'features --quiet'
11
+ end
12
+
13
+
14
+ task :default do
15
+ Rake::Task[:spec].execute
16
+ if RUBY_PLATFORM != 'java'
17
+ Rake::Task[:features].execute
18
+ end
19
+ end
data/TODO.md ADDED
@@ -0,0 +1,3 @@
1
+ # TODO
2
+
3
+ - Add tag handlers: JPEG, MMD
data/bin/stickyflag ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- encoding : utf-8 -*-
3
+ $KCODE = 'U' if RUBY_VERSION < "1.9.0"
4
+ require 'rubygems'
5
+ require 'stickyflag'
6
+ StickyFlag::ThorApp.start
@@ -0,0 +1,14 @@
1
+ Feature: Clear File Tags
2
+ In order to reset the tags on a file
3
+ As a user with some tagged files
4
+ I want to be able to clear all the file's tags
5
+
6
+ Scenario: Clear tags from a tagged file
7
+ Given the example configuration
8
+ When I clear the tags for "mmd_crazy_tags.mmd"
9
+ Then the output should match /Tags cleared for .*mmd_crazy_tags\.mmd/
10
+
11
+ Scenario: Clear tags from an untagged file
12
+ Given the example configuration
13
+ When I clear the tags for "mmd_no_tags.mmd"
14
+ Then the output should match /Tags cleared for .*mmd_no_tags\.mmd/
@@ -0,0 +1,23 @@
1
+ Feature: Silence Extraneous Output on Clear
2
+ In order to use StickyFlag in scripts
3
+ As a power user
4
+ I want to be able to clear tags without any output at all
5
+
6
+ Scenario: Clear tags without worrying about missing tags or files
7
+ Given the example configuration
8
+ When I quietly clear the tags for "mmd_crazy_tags.mmd", "mmd_no_tags.mmd", and "nonexistent.mmd"
9
+ Then the output should not contain "mmd_crazy_tags.mmd"
10
+ And the output should not contain "mmd_no_tags.mmd"
11
+ And the output should not contain "nonexistent.mmd"
12
+
13
+ Scenario: Determine quiet tag clear success from return value
14
+ Given the example configuration
15
+ Given PENDING: figure out how to get Thor to do exit codes
16
+ When I quietly clear the tags for "mmd_crazy_tags.mmd"
17
+ Then the exit status should be 0
18
+
19
+ Scenario: Determine quiet tag clear failure from return value
20
+ Given the example configuration
21
+ Given PENDING: figure out how to get Thor to do exit codes
22
+ When I quietly clear the tags for "nonexistent.mmd"
23
+ Then the exit status should not be 0
@@ -0,0 +1,14 @@
1
+ Feature: Persistent Configuration
2
+ In order to customize the behavior of StickyFlag
3
+ As a new user
4
+ I want to be able to set persistent configuration values
5
+
6
+ Scenario: Set and query a configuration value
7
+ Given a clean configuration
8
+ When I set the configuration key "root" to "/test/"
9
+ And I get the configuration key "root"
10
+ Then the output should contain "root: '/test/'"
11
+
12
+ Scenario: Query a previously set configuration value
13
+ When I get the configuration key "root"
14
+ Then the output should contain "root: '/test/'"
@@ -0,0 +1,14 @@
1
+ Feature: Get File Tags
2
+ In order to know what tags I have set on a file
3
+ As a user with some tagged files
4
+ I want to be able to query the file tags
5
+
6
+ Scenario: Get tags from a tagged file
7
+ Given the example configuration
8
+ When I get the tags for "mmd_crazy_tags.mmd"
9
+ Then the output should contain "mmd_crazy_tags.mmd: asdf, sdfg, dfgh, fghj, qwer"
10
+
11
+ Scenario: Get tags from an untagged file
12
+ Given the example configuration
13
+ When I get the tags for "mmd_no_tags.mmd"
14
+ Then the output should contain "mmd_no_tags.mmd: no tags"
@@ -0,0 +1,23 @@
1
+ Feature: Silence Extraneous Output on Get
2
+ In order to use StickyFlag in scripts
3
+ As a power user
4
+ I want to be able to get tags without extra output
5
+
6
+ Scenario: Get tags without worrying about missing tags or files
7
+ Given the example configuration
8
+ When I quietly get the tags for "mmd_crazy_tags.mmd", "mmd_no_tags.mmd", and "nonexistent.mmd"
9
+ Then the output should contain "mmd_crazy_tags.mmd: asdf, sdfg, dfgh, fghj, qwer"
10
+ And the output should not contain "mmd_no_tags.mmd"
11
+ And the output should not contain "nonexistent.mmd"
12
+
13
+ Scenario: Determine quiet tag get success from return value
14
+ Given the example configuration
15
+ Given PENDING: figure out how to get Thor to do exit codes
16
+ When I quietly get the tags for "mmd_crazy_tags.mmd"
17
+ Then the exit status should be 0
18
+
19
+ Scenario: Determine quiet tag get failure from return value
20
+ Given the example configuration
21
+ Given PENDING: figure out how to get Thor to do exit codes
22
+ When I quietly get the tags for "nonexistent.mmd"
23
+ Then the exit status should not be 0
@@ -0,0 +1,14 @@
1
+ Feature: Set File Tags
2
+ In order to keep track of my files
3
+ As a user
4
+ I want to be able to set new tags on files
5
+
6
+ Scenario: Set tags on an already tagged file
7
+ Given the example configuration
8
+ When I set the tag "test2" for "mmd_crazy_tags.mmd"
9
+ Then the output should match /New tags for .*mmd_crazy_tags.mmd: asdf, sdfg, dfgh, fghj, qwer, test2/
10
+
11
+ Scenario: Set tags on an untagged file
12
+ Given the example configuration
13
+ When I set the tag "test" for "mmd_no_tags.mmd"
14
+ Then the output should match /New tags for .*mmd_no_tags.mmd: test/
@@ -0,0 +1,22 @@
1
+ Feature: Silence Extraneous Output on Set
2
+ In order to use StickyFlag in scripts
3
+ As a power user
4
+ I want to be able to set tags without any output at all
5
+
6
+ Scenario: Set tags with no output at all
7
+ Given the example configuration
8
+ When I quietly set the tag "test2" for "mmd_crazy_tags.mmd"
9
+ Then the output should not contain "mmd_crazy_tags.mmd"
10
+ And the output should not contain "test2"
11
+
12
+ Scenario: Determine quiet set tag success from return value
13
+ Given the example configuration
14
+ Given PENDING: figure out how to get Thor to do exit codes
15
+ When I quietly set the tag "test2" for "mmd_crazy_tags.mmd"
16
+ Then the exit status should be 0
17
+
18
+ Scenario: Determine quiet set tag failure from return value
19
+ Given the example configuration
20
+ Given PENDING: figure out how to get Thor to do exit codes
21
+ When I quietly set the tag "test" for "nonexistent.mmd"
22
+ Then the exit status should not be 0
@@ -0,0 +1,31 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rspec/expectations'
3
+ require 'cucumber/formatter/unicode'
4
+ require 'aruba/cucumber'
5
+ require_relative '../../spec/support/examples'
6
+
7
+ Given /a clean configuration/ do
8
+ FileUtils.rm $paths.config_path if File.exist? $paths.config_path
9
+ end
10
+
11
+ Given /the example configuration/ do
12
+ path = example_root
13
+
14
+ steps %Q{
15
+ Given a clean configuration
16
+ When I run `stickyflag config -k root '#{path}'`
17
+ And I run `stickyflag update`
18
+ }
19
+ end
20
+
21
+ When /I set the configuration key "(.*?)" to "(.*?)"$/ do |key, val|
22
+ steps %Q{
23
+ When I run `stickyflag config -k '#{key}' '#{val}'`
24
+ }
25
+ end
26
+
27
+ When /I get the configuration key "(.*?)"$/ do |key|
28
+ steps %Q{
29
+ When I run `stickyflag config -k '#{key}'`
30
+ }
31
+ end
@@ -0,0 +1,41 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rspec/expectations'
3
+ require 'cucumber/formatter/unicode'
4
+ require 'aruba/cucumber'
5
+
6
+ Given /a clean database/ do
7
+ FileUtils.rm $paths.database_path if File.exist? $paths.database_path
8
+ end
9
+
10
+ Given /the example database/ do
11
+ steps %Q{
12
+ Given the example configuration
13
+ When I run `stickyflag update`
14
+ }
15
+ end
16
+
17
+ Given /I update the database in the directory "(.*?)"$/ do |dir|
18
+ steps %Q{
19
+ When I set the configuration key "root" to "#{dir}"
20
+ When I run `stickyflag update`
21
+ }
22
+ end
23
+
24
+ When /I get the list of tags in use/ do
25
+ steps %Q{
26
+ When I run `stickyflag tags`
27
+ }
28
+ end
29
+
30
+ When /I quietly get the list of tags in use/ do
31
+ steps %Q{
32
+ When I run `stickyflag tags --quiet`
33
+ }
34
+ end
35
+
36
+ When /I search for the tag (".*?")$/ do |tag_strings|
37
+ tags = tag_strings.scan(/"([^"]+?)"/).flatten
38
+ steps %Q{
39
+ When I run `stickyflag find #{tags.join(' ')}`
40
+ }
41
+ end
@@ -0,0 +1,5 @@
1
+ # -*- encoding : utf-8 -*-
2
+
3
+ Given /^PENDING/ do
4
+ pending
5
+ end
@@ -0,0 +1,62 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rspec/expectations'
3
+ require 'cucumber/formatter/unicode'
4
+ require 'aruba/cucumber'
5
+ require 'backports'
6
+ require_relative '../../spec/support/examples'
7
+
8
+ When /I get the tags for (".*?")$/ do |filename_strings|
9
+ filenames = filename_strings.scan(/"([^"]+?)"/).flatten.map { |f| "'#{example_path(f).to_s}'" }
10
+ steps %Q{
11
+ When I run `stickyflag get #{filenames.join(' ')}`
12
+ }
13
+ end
14
+
15
+ When /I quietly get the tags for (".*?")$/ do |filename_strings|
16
+ filenames = filename_strings.scan(/"([^"]+?)"/).flatten.map { |f| "'#{example_path(f).to_s}'" }
17
+ steps %Q{
18
+ When I run `stickyflag get #{filenames.join(' ')} --quiet`
19
+ }
20
+ end
21
+
22
+ When /I set the tag "(.*?)" for "(.*?)"$/ do |tag, filename|
23
+ path = copy_example(filename)
24
+ steps %Q{
25
+ When I run `stickyflag set '#{path}' '#{tag}'`
26
+ }
27
+ end
28
+
29
+ When /I quietly set the tag "(.*?)" for "(.*?)"$/ do |tag, filename|
30
+ path = copy_example(filename)
31
+ steps %Q{
32
+ When I run `stickyflag set '#{path}' '#{tag}' --quiet`
33
+ }
34
+ end
35
+
36
+ When /I unset the tag "(.*?)" for "(.*?)"$/ do |tag, filename|
37
+ path = copy_example(filename)
38
+ steps %Q{
39
+ When I run `stickyflag unset '#{path}' '#{tag}'`
40
+ }
41
+ end
42
+
43
+ When /I quietly unset the tag "(.*?)" for "(.*?)"$/ do |tag, filename|
44
+ path = copy_example(filename)
45
+ steps %Q{
46
+ When I run `stickyflag unset '#{path}' '#{tag}' --quiet`
47
+ }
48
+ end
49
+
50
+ When /I clear the tags for (".*?")$/ do |filename_strings|
51
+ filenames = filename_strings.scan(/"([^"]+?)"/).flatten.map { |f| "'#{copy_example(f).to_s}'" }
52
+ steps %Q{
53
+ When I run `stickyflag clear #{filenames.join(' ')}`
54
+ }
55
+ end
56
+
57
+ When /I quietly clear the tags for (".*?")$/ do |filename_strings|
58
+ filenames = filename_strings.scan(/"([^"]+?)"/).flatten.map { |f| "'#{copy_example(f).to_s}'" }
59
+ steps %Q{
60
+ When I run `stickyflag clear #{filenames.join(' ')} --quiet`
61
+ }
62
+ end
@@ -0,0 +1,82 @@
1
+ # Copyright 2011 Solano Labs All Rights Reserved
2
+
3
+ require 'aruba'
4
+ require 'aruba/api'
5
+
6
+ class CukeGem
7
+ @setup_done = false
8
+
9
+ class << self
10
+ include Aruba::Api
11
+
12
+ attr_reader :setup_done
13
+
14
+ def setup(gemspec, once=true)
15
+ gem_home = setup_env
16
+ if !@setup_done || !once then
17
+ @setup_done = true
18
+ mkgemdir(gem_home)
19
+ gem_install(gemspec)
20
+ end
21
+ end
22
+
23
+ def teardown
24
+ restore_env
25
+ end
26
+
27
+ def setup_env
28
+ tid = ENV['TDDIUM_TID'] || ''
29
+ gem_home = File.expand_path(File.join(Dir.tmpdir, "aruba-gem"))
30
+
31
+ set_env('GEM_HOME', gem_home)
32
+ set_env('GEM_PATH', gem_home)
33
+ set_env('BUNDLE_PATH', gem_home)
34
+ unset_bundler_env_vars
35
+
36
+ paths = (ENV['PATH'] || "").split(File::PATH_SEPARATOR)
37
+ paths.unshift(File.join(gem_home, 'bin'))
38
+ set_env('PATH', paths.uniq.join(File::PATH_SEPARATOR))
39
+
40
+ return gem_home
41
+ end
42
+
43
+ def mkgemdir(gem_home)
44
+ FileUtils::rm_rf(gem_home)
45
+ FileUtils::mkdir_p(gem_home)
46
+
47
+ output = `gem install bundler`
48
+ if $?.exitstatus != 0 then
49
+ raise "unable to install bundler into #{gem_home}: #{output}"
50
+ end
51
+ end
52
+
53
+ def gem_install(gemspec)
54
+ gem_file = nil
55
+ begin
56
+ pwd = Dir.pwd
57
+ gemspec_dir = File.dirname(gemspec)
58
+ Dir.chdir(gemspec_dir)
59
+ output = `gem build #{File.basename(gemspec)}`
60
+ Dir.chdir(pwd)
61
+
62
+ if $?.exitstatus != 0 then
63
+ raise "unable to build gem: #{output}"
64
+ end
65
+
66
+ if output =~ /File:\s+([A-Za-z0-9_.-]+[.]gem)/ then
67
+ gem_file = $1
68
+ output = `gem install #{File.join(gemspec_dir, gem_file)}`
69
+ if $?.exitstatus != 0 then
70
+ raise "unable to install gem: #{output}"
71
+ end
72
+ else
73
+ raise "garbled gem build output: #{output}"
74
+ end
75
+ ensure
76
+ if gem_file then
77
+ FileUtils.rm_f(File.join(gemspec_dir, gem_file))
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,37 @@
1
+ # -*- encoding : utf-8 -*-
2
+ $:.unshift File.expand_path("../../../lib", __FILE__)
3
+
4
+ require 'rubygems'
5
+ require 'bundler/setup'
6
+
7
+ require 'backports'
8
+ require 'aruba/cucumber'
9
+ require 'stickyflag'
10
+ require 'fileutils'
11
+ require_relative './cukegem'
12
+
13
+ # JRuby is slow to start up
14
+ Before do
15
+ @aruba_timeout_seconds = 10
16
+ end
17
+
18
+ # Back up and restore the user's configuration and database
19
+ $backup_db = File.tmpnam('.sqlite')
20
+ $backup_config = File.tmpnam('.yml')
21
+
22
+ class GetPaths
23
+ include StickyFlag::Paths
24
+ end
25
+ $paths = GetPaths.new
26
+
27
+ FileUtils.mv $paths.config_path, $backup_config if File.exist? $paths.config_path
28
+ FileUtils.mv $paths.database_path, $backup_db if File.exist? $paths.database_path
29
+
30
+ CukeGem.setup(File.expand_path('../../../stickyflag.gemspec', __FILE__))
31
+
32
+ at_exit do
33
+ CukeGem.teardown
34
+
35
+ FileUtils.mv $backup_config, $paths.config_path if File.exist? $backup_config
36
+ FileUtils.mv $backup_db, $paths.database_path if File.exist? $backup_db
37
+ end
@@ -0,0 +1,18 @@
1
+ Feature: Get List of Tags in Use
2
+ In order to know which tags I've already used
3
+ As a user with some tagged files
4
+ I want to be able to get a list of all file tags
5
+
6
+ Scenario: Get list of tags
7
+ Given the example database
8
+ When I get the list of tags in use
9
+ Then the output should contain " test"
10
+ And the output should contain " asdf"
11
+ And the output should contain "Tags currently in use:"
12
+ And the output should not contain "rspec"
13
+
14
+ Scenario: Get bare list of tags for scripting
15
+ Given the example database
16
+ When I quietly get the list of tags in use
17
+ Then the output should not contain "Tags currently in use:"
18
+ And the output should contain "\ntest\n"
@@ -0,0 +1,14 @@
1
+ Feature: Unset File Tags
2
+ In order to be able to change my mind
3
+ As a user
4
+ I want to be able to unset or remove tags from files
5
+
6
+ Scenario: Unset tags from a file with multiple tags
7
+ Given the example configuration
8
+ When I unset the tag "asdf" for "mmd_crazy_tags.mmd"
9
+ Then the output should match /New tags for .*mmd_crazy_tags.mmd: sdfg, dfgh, fghj, qwer/
10
+
11
+ Scenario: Unset tags from a file with one tag
12
+ Given the example configuration
13
+ When I unset the tag "test" for "mmd_with_tag.mmd"
14
+ Then the output should match /New tags for .*mmd_with_tag.mmd: no tags/
@@ -0,0 +1,23 @@
1
+ Feature: Silence Extraneous Output on Unset
2
+ In order to use StickyFlag in scripts
3
+ As a power user
4
+ I want to be able to unset tags without any output at all
5
+
6
+ Scenario: Unset tags with no output at all
7
+ Given the example configuration
8
+ When I quietly unset the tag "asdf" for "mmd_crazy_tags.mmd"
9
+ Then the output should not contain "mmd_crazy_tags.mmd"
10
+ And the output should not contain "sdfg"
11
+
12
+ Scenario: Determine quiet unset tag success from return value
13
+ Given the example configuration
14
+ Given PENDING: figure out how to get Thor to do exit codes
15
+ When I quietly unset the tag "asdf" for "mmd_crazy_tags.mmd"
16
+ Then the exit status should be 0
17
+
18
+ Scenario: Determine quiet unset tag failure from return value
19
+ Given the example configuration
20
+ Given PENDING: figure out how to get Thor to do exit codes
21
+ When I quietly unset the tag "test" for "nonexistent.mmd"
22
+ Then the exit status should not be 0
23
+
@@ -0,0 +1,66 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'thor'
3
+ require 'yaml'
4
+ require 'stickyflag/paths'
5
+
6
+ module StickyFlag
7
+ module Configuration
8
+ DEFAULT_CONFIG = {
9
+ :have_pdftk => false,
10
+ :pdftk_path => '',
11
+ :root => ''
12
+ }
13
+
14
+ def get_config(key)
15
+ @configuration ||= DEFAULT_CONFIG.clone
16
+
17
+ unless @configuration.keys.include?(key.to_sym)
18
+ raise Thor::Error.new('ERROR: Invalid configuration key')
19
+ end
20
+
21
+ @configuration[key.to_sym]
22
+ end
23
+
24
+ def set_config(key, value)
25
+ @configuration ||= DEFAULT_CONFIG.clone
26
+
27
+ unless @configuration.keys.include?(key.to_sym)
28
+ raise Thor::Error.new('ERROR: invalid configuration key')
29
+ end
30
+
31
+ @configuration[key.to_sym] = value
32
+ end
33
+
34
+ def reset_config!
35
+ @configuration = DEFAULT_CONFIG.clone
36
+ save_config!
37
+ end
38
+
39
+ def dump_config
40
+ @configuration ||= DEFAULT_CONFIG.clone
41
+
42
+ return if options.quiet?
43
+
44
+ say "StickyFlag Configuration:"
45
+ @configuration.each do |key, val|
46
+ say " #{key}: '#{val}'"
47
+ end
48
+ end
49
+
50
+ def load_config!
51
+ file_name = config_path
52
+ if File.file? file_name
53
+ @configuration = YAML::load(File.open(file_name, 'r:UTF-8'))
54
+ end
55
+ end
56
+
57
+ def save_config!
58
+ @configuration ||= DEFAULT_CONFIG.clone
59
+
60
+ file_name = config_path
61
+ File.open(file_name, 'w:UTF-8') do |f|
62
+ YAML.dump(@configuration, f)
63
+ end
64
+ end
65
+ end
66
+ end