taskloop 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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