taskloop 0.1.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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.idea/.gitignore +8 -0
  3. data/.idea/misc.xml +4 -0
  4. data/.idea/modules.xml +8 -0
  5. data/.idea/taskloop.iml +51 -0
  6. data/.idea/vcs.xml +6 -0
  7. data/Gemfile +9 -0
  8. data/Gemfile.lock +36 -0
  9. data/README.md +31 -0
  10. data/Rakefile +4 -0
  11. data/exe/taskloop +16 -0
  12. data/lib/taskloop/command/deploy.rb +136 -0
  13. data/lib/taskloop/command/env.rb +134 -0
  14. data/lib/taskloop/command/init.rb +42 -0
  15. data/lib/taskloop/command/launch.rb +67 -0
  16. data/lib/taskloop/command/list.rb +59 -0
  17. data/lib/taskloop/command/log.rb +104 -0
  18. data/lib/taskloop/command/run.rb +106 -0
  19. data/lib/taskloop/command/shutdown.rb +49 -0
  20. data/lib/taskloop/command/undeploy.rb +46 -0
  21. data/lib/taskloop/command.rb +168 -0
  22. data/lib/taskloop/dsl/dsl.rb +63 -0
  23. data/lib/taskloop/extension/integer_extension.rb +25 -0
  24. data/lib/taskloop/extension/string_extension.rb +18 -0
  25. data/lib/taskloop/rules/after_scope_rule.rb +91 -0
  26. data/lib/taskloop/rules/before_scope_rule.rb +90 -0
  27. data/lib/taskloop/rules/between_scope_rule.rb +130 -0
  28. data/lib/taskloop/rules/date_list_rule.rb +47 -0
  29. data/lib/taskloop/rules/default_rule.rb +19 -0
  30. data/lib/taskloop/rules/interval_rule.rb +26 -0
  31. data/lib/taskloop/rules/loop_rule.rb +25 -0
  32. data/lib/taskloop/rules/rule.rb +34 -0
  33. data/lib/taskloop/rules/scope_rule.rb +22 -0
  34. data/lib/taskloop/rules/specific_rule.rb +64 -0
  35. data/lib/taskloop/rules/time_list_rule.rb +49 -0
  36. data/lib/taskloop/task/task.rb +244 -0
  37. data/lib/taskloop/task/task_data_file.rb +46 -0
  38. data/lib/taskloop/task/task_error.rb +17 -0
  39. data/lib/taskloop/task/task_property.rb +294 -0
  40. data/lib/taskloop/utils/proj_tasklist.rb +145 -0
  41. data/lib/taskloop/version.rb +5 -0
  42. data/lib/taskloop.rb +9 -0
  43. data/sig/taskloop.rbs +4 -0
  44. data/taskloop.gemspec +37 -0
  45. metadata +103 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 6395f4580c66f3deef3ec7a0a6103083b7d1b3a608c68cc0b878ad0a496c0116
4
+ data.tar.gz: 8775908ba3ac44c34dd23435e5159e52fab16d7901ff970d0a3d2af7ccc3e8d4
5
+ SHA512:
6
+ metadata.gz: d2e8aa350458c9d9538cc339fbfd93f820fc3abdfcc4d905178d757805d9cafda6042c5049b12033ca84814fcd1f8d2111bc890c23de5b8785fb180553980dd2
7
+ data.tar.gz: fc4513b7568acc4789af5b39d73b31b28039bae7885b9ff70c838fc00f810fc9d501eba9041c540026da02224c8ba3763988d9fa7f39d8dc9157eb0ec0dc771e
data/.idea/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
data/.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="RVM: ruby-2.6.5 [yp]" project-jdk-type="RUBY_SDK" />
4
+ </project>
data/.idea/modules.xml ADDED
@@ -0,0 +1,8 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectModuleManager">
4
+ <modules>
5
+ <module fileurl="file://$PROJECT_DIR$/.idea/taskloop.iml" filepath="$PROJECT_DIR$/.idea/taskloop.iml" />
6
+ </modules>
7
+ </component>
8
+ </project>
@@ -0,0 +1,51 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="RUBY_MODULE" version="4">
3
+ <component name="ModuleRunConfigurationManager">
4
+ <shared />
5
+ </component>
6
+ <component name="NewModuleRootManager">
7
+ <content url="file://$MODULE_DIR$">
8
+ <sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
9
+ <sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
10
+ <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
11
+ </content>
12
+ <orderEntry type="inheritedJdk" />
13
+ <orderEntry type="sourceFolder" forTests="false" />
14
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v1.17.3, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="claide (v1.0.3, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
16
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.5.0, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="rake (v12.3.3, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
18
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v3.12.0, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
19
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.12.2, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.12.3, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
21
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.12.5, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
22
+ <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.12.1, RVM: ruby-2.6.5 [yp]) [gem]" level="application" />
23
+ </component>
24
+ <component name="RakeTasksCache">
25
+ <option name="myRootTask">
26
+ <RakeTaskImpl id="rake">
27
+ <subtasks>
28
+ <RakeTaskImpl description="Build taskloop-0.1.0.gem into the pkg directory" fullCommand="build" id="build" />
29
+ <RakeTaskImpl description="Remove any temporary products" fullCommand="clean" id="clean" />
30
+ <RakeTaskImpl description="Remove any generated files" fullCommand="clobber" id="clobber" />
31
+ <RakeTaskImpl description="Build and install taskloop-0.1.0.gem into system gems" fullCommand="install" id="install" />
32
+ <RakeTaskImpl id="install">
33
+ <subtasks>
34
+ <RakeTaskImpl description="Build and install taskloop-0.1.0.gem into system gems without network access" fullCommand="install:local" id="local" />
35
+ </subtasks>
36
+ </RakeTaskImpl>
37
+ <RakeTaskImpl description="Create tag v0.1.0 and build and push taskloop-0.1.0.gem to rubygems.org" fullCommand="release[remote]" id="release[remote]" />
38
+ <RakeTaskImpl description="" fullCommand="default" id="default" />
39
+ <RakeTaskImpl description="" fullCommand="release" id="release" />
40
+ <RakeTaskImpl id="release">
41
+ <subtasks>
42
+ <RakeTaskImpl description="" fullCommand="release:guard_clean" id="guard_clean" />
43
+ <RakeTaskImpl description="" fullCommand="release:rubygem_push" id="rubygem_push" />
44
+ <RakeTaskImpl description="" fullCommand="release:source_control_push" id="source_control_push" />
45
+ </subtasks>
46
+ </RakeTaskImpl>
47
+ </subtasks>
48
+ </RakeTaskImpl>
49
+ </option>
50
+ </component>
51
+ </module>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in taskloop.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 12.0"
9
+ gem "rspec", "~> 3.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ taskloop (0.1.0)
5
+ claide (~> 1.0.3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ claide (1.0.3)
11
+ diff-lcs (1.5.0)
12
+ rake (12.3.3)
13
+ rspec (3.12.0)
14
+ rspec-core (~> 3.12.0)
15
+ rspec-expectations (~> 3.12.0)
16
+ rspec-mocks (~> 3.12.0)
17
+ rspec-core (3.12.2)
18
+ rspec-support (~> 3.12.0)
19
+ rspec-expectations (3.12.3)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.12.0)
22
+ rspec-mocks (3.12.5)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.12.0)
25
+ rspec-support (3.12.1)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ rake (~> 12.0)
32
+ rspec (~> 3.0)
33
+ taskloop!
34
+
35
+ BUNDLED WITH
36
+ 1.17.3
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ ![](https://chuquan-public-r-001.oss-cn-shanghai.aliyuncs.com/sketch-images/taskloop-logo-white.png)
2
+
3
+ # Taskloop
4
+
5
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/taskloop`. To experiment with that code, run `bin/console` for an interactive prompt.
6
+
7
+ TODO: Delete this and the text above, and describe your gem
8
+
9
+ ## Installation
10
+
11
+ Install the gem and add to the application's Gemfile by executing:
12
+
13
+ $ bundle add taskloop
14
+
15
+ If bundler is not being used to manage dependencies, install the gem by executing:
16
+
17
+ $ gem install taskloop
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Development
24
+
25
+ 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.
26
+
27
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
28
+
29
+ ## Contributing
30
+
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/taskloop.
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ task default: %i[]
data/exe/taskloop ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/taskloop"
4
+
5
+ TaskLoop::Command.run(ARGV)
6
+ # TaskLoop::Command.run(["init"])
7
+ # TaskLoop::Command.run(["list"])
8
+ # TaskLoop::Command.run(["log", "--task-name=chuquan"])
9
+ # TaskLoop::Command.run(["log", "--cron"])
10
+ # TaskLoop::Command.run(["launch"])
11
+ # TaskLoop::Command.run(["env", "--remove=NOX_TEMPALTES,NOX_HOME"])
12
+ # TaskLoop::Command.run(["env", "--global-list"])
13
+ # TaskLoop::Command.run(["env", "--import=PATH,RUBY_VERSION,GEM_PATH,GEM_HOME,IRBRC,NOX_ROOT,NOX_HOME,NOX_COMMON,NOX_SCRIPTS,NOX_CONFIG,NOX_TEMPALTES"])
14
+ # TaskLoop::Command.run(["shutdown"])
15
+ # TaskLoop::Command.run(["run"])
16
+ # TaskLoop::Command.run(["deploy"])
@@ -0,0 +1,136 @@
1
+
2
+ module TaskLoop
3
+ class Deploy < Command
4
+ require_relative '../task/task'
5
+ require_relative '../rules/rule'
6
+ require_relative '../rules/interval_rule'
7
+ require_relative '../rules/scope_rule'
8
+ require_relative '../rules/default_rule'
9
+ require_relative '../rules/specific_rule'
10
+ require_relative '../rules/after_scope_rule'
11
+ require_relative '../rules/before_scope_rule'
12
+ require_relative '../rules/between_scope_rule'
13
+ require_relative '../rules/loop_rule'
14
+ require_relative '../rules/date_list_rule'
15
+ require_relative '../rules/time_list_rule'
16
+ require_relative '../extension/string_extension'
17
+ require_relative '../extension/integer_extension'
18
+ require_relative '../dsl/dsl'
19
+ require 'json'
20
+
21
+ include TaskLoop::DSL
22
+
23
+ self.abstract_command = false
24
+
25
+ self.summary = "Deploy a Taskfile into taskloop."
26
+
27
+ self.description = <<-DESC
28
+ The `taskloop deploy` command will deploy a Taskfile into taskloop.
29
+ Taskloop will record the path of a Taskfile into ~/.taskloop/tasklist.json.
30
+ DESC
31
+
32
+ attr_writer :tasklist
33
+
34
+ def tasklist
35
+ @tasklist ||= []
36
+ end
37
+
38
+ def run
39
+ super
40
+ # check if Taskfile exist
41
+ unless File.file?(:Taskfile.to_s)
42
+ puts "Error:".ansi.red
43
+ puts " Taskfile is not exist. Please goto the project's root directory and execute again, or run `taskloop init` command first if current directory is the root directory of a project.".ansi.red
44
+ exit 1
45
+ end
46
+
47
+ register_taskfile_dir_if_needed
48
+ unless deploy_lint?
49
+ puts "Taskfile deploy failed. Please check Taskfile again.".ansi.red
50
+ exit 1
51
+ end
52
+
53
+ generate_taskfile_deploy
54
+
55
+ clean_loopfile_if_needed
56
+ end
57
+
58
+ #################################
59
+ # Register taskfile dir if needed
60
+ #################################
61
+ private def register_taskfile_dir_if_needed
62
+ json_string = File.read(taskloop_proj_list_path)
63
+ parsed_json = JSON.parse(json_string)
64
+ # check if all the registered path
65
+ push_taskfile_dir_if_needed(parsed_json)
66
+ end
67
+
68
+ private def push_taskfile_dir_if_needed(parsed_json)
69
+ proj_dir = Dir.pwd
70
+ duplicate = parsed_json.select { |path| path == proj_dir }
71
+ if duplicate.empty?
72
+ puts "First time to deploy current Taskfile.".ansi.blue
73
+ puts "Register Taskfile into taskloop.".ansi.blue
74
+ parsed_json.push(proj_dir)
75
+
76
+ File.open(taskloop_proj_list_path, 'w') do |file|
77
+ file.write(JSON.pretty_generate(parsed_json))
78
+ end
79
+ end
80
+ end
81
+
82
+ #################################
83
+ # Deploy lint
84
+ #################################
85
+ private def deploy_lint?
86
+ taskfile_path = Dir.pwd + "/Taskfile"
87
+
88
+ eval_taskfile(taskfile_path)
89
+
90
+ results = []
91
+ lint_msgs = []
92
+ for task in TaskLoop::Task::tasklist
93
+ results.push(task.deploy_lint?)
94
+ end
95
+ return !results.include?(false)
96
+ end
97
+
98
+ private def eval_taskfile(path)
99
+ string = File.open(path, 'r:utf-8', &:read)
100
+ if string.respond_to?(:encoding) && string.encoding.name != 'UTF-8'
101
+ string.encode!('UTF-8')
102
+ end
103
+ eval(string)
104
+ rescue Exception => e
105
+ raise TaskfileDeployError, "Error: Taskfile eval failed. Please check Taskfile again. #{e.message}"
106
+ end
107
+
108
+ #################################
109
+ # Generate Taskfile.lock
110
+ #################################
111
+
112
+ private def generate_taskfile_deploy
113
+ data_proj_dir = File.join(taskloop_data_dir, Dir.pwd.sha1_8bit)
114
+ create_dir_if_needed(data_proj_dir)
115
+ deploy_path = File.join(data_proj_dir, ".Taskfile.deploy")
116
+
117
+ FileUtils.copy_file("Taskfile", deploy_path)
118
+ puts DOLPHIN.ansi.blue
119
+ puts " Taskfile deploy success!".ansi.blue
120
+ end
121
+
122
+ #################################
123
+ # Clean loopfile
124
+ #################################
125
+ private def clean_loopfile_if_needed
126
+ data_proj_dir = File.join(taskloop_data_dir, Dir.pwd.sha1_8bit)
127
+ TaskLoop::Task::tasklist.each do |task|
128
+ loopfile_path = File.join(data_proj_dir, task.loopfile_name)
129
+ if File.exists?(loopfile_path)
130
+ File.delete(loopfile_path)
131
+ end
132
+ end
133
+ end
134
+
135
+ end
136
+ end
@@ -0,0 +1,134 @@
1
+ module TaskLoop
2
+ class Env < Command
3
+ self.abstract_command = false
4
+
5
+ self.summary = "To import one or more global environment variables into taskloop."
6
+
7
+ self.description = <<-DESC
8
+ The `taskloop env` command can be used to deal with global environment variable related operations.
9
+ For example, you can export environment variables into taskloop with `--global-export=VAR1,VAR2...` options.
10
+ Beside, you can list all the global environment variables exported in taskloop.
11
+ All above operations are based on ~/.taskloop/environments file. If you want more details about global environment
12
+ variables, check and edit ~/.taskloop/environments by yourself.
13
+ DESC
14
+
15
+ def self.options
16
+ [
17
+ ['--global-import=VAR1,VAR2...', 'Import one or more global environment variables into taskloop.'],
18
+ ["--global-remove=VAR1,VAR2...", 'Remove one or more global environment variables from taskloop.']
19
+ ].concat(super)
20
+ end
21
+
22
+ def initialize(argv)
23
+ @import = argv.option('global-import')
24
+ @remove = argv.option('global-remove')
25
+ super
26
+ end
27
+
28
+ def run
29
+ super
30
+ if @import == nil && @remove == nil
31
+ list_environment_variables
32
+ return
33
+ end
34
+
35
+ if @import
36
+ import_environment_variables
37
+ end
38
+
39
+ if @remove
40
+ remove_environment_variables
41
+ end
42
+ end
43
+
44
+ def validate!
45
+ super
46
+ if @export && @list
47
+ help! "The --global-export option and the --global-list option cannot be used simultaneously."
48
+ end
49
+ if @remove && @list
50
+ help! "The --global-remove option and the --global-list option cannot be used simultaneously."
51
+ end
52
+ end
53
+
54
+ def import_environment_variables
55
+ env_list = @import.split(',')
56
+ unless env_list.length > 0
57
+ puts "Warning: the global environment variables you import is empty. Please check the option arguments again.".ansi.yellow
58
+ return
59
+ end
60
+ env_file = File.open(taskloop_environments_path, "a")
61
+ env_list.each do |var|
62
+ puts "importing #{var} ...".ansi.blue
63
+ puts " #{var}=#{ENV[var]}".ansi.blue
64
+ env_file.puts "export #{var}=#{ENV[var]}"
65
+ end
66
+ puts ""
67
+ puts "import global environment variables complete.".ansi.blue
68
+ env_file.close
69
+ end
70
+
71
+ def remove_environment_variables
72
+ env_list = @remove.split(',')
73
+ unless env_list.length > 0
74
+ puts "Warning: the global environment variables you import is empty. Please check the option arguments again.".ansi.yellow
75
+ return
76
+ end
77
+
78
+ file_content = []
79
+ File.open(taskloop_environments_path, "r") do |file|
80
+ file.each_line do |line|
81
+ name = get_environment_variable_from_line(line)
82
+ unless env_list.include?(name)
83
+ file_content.push(line)
84
+ end
85
+ end
86
+ end
87
+
88
+ File.open(taskloop_environments_path, "w") do |file|
89
+ file_content.each do |line|
90
+ file.puts line
91
+ end
92
+ end
93
+ puts "remove global environment variables complete.".ansi.blue
94
+ end
95
+
96
+ def list_environment_variables
97
+ env_list = {}
98
+ env_file = File.open(taskloop_environments_path, "r")
99
+ pattern = /\Aexport /
100
+ env_file.each_line do |line|
101
+ if line.match(pattern)
102
+ left = line.index(" ")
103
+ right = line.index("=")
104
+ if left && right
105
+ name = line[left+1..right-1]
106
+ value = line[left+1..-1]
107
+ env_list[name] = value
108
+ end
109
+ end
110
+ end
111
+ if env_list.empty?
112
+ puts "Warning: no global environment variable imported in taskloop.".ansi.blue
113
+ return
114
+ end
115
+ puts "There are the global environments variables imported in taskloop:".ansi.blue
116
+ env_list.each do |k, v|
117
+ puts v
118
+ end
119
+ end
120
+
121
+ private def get_environment_variable_from_line(line)
122
+ pattern = /\Aexport /
123
+ result = nil
124
+ if line.match(pattern)
125
+ left = line.index(" ")
126
+ right = line.index("=")
127
+ if left && right
128
+ result = line[left+1..right-1]
129
+ end
130
+ end
131
+ return result
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,42 @@
1
+ module TaskLoop
2
+ class Init < Command
3
+ self.abstract_command = false
4
+
5
+ self.summary = "Setup a project to support taskloop."
6
+
7
+ self.description = <<-DESC
8
+ The `taskloop init` command will create a file named Taskfile in the current directory.
9
+ You can modify Taskfile to customize the execution rules for each scheduled task.
10
+ Attention! You should execute this command in the root directory of your project.
11
+ DESC
12
+
13
+ def run
14
+ super
15
+ # check if Taskfile exist in current directory
16
+ if File.exists?(:Taskfile.to_s)
17
+ puts "Warning: Taskfile exists! There is no need to execute `taskloop init` command in current directory!".ansi.yellow
18
+ puts ""
19
+ return
20
+ end
21
+
22
+ file = File.new(:Taskfile.to_s, "w+")
23
+ content = <<-DESC
24
+ # env to set environment variables which are shared by all tasks defined in the Taskfile. <Optional>
25
+ # env "ENV_NAME", "ENV_VALUE"
26
+
27
+ TaskLoop::Task.new do |t|
28
+ t.name = 'TODO: task name. <Required>'
29
+ t.path = 'TODO: task job path. For exmaple, t.path = "./Job.sh". <Required>'
30
+ t.year = "TODO: year rule. <Optional>"
31
+ t.month = "TODO: month rule. <Optional>"
32
+ t.day = "TODO: day rule. <Optional>"
33
+ t.hour = "TODO: hour rule. <Optional>"
34
+ t.minute = "TODO: minute rule. <Optional>"
35
+ t.loop = "TODO: loop count. <Optional>"
36
+ end
37
+ DESC
38
+ file.puts content
39
+ file.close
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,67 @@
1
+ module TaskLoop
2
+ class Launch < Command
3
+ self.abstract_command = false
4
+
5
+ self.summary = "Launch taskloop in order to run all the tasks which conform their rules."
6
+
7
+ self.description = <<-DESC
8
+ The `taskloop launch` command will register a schedule job into to crontab which is * * * * * sh ~/.tasklooprc.
9
+ Taskloop which check all the tasks every minute. If a task met its rule, execute it.
10
+ DESC
11
+ def run
12
+ super
13
+ create_environments_file_if_needed
14
+ create_tasklooprc_file_if_needed
15
+ register_taskloop_into_crontab_if_needed
16
+ end
17
+
18
+ def create_environments_file_if_needed
19
+ unless File.exists?(taskloop_environments_path)
20
+ env_file = File.new(taskloop_environments_path, "w+")
21
+ variables = ["PATH", "RUBY_VERSION", "GEM_PATH", "GEM_HOME", "IRBRC"]
22
+ variables.each do |var|
23
+ env_file.puts "export " + var + "=#{ENV[var]}"
24
+ end
25
+ env_file.close
26
+ end
27
+ end
28
+
29
+ def create_tasklooprc_file_if_needed
30
+ unless File.exists?(tasklooprc_path)
31
+ rc = File.new(tasklooprc_path, "w+")
32
+ rc.puts "source ~/.taskloop/environments"
33
+ rc.puts "taskloop run > ~/.taskloop/cronlog 2>&1"
34
+ rc.close
35
+ end
36
+ end
37
+
38
+ def register_taskloop_into_crontab_if_needed
39
+ # TODO: @baocq 考虑 crontab 为空的情况
40
+ system("crontab -l > #{taskloop_cron_tab_path}")
41
+ registered = false
42
+ pattern = /\A\* \* \* \* \* sh ~\/\.tasklooprc/
43
+ File.open(taskloop_cron_tab_path, "r").each_line do |line|
44
+ if line.match?(pattern)
45
+ registered = true
46
+ break
47
+ end
48
+ end
49
+
50
+ if registered
51
+ puts "Warning: taskloop has already launched. Please do not launch again.".ansi.yellow
52
+ puts " If your want to shutdown taskloop, please execute the `taskloop shutdown` command.".ansi.yellow
53
+ return
54
+ end
55
+
56
+ File.open(taskloop_cron_tab_path, "a") do |file|
57
+ file.puts "* * * * * sh ~/.tasklooprc"
58
+ end
59
+
60
+ system("crontab #{taskloop_cron_tab_path}")
61
+
62
+ puts LOGO.ansi.blue
63
+ puts " taskloop has launched successfully. ".ansi.blue
64
+ puts ""
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,59 @@
1
+ require_relative '../utils/proj_tasklist'
2
+ require_relative '../dsl/dsl'
3
+
4
+ module TaskLoop
5
+ class List < Command
6
+ include TaskLoop::DSL
7
+ include TaskLoop::ProjTaskList
8
+
9
+ self.abstract_command = false
10
+
11
+ self.summary = "List current running tasks in taskloop."
12
+
13
+ self.description = <<-DESC
14
+ The 'taskloop list' command will list all the running tasks in taskloop.
15
+ DESC
16
+
17
+ attr_reader :proj_tasklist_map
18
+
19
+ def proj_tasklist_map
20
+ @proj_tasklist_map ||= {}
21
+ end
22
+
23
+ def run
24
+ super
25
+ create_data_proj_dir_if_needed
26
+ create_data_proj_description_if_needed
27
+
28
+ construct_proj_tasklist_map
29
+ setup_task_property
30
+
31
+ show_proj_tasklist_info
32
+ end
33
+
34
+ def show_proj_tasklist_info
35
+ unless @proj_tasklist_map != nil && !@proj_tasklist_map.empty?
36
+ puts "Warning: there is no task in taskloop.".ansi.yellow
37
+ return
38
+ end
39
+ @proj_tasklist_map.each do |proj, list|
40
+ unless list.length > 0
41
+ next
42
+ end
43
+ puts "=============================".ansi.blue
44
+ puts "Tasks above are defined in Taskfile of <#{proj}>".ansi.blue
45
+ list.each do |task|
46
+ puts " #{task.desc}".ansi.blue
47
+ puts " t.name = #{task.name}".ansi.blue
48
+ puts " t.path = #{task.path}".ansi.blue
49
+ puts " t.year = #{task.year.desc}".ansi.blue
50
+ puts " t.month = #{task.month.desc}".ansi.blue
51
+ puts " t.day = #{task.day.desc}".ansi.blue
52
+ puts " t.hour = #{task.hour.desc}".ansi.blue
53
+ puts " t.minute = #{task.minute.desc}".ansi.blue
54
+ puts " t.loop = #{task.loop.desc}".ansi.blue
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end