stickyflag 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.rspec +4 -0
- data/.simplecov +9 -0
- data/.travis.yml +13 -0
- data/Gemfile +2 -0
- data/LICENSE.md +7 -0
- data/README.md +49 -0
- data/Rakefile +19 -0
- data/TODO.md +3 -0
- data/bin/stickyflag +6 -0
- data/features/clear.feature +14 -0
- data/features/clear_quietly.feature +23 -0
- data/features/configuration.feature +14 -0
- data/features/get.feature +14 -0
- data/features/get_quietly.feature +23 -0
- data/features/set.feature +14 -0
- data/features/set_quietly.feature +22 -0
- data/features/step_definitions/configuration_steps.rb +31 -0
- data/features/step_definitions/database_steps.rb +41 -0
- data/features/step_definitions/pending_steps.rb +5 -0
- data/features/step_definitions/tag_steps.rb +62 -0
- data/features/support/cukegem.rb +82 -0
- data/features/support/env.rb +37 -0
- data/features/tags.feature +18 -0
- data/features/unset.feature +14 -0
- data/features/unset_quietly.feature +23 -0
- data/lib/stickyflag/configuration.rb +66 -0
- data/lib/stickyflag/database.rb +162 -0
- data/lib/stickyflag/external_cmds.rb +64 -0
- data/lib/stickyflag/patches/tempfile_encoding.rb +22 -0
- data/lib/stickyflag/patches/tmpnam.rb +38 -0
- data/lib/stickyflag/paths.rb +47 -0
- data/lib/stickyflag/tag_factory.rb +108 -0
- data/lib/stickyflag/tags/c.rb +25 -0
- data/lib/stickyflag/tags/mmd.rb +168 -0
- data/lib/stickyflag/tags/pdf.rb +119 -0
- data/lib/stickyflag/tags/png.rb +61 -0
- data/lib/stickyflag/tags/source_code.rb +99 -0
- data/lib/stickyflag/tags/tex.rb +25 -0
- data/lib/stickyflag/version.rb +12 -0
- data/lib/stickyflag.rb +253 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/stickyflag/configuration_spec.rb +132 -0
- data/spec/stickyflag/database_spec.rb +331 -0
- data/spec/stickyflag/external_cmds_spec.rb +175 -0
- data/spec/stickyflag/patches/tempfile_encoding_spec.rb +26 -0
- data/spec/stickyflag/patches/tmpnam_spec.rb +35 -0
- data/spec/stickyflag/paths_spec.rb +29 -0
- data/spec/stickyflag/tag_factory_spec.rb +185 -0
- data/spec/stickyflag/tags/c_spec.rb +14 -0
- data/spec/stickyflag/tags/mmd_spec.rb +40 -0
- data/spec/stickyflag/tags/pdf_spec.rb +39 -0
- data/spec/stickyflag/tags/png_spec.rb +6 -0
- data/spec/stickyflag/tags/tex_spec.rb +6 -0
- data/spec/stickyflag_spec.rb +482 -0
- data/spec/support/examples/c_all_comments.c +3 -0
- data/spec/support/examples/c_no_tags.c +5 -0
- data/spec/support/examples/c_with_tag.c +6 -0
- data/spec/support/examples/mmd_all_meta.mmd +6 -0
- data/spec/support/examples/mmd_crazy_keys.mmd +8 -0
- data/spec/support/examples/mmd_crazy_tags.mmd +9 -0
- data/spec/support/examples/mmd_no_tags.mmd +1 -0
- data/spec/support/examples/mmd_with_tag.mmd +3 -0
- data/spec/support/examples/pdf_no_tags.pdf +0 -0
- data/spec/support/examples/pdf_with_tag.pdf +0 -0
- data/spec/support/examples/png_no_tags.png +0 -0
- data/spec/support/examples/png_with_tag.png +0 -0
- data/spec/support/examples/tex_no_tags.tex +10 -0
- data/spec/support/examples/tex_with_tag.tex +11 -0
- data/spec/support/examples/untaggable.txt +0 -0
- data/spec/support/examples.rb +32 -0
- data/spec/support/run_with_args.rb +36 -0
- data/spec/support/silence_stream.rb +12 -0
- data/spec/support/tag_handler_behavior.rb +125 -0
- data/stickyflag.gemspec +48 -0
- metadata +399 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.simplecov
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
data/bin/stickyflag
ADDED
@@ -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,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
|