systemdy 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: abda4b02a15b8b3dcf89cc3c92fe53027b67708cf07b37b0274f51f11d1e0e07
4
- data.tar.gz: 94edeaca38a67b73676e7301f23bcdc25e87da29dce75d4584c36adc3a3f04d0
3
+ metadata.gz: 3295c50515809b73fe45a95f7d9a515e06bc228595f32d8001794d234de5f9cb
4
+ data.tar.gz: 2df557021563e4b76767652b0d23c0cdf6fba1bc161c568f15ec959f273edb83
5
5
  SHA512:
6
- metadata.gz: 30eda44f1659af67b18de78cb20be466f0986220e4a40963b83bbbc3422dad3a3809dc2f9f94a26bca7f236890ee4e0c682c66edb548d4a280c31a3ad2090f7c
7
- data.tar.gz: 868bac0eb61ea2bb42fe849e421fad778d3fc6605f0a43f5c054fd9ac3870674662e19895cc3cfc97980b09e0ed59a5c770551106c3f8f87295bcb43866a6295
6
+ metadata.gz: e57fab1a933d002e1c4328215f65b634656657a7e24e305b572d784515d4611140d28c1ade509d8507864db44a1503f16f0c4abbbe99c3b27f46481e685eeed7
7
+ data.tar.gz: 1d9c0958c693c7bd6d0d7b02c36549ec3317f646773c2d07478844de7d91553aeba867b97f6dd48300488ca0e4819946dc6cd42ce9f4f0e3f43064442837206f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,141 @@
1
- ## [Unreleased]
1
+ ## [0.2.0] - 2022-10-10
2
+
3
+ ### Added
4
+
5
+ - Yard documentation of all gem's modules, classes, constants and methods(included methods generated with metaprogramming techniques)
6
+
7
+ ## [0.1.0] - 2022-10-07
8
+
9
+ ### Added
10
+
11
+ - Yard-like comments for documentation of the remained gem's classes, constants and modules
12
+ - Yard-like comments for documentation of private methods
13
+
14
+ ### Changed
15
+
16
+ - Changed markdown README.md structure for yard documentation
17
+
18
+ ## [0.1.0] - 2022-10-06
19
+
20
+ ### Changed
21
+
22
+ - URL image path on README.md for proper yard documentation
23
+ - Comments in Systemdy::Utility::Validator class with a yard-like syntax for generate documentation
24
+ - Comments in Systemdy::Service with a yard-like syntax for generate documentation
25
+
26
+ ## [0.1.0] - 2022-10-05
27
+
28
+ ### Changed
29
+
30
+ - Systemdy::Utility::Formatter comment section to yard-like syntax for generating documentation
31
+ - Variable name sudo_command to sudo in Systemdy::Service class
32
+ - Logic for the Systemdy::Utility::KeyValueFilter.filter_by_keys class method
33
+
34
+ ### Added
35
+
36
+ - Yard-style comments for the Systemdy::Utility::Validator.check_if_a_service_exist class method
37
+ - Yard-style comments for the Systemdy::Utility::MessageDisplayer.display_message class method
38
+ - Yard-style comments for the Systemdy::Utility::KeyValueFilter.filter_by_keys class method
39
+
40
+ ### Fixed
41
+
42
+ - Yard params description in Systemdy::Utility::Formatter class
43
+
44
+ ## [0.1.0] - 2022-10-04
45
+
46
+ ### Changed
47
+
48
+ - README.md for load image logo
49
+
50
+ ### Added
51
+
52
+ - Image logo
53
+
54
+ ## [0.1.0] - 2022-10-03
55
+
56
+ ### Changed
57
+
58
+ - Gem name from Systemd to Systemdy to avoid name conflicts with other rubygems with the same namespace
59
+
60
+ ### Added
61
+
62
+ - Badges in README.md for render essential metadata of the project
63
+
64
+ ## [0.1.0] - 2022-09-29
65
+
66
+ ### Changed
67
+
68
+ - Status method of Systemd::Service class
69
+ - Systemd::Utility::Validator.check_if_a_service_exist class method
70
+
71
+ ### Added
72
+
73
+ - Systemd::Utility::KeyValueFilter.filter_by_keys class method
74
+ - Systemd::Utility::KeyValueFilter class for filter hash with provided keys
75
+
76
+ ## [0.1.0] - 2022-09-28
77
+
78
+ ### Changed
79
+
80
+ - Moved render_message method from Systemd::Utility::Validator class to Systemd::Utility::MessageDisplayer class
81
+
82
+ ### Added
83
+
84
+ - Custom exception for Systemd::Utility::Formatter.return_an_array_from_system_command class method
85
+ - Systemd::Utility::Formatter return_an_array_from_system_command class method
86
+ - Systemd::Utility::Formatter class
87
+ - Systemd::Utility::MessageDisplayer class with render_message class method
88
+
89
+ ## [0.1.0] - 2022-09-25
90
+
91
+ ### Added
92
+
93
+ - Custom test variables to TestVariables module in spec/setup/test_variables.rb with test refactor
94
+ - TestSetup module in spech_helper for share spec's variables
95
+
96
+ ## [0.1.0] - 2022-09-23
97
+
98
+ ### Changed
99
+
100
+ - Systemd::Utility::Validator.exist? method with forwardable module for delegation pattern
101
+
102
+ ## [0.1.0] - 2022-09-22
103
+
104
+ ### Changed
105
+
106
+ - Removed Systemd::Journal::Unit class in favour of a universal api design
107
+
108
+ ## [0.1.0] - 2022-09-19
109
+
110
+ ### Changed
111
+
112
+ - Methods is_active? and is_enabled? for return a boolean value instead of a string
113
+
114
+ ### Added
115
+
116
+ - Systemd::Journal::Unit.display_logs method for manage journalctl units
117
+ - Systemd::Journal::Unit class
118
+
119
+ ## [0.1.0] - 2022-09-18
120
+
121
+ ### Added
122
+
123
+ - Methods mask and unmask to the Systemd::Service class
124
+ - Methods is_enabled? and is_active? and rspec tests the Systemd::Service class for check if a service is enabled or active
125
+
126
+ ## [0.1.0] - 2022-09-17
127
+
128
+ ### Changed
129
+
130
+ - Values of gemspec code_of_conduct and changelog url paths
131
+
132
+ ### Added
133
+
134
+ - Founded attribute to Systemd::Service class to mark a provided service if is found or not on the system
135
+ - Method exist? for check if a service exist
136
+ - Method status to Systemd::Service class with rspec test
137
+ - Actions method for execute different actions on a systemd service
2
138
 
3
139
  ## [0.1.0] - 2022-09-15
4
140
 
5
- - Initial release
141
+ - Initial release
data/README.md CHANGED
@@ -1,16 +1,15 @@
1
- # Systemd
1
+ <img src="https://raw.githubusercontent.com/magic4dev/systemdy/master/systemdy.png" width="1012px" alt="Systemdy Logo">
2
2
 
3
- <div align="center">
4
-
5
- ![GitHub repo size](https://img.shields.io/github/repo-size/magic4dev/systemdy?label=size&style=flat-square)
6
- [![GitHub issues](https://img.shields.io/github/issues/magic4dev/systemdy?style=flat-square)](https://github.com/magic4dev/systemdy/issues)
3
+ ![Gem](https://img.shields.io/gem/v/systemdy?style=flat-square)
4
+ ![Gem](https://img.shields.io/gem/dt/systemdy?style=flat-square)
7
5
  [![GitHub forks](https://img.shields.io/github/forks/magic4dev/systemdy?style=flat-square)](https://github.com/magic4dev/systemdy/network)
6
+ [![GitHub issues](https://img.shields.io/github/issues/magic4dev/systemdy?style=flat-square)](https://github.com/magic4dev/systemdy/issues)
8
7
  [![GitHub license](https://img.shields.io/github/license/magic4dev/systemdy?style=flat-square)](https://github.com/magic4dev/systemdy/blob/master/LICENSE.txt)
9
8
  [![GitHub stars](https://img.shields.io/github/stars/magic4dev/systemdy?style=flat-square)](https://github.com/magic4dev/systemdy/stargazers)
10
9
 
11
- </div>
10
+ # Systemdy
12
11
 
13
- A lightweight gem for interact with systemd.
12
+ A lightweight gem for interact with Systemd.
14
13
 
15
14
  If your goal is to develop software to quickly manage systemd services or journalctl logs, this gem is for you! :grin:
16
15
 
@@ -19,7 +18,7 @@ If your goal is to develop software to quickly manage systemd services or journa
19
18
 
20
19
  - Lightweight
21
20
  - Expressive classes and methods
22
- - Manage systemd's services lifecycle with minimal effort!
21
+ - Manage Systemd's services lifecycle with minimal effort!
23
22
  - Extract and manipulate Journalctl logs with a single action!
24
23
 
25
24
  ## Table of contents
@@ -55,6 +54,7 @@ If your goal is to develop software to quickly manage systemd services or journa
55
54
  * [License](#license)
56
55
  * [Useful links and resources](#useful-links-and-resources)
57
56
  * [Acknowledgements](#acknowledgements)
57
+
58
58
  ## Installation
59
59
 
60
60
  Add this line to your application's Gemfile:
@@ -72,7 +72,7 @@ Or install it yourself as:
72
72
  $ gem install systemdy
73
73
  ## Dependencies
74
74
 
75
- The only dependecy you need is [systemd](http://www.freedesktop.org/wiki/Software/systemdy/) installed on your system (specifically libsystemd or the older libsystemdy-journal) in order to use the gem. Currently the gem support systemd 249 or higher.
75
+ The only dependecy you need is [systemd](http://www.freedesktop.org/wiki/Software/systemdy/) installed on your system (specifically libsystemd or the older libsystemd-journal) in order to use the gem. Currently the gem support systemd 249 or higher.
76
76
  ## Usage
77
77
 
78
78
  After installing the gem, the first step is to require it:
@@ -84,11 +84,11 @@ require 'systemdy'
84
84
 
85
85
  The first goal of this gem is to manage a systemd's service with minimal effort.
86
86
 
87
- This section provides an overview of the Systemdy::Service class for managing the life cycle of a systemdy's service.
87
+ This section provides an overview of the Systemdy::Service class for managing the life cycle of a systemd's service.
88
88
 
89
89
  ### Create a Systemdy Service object for control a service
90
90
 
91
- The first step is to create a new instance of the systemdy::Service class for control the desired service
91
+ The first step is to create a new instance of the Systemdy::Service class for control the desired service
92
92
 
93
93
  ```ruby
94
94
  my_postgresql_service = Systemdy::Service.new('postgresql')
@@ -260,6 +260,8 @@ This line anable you to run ‘systemctl’ commands without a password.
260
260
 
261
261
  Save with CTRL + X
262
262
 
263
+ Type 'exit' on your terminal as follows:
264
+
263
265
  ```console
264
266
  root@my-machine:~# exit
265
267
  ```
@@ -388,7 +390,7 @@ Obviously this method require the unit's name as argument, if executed with no a
388
390
  "display_unit_logs require an argument!"
389
391
  ```
390
392
 
391
- Obviously as for the previous method, you can filter the unit logs by passing **4** positional arguments:
393
+ As for the previous method, you can filter the unit logs by passing **4** positional arguments:
392
394
 
393
395
  * **argument**: in this case the unit's name
394
396
 
@@ -443,7 +445,7 @@ Obviously this method require the GUID as argument, if executed with no argument
443
445
  "display_group_id_logs require an argument!"
444
446
  ```
445
447
 
446
- Obviously as for the previous method, you can filter the GUID logs by passing **4** positional arguments:
448
+ As for the previous method, you can filter the GUID logs by passing **4** positional arguments:
447
449
 
448
450
  * **argument**: in this case the GUID
449
451
 
@@ -498,7 +500,7 @@ Obviously this method require the UID as argument, if executed with no arguments
498
500
  "display_user_id_logs require an argument!"
499
501
  ```
500
502
 
501
- Obviously as for the previous method, you can filter the UID logs by passing **4** positional arguments:
503
+ As for the previous method, you can filter the UID logs by passing **4** positional arguments:
502
504
 
503
505
  * **argument**: in this case the UID
504
506
 
@@ -537,7 +539,7 @@ If the passed arguments not match anything the method return an array with a mes
537
539
 
538
540
  We :heart: pull requests from everyone.
539
541
 
540
- Everyone interacting in the systemdy project's codebases is expected to follow the [code of conduct](https://github.com/magic4dev/systemdy/blob/master/CODE_OF_CONDUCT.md).
542
+ Everyone interacting in the systemdy's project codebase is expected to follow the [code of conduct](https://github.com/magic4dev/systemdy/blob/master/CODE_OF_CONDUCT.md).
541
543
 
542
544
  ### Develop a new feature
543
545
 
@@ -566,9 +568,8 @@ If you wanna develop a new feature:
566
568
  * Write a good commit message
567
569
  * Push to your fork
568
570
  * [Submit a pull request](https://github.com/magic4dev/systemdy/compare)
569
- * Wait for us, we will reply as soon as possible
570
- * We may suggest changes for better code quality
571
- * Please, if you push more than mone commit let's keep the history clean :stuck_out_tongue_winking_eye:
571
+ * Wait for us, we will reply as soon as possible and if is the case we suggest some changes for a better quality of the code
572
+ * Please, if you push more than one commit let's keep the history clean :stuck_out_tongue_winking_eye:
572
573
 
573
574
  Thank you for your contribution! :handshake:
574
575
 
@@ -599,9 +600,8 @@ If you wanna fix a bug:
599
600
  * Write a good commit message
600
601
  * Push to your fork
601
602
  * [Submit a pull request](https://github.com/magic4dev/systemdy/compare)
602
- * Wait for us, we will reply as soon as possible
603
- * We may suggest changes for better code quality
604
- * Please, if you push more than mone commit let's keep the history clean :stuck_out_tongue_winking_eye:
603
+ * Wait for us, we will reply as soon as possible and if is the case we suggest some changes for a better quality of the code
604
+ * Please, if you push more than one commit let's keep the history clean :stuck_out_tongue_winking_eye:
605
605
 
606
606
  Thank you for your contribution! :handshake:
607
607
 
@@ -619,9 +619,9 @@ and replace:
619
619
 
620
620
  * let (:real_service_name) { 'postgresql' }
621
621
 
622
- with:
622
+ with a service already installed on your system as follows:
623
623
 
624
- * let (:real_service_name) { 'a_installed_service_on_your_system' }
624
+ * let (:real_service_name) { 'a_service_already_installed_on_your_system' }
625
625
 
626
626
  ## License
627
627
 
@@ -630,7 +630,7 @@ The gem is available as open source under the terms of the [MIT License](https:/
630
630
  ## Useful links and resources
631
631
 
632
632
  - An interesting article on [how to run sudo commands without password](https://www.linuxshelltips.com/run-sudo-commands-without-password/)
633
- - The official systemdy documentation for [time specification](https://www.freedesktop.org/software/systemd/man/systemd.time.html)
633
+ - The official Systemd documentation for [time specification](https://www.freedesktop.org/software/systemd/man/systemd.time.html)
634
634
 
635
635
  ## Acknowledgements
636
636
 
@@ -1,29 +1,20 @@
1
1
  module Systemdy
2
+ # Allows to filter journalctl logs
2
3
  class Journal
3
4
 
4
5
  # extend SingleForwardableForwardable standard's library module for delegate a specified method to a designated object
5
6
  extend SingleForwardable
6
7
 
7
8
  # list of options for execute journalctl command that not accept arguments
8
- # Example command: journalctl -k
9
- # the '-k' option not accept arguments
10
- # journalctl -k [argument] return
11
- # Failed to add match [argument]: Invalid argument
9
+ # @note The meaning of this constant is that in linux the command ``` journalctl -k ``` not accept arguments
12
10
  LIST_OF_OPTIONS_THAT_NOT_ACCEPT_ARGUMENTS = { kernel: '-k' }
13
11
 
14
12
  # list of options for execute journalctl command that accept arguments
15
- # Example command: journalctl -b
16
- # the '-b' option accept an argument (the number of the boot)
17
- # journalctl -b postgresql return the boots's logs
18
- # journalctl -b 3 return the third of the availables boot logs
13
+ # @note The meaning of this constant is that in linux the command ``` journalctl -b ``` can accept arguments, if executed without argument return the last boot logs
19
14
  LIST_OF_OPTIONS_THAT_ACCEPT_AN_ARGUMENT = { boot: '-b' }
20
15
 
21
16
  # list of options for execute journalctl command that require arguments
22
- # Example command: journalctl -u
23
- # the '-u' option require an argument (the name of the unit)
24
- # journalctl -u postgresql return the postgresql's logs
25
- # journalctl -u without an argument return
26
- # journalctl: option requires an argument -- 'u'
17
+ # @note The meaning of this constant is that in linux the command like ``` journalctl -u ``` require arguments, if executed without argument return an error
27
18
  LIST_OF_OPTIONS_THAT_REQUIRE_AN_ARGUMENT = { unit: '-u', group_id: '_GID', user_id: '_UID' }
28
19
 
29
20
  # we delegate return_an_array_from_system_command method to Systemdy::Utility::Formatter class contained in Systemdy/utility/formatter.rb
@@ -31,19 +22,24 @@ module Systemdy
31
22
  # we delegate render_message method to Systemdy::Utility::MessageDisplayer class contained in Systemdy/utility/message_displayer.rb
32
23
  def_delegator Systemdy::Utility::MessageDisplayer, :render_message
33
24
 
34
- # create dynamically class methods based on LIST_OF_OPTIONS_THAT_NOT_ACCEPT_ARGUMENTS constant
35
- # we can call the methods:
36
- # Systemdy::Journal.display_kernel_logs
37
- # this method accept 3 keyword arguments:
38
- # 1. since ('the log's initial period') - String - default 'yesterday'
39
- # 2. to ('the log's end period') - String - default Time.now.strftime('%H:%M')
40
- # 3. lines ('the log's number of lines') - Integer - default 10 .display_kernel_logs
41
- # Example:
42
- # Systemdy::Journal.display_kernel_logs(since: '1 month ago', lines: 50)
43
- # if you call this method without arguments
44
- # - it return an array with 10 lines of logs
45
- LIST_OF_OPTIONS_THAT_NOT_ACCEPT_ARGUMENTS.each do |message_from, option|
46
- define_singleton_method "display_#{message_from}_logs" do |since: 'today', to: Time.now.strftime('%H:%M'), lines: 10|
25
+ # create dynamically methods based on LIST_OF_OPTIONS_THAT_NOT_ACCEPT_ARGUMENTS constant
26
+ # @!scope class
27
+ # @!method display_kernel_logs
28
+ # display the +kernel logs+
29
+ # @param since [String] the log's initial period - **default**: +today+
30
+ # @param to [String] the log's end period - **default**: +timenow+
31
+ # @param lines [Integer] the log's number of lines - **default**: +10+
32
+ # @return [Array] a list of kernel logs
33
+ # @example display the last 10 lines of kernel logs since today to the time execution method
34
+ # Systemdy::Journal.display_kernel_logs #=> [...]
35
+ # @example display the last the last 20 log lines ranging from a week ago to yesterday
36
+ # Systemdy::Journal.display_kernel_logs(since: '1 week ago', to: 'yesterday', lines: 20) #=> [...]
37
+ # @example You can also filter the logs by specific dates in the format 'YYYY-MM-DD'
38
+ # Systemdy::Journal.display_kernel_logs(since: '2022-08-27', lines: 200) #=> [...]
39
+ # @note This method is generated with use of metaprogramming techniques
40
+ #
41
+ LIST_OF_OPTIONS_THAT_NOT_ACCEPT_ARGUMENTS.each do |from, option|
42
+ define_singleton_method "display_#{from}_logs" do |since: 'today', to: Time.now.strftime('%H:%M'), lines: 10|
47
43
  # logs from system call
48
44
  logs = `#{JOURNALCTL_COMMAND} #{option} -S '#{since}' -U '#{to}' -n #{lines} | tail -n #{lines} 2>&1`
49
45
  # logs from system call converted into array
@@ -51,20 +47,27 @@ module Systemdy
51
47
  end
52
48
  end
53
49
 
54
- # create dynamically class methods based on LIST_OF_OPTIONS_THAT_ACCEPT_AN_ARGUMENT constant
55
- # we can call the methods:
56
- # Systemdy::Journal.display_boot_logs
57
- # this method accept 4 keyword arguments:
58
- # 1. argument ('the boot's number') - Integer - optional
59
- # 2. since ('the log's initial period') - String - default 'yesterday'
60
- # 3. to ('the log's end period') - String - default Time.now.strftime('%H:%M')
61
- # 4. lines ('the log's number of lines') - Integer - default 10
62
- # Example:
63
- # Systemdy::Journal.display_boot_logs(argument: 3, since: '1 month ago', lines: 50)
64
- # if you call this method without arguments
65
- # - it return an array with 10 lines of logs
66
- LIST_OF_OPTIONS_THAT_ACCEPT_AN_ARGUMENT.each do |message_from, option|
67
- define_singleton_method "display_#{message_from}_logs" do |argument: '', since: 'today', to: Time.now.strftime('%H:%M'), lines: 10|
50
+ # create dynamically methods based on LIST_OF_OPTIONS_THAT_ACCEPT_AN_ARGUMENT constant
51
+ # @!scope class
52
+ # @!method display_boot_logs
53
+ # display the +boot logs+
54
+ # @param argument [Integer] the boot number
55
+ # @param since [String] the log's initial period - **default**: +today+
56
+ # @param to [String] the log's end period - **default**: +timenow+
57
+ # @param lines [Integer] the log's number of lines - **default**: +10+
58
+ # @return [Array] a list of boot logs
59
+ # @example display the last 10 lines of kernel logs since today to the time execution method
60
+ # Systemdy::Journal.display_boot_logs #=> [...]
61
+ # @example display the last 50 log lines of the second boot ranging from a month ago to 10:00 of the current day
62
+ # Systemdy::Journal.display_boot_logs(argument: 2, since: '1 month ago', to: '10:00', lines: 50) #=> [...]
63
+ # @example display the last 20 log of the third boot lines ranging from a week ago to yesterday
64
+ # Systemdy::Journal.display_boot_logs(argument: 3, since: '1 week ago', to: 'yesterday', lines: 20) #=> [...]
65
+ # @example You can also filter the logs by specific dates in the format 'YYYY-MM-DD'
66
+ # Systemdy::Journal.display_boot_logs(since: '2022-08-27', lines: 200) #=> [...]
67
+ # @note This method is generated with use of metaprogramming techniques
68
+ #
69
+ LIST_OF_OPTIONS_THAT_ACCEPT_AN_ARGUMENT.each do |from, option|
70
+ define_singleton_method "display_#{from}_logs" do |argument: '', since: 'today', to: Time.now.strftime('%H:%M'), lines: 10|
68
71
  # logs from system call
69
72
  logs = `#{JOURNALCTL_COMMAND} #{option} #{argument} -S '#{since}' -U '#{to}' -n #{lines} | tail -n #{lines} 2>&1`
70
73
  # logs from system call converted into array
@@ -73,27 +76,63 @@ module Systemdy
73
76
  end
74
77
 
75
78
  # create dynamically class methods based on LIST_OF_OPTIONS_THAT_REQUIRE_AN_ARGUMENT constant
76
- # we can call the methods:
77
- # Systemdy::Journal.display_unit_logs
78
- # Systemdy::Journal.display_group_id_logs
79
- # Systemdy::Journal.display_user_id_logs
80
- # this method accept 4 keyword arguments:
81
- # 1. argument ('the unit, the group_id or user_id) - String - required
82
- # 2. since ('the log's initial period') - String - default 'yesterday'
83
- # 3. to ('the log's end period') - String - default Time.now.strftime('%H:%M')
84
- # 4. lines ('the log's number of lines') - Integer - default 10
85
- # Example:
86
- # Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '1 month ago', lines: 50)
87
- # Systemdy::Journal.display_user_id_logs(argument: 1000, since: '1 month ago', lines: 50)
88
- # Systemdy::Journal.display_group_id_logs(argument: 1000, since: '1 month ago', lines: 50)
89
- LIST_OF_OPTIONS_THAT_REQUIRE_AN_ARGUMENT.each do |message_from, option|
90
- define_singleton_method "display_#{message_from}_logs" do |argument: '', since: 'today', to: Time.now.strftime('%H:%M'), lines: 10|
79
+ # @!scope class
80
+ # @!method display_unit_logs
81
+ # display the +unit logs+
82
+ # @param argument [string] the unit name
83
+ # @param since [String] the log's initial period - **default**: +today+
84
+ # @param to [String] the log's end period - **default**: +timenow+
85
+ # @param lines [Integer] the log's number of lines - **default**: +10+
86
+ # @return [Array] a list of unit logs
87
+ # @example display the last 50 log lines of the potsgresql service ranging from a month ago to 10:00 of the current day
88
+ # Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '1 month ago', to: '10:00', lines: 50) #=> [...]
89
+ # @example display the last 20 log lines of the potsgresql service ranging from a week ago to yesterday
90
+ # Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '1 week ago', to: 'yesterday', lines: 20) #=> [...]
91
+ # @example You can also filter the logs by specific dates in the format 'YYYY-MM-DD'
92
+ # Systemdy::Journal.display_unit_logs(argument: 'postgresql', since: '2022-08-27', lines: 200) #=> [...]
93
+ # @note This method is generated with use of metaprogramming techniques
94
+ # @todo This method require the unit name as argument. For more information check out the examples below
95
+ #
96
+ # @!method display_group_id_logs
97
+ # display the +group_id logs (GUID)+
98
+ # @param argument [Integer] the group id
99
+ # @param since [String] the log's initial period - **default**: +today+
100
+ # @param to [String] the log's end period - **default**: +timenow+
101
+ # @param lines [Integer] the log's number of lines - **default**: +10+
102
+ # @return [Array] a list of group id logs
103
+ # @example display the last 50 log lines of the GUID 1000 ranging from a month ago to 10:00 of the current day
104
+ # Systemdy::Journal.display_group_id_logs(argument: 1000, since: '1 month ago', to: '10:00', lines: 50) #=> [...]
105
+ # @example display the last 20 log lines of the GUID 1000 ranging from a week ago to yesterday
106
+ # Systemdy::Journal.display_group_id_logs(argument: 1000, since: '1 week ago', to: 'yesterday', lines: 20) #=> [...]
107
+ # @example You can also filter the logs by specific dates in the format 'YYYY-MM-DD'
108
+ # Systemdy::Journal.display_group_id_logs(argument: 1000, since: '2022-08-27', lines: 200) #=> [...]
109
+ # @note This method is generated with use of metaprogramming techniques
110
+ # @todo This method require the GUID as argument. For more information check out the examples below
111
+ #
112
+ # @!method display_user_id_logs
113
+ # display the +user_id logs (UID)+
114
+ # @param argument [Integer] the user id
115
+ # @param since [String] the log's initial period - **default**: +today+
116
+ # @param to [String] the log's end period - **default**: +timenow+
117
+ # @param lines [Integer] the log's number of lines - **default**: +10+
118
+ # @return [Array] a list of user id logs
119
+ # @example display the last 50 log lines of the UID 1000 ranging from a month ago to 10:00 of the current day
120
+ # Systemdy::Journal.display_user_id_logs(argument: 1000, since: '1 month ago', to: '10:00', lines: 50) #=> [...]
121
+ # @example display the last 20 log lines of the UID 1000 ranging from a week ago to yesterday
122
+ # Systemdy::Journal.display_user_id_logs(argument: 1000, since: '1 week ago', to: 'yesterday', lines: 20) #=> [...]
123
+ # @example You can also filter the logs by specific dates in the format 'YYYY-MM-DD'
124
+ # Systemdy::Journal.display_user_id_logs(argument: 1000, since: '2022-08-27', lines: 200) #=> [...]
125
+ # @note This method is generated with use of metaprogramming techniques
126
+ # @todo This method require the UID as argument. For more information check out the examples below
127
+ #
128
+ LIST_OF_OPTIONS_THAT_REQUIRE_AN_ARGUMENT.each do |from, option|
129
+ define_singleton_method "display_#{from}_logs" do |argument: '', since: 'today', to: Time.now.strftime('%H:%M'), lines: 10|
91
130
  # return an error message if the required argument is not provided
92
131
  # render_message class method contained in Systemdy/utility/message_displayer.rb
93
- return render_message("display_#{message_from}_logs require an argument!") if argument.to_s.empty?
132
+ return render_message("display_#{from}_logs require an argument!") if argument.to_s.empty?
94
133
  # combination of option and argument based on typology
95
134
  # '-u postgresql' or '_GUID=1000' or '_UID=1000'
96
- option_with_argument = merge_option_with_argument_based_on_option_typology(message_from, option, argument)
135
+ option_with_argument = merge_option_with_argument_based_on_option_typology(from, option, argument)
97
136
  # logs from system call
98
137
  logs = `#{JOURNALCTL_COMMAND} #{option_with_argument} -S '#{since}' -U '#{to}' | tail -n #{lines} 2>&1`
99
138
  # logs from system call converted into array
@@ -101,12 +140,31 @@ module Systemdy
101
140
  end
102
141
  end
103
142
 
143
+ # @!scope class
144
+ # @!method return_an_array_from_system_command
145
+ # @param system_call [String] system call to convert to an array
146
+ # @return [Array] an array-based list of the values ​​returned by making a system call
147
+ # @note check out more about this method in Systemdy/utility/formatter.rb
148
+ #
149
+ # @!scope class
150
+ # @!method render_message
151
+ # @param message [String] the message to render
152
+ # @return [String] the content of the message
153
+ # @note check out more about this method in Systemdy/utility/message_displayer.rb
154
+ #
155
+
104
156
  # method for return formatted option
105
- # Example
106
- # merge_option_with_argument_based_on_option_typology(:unit, '-u', 'postgresql') return '-u postgresql'
107
- # merge_option_with_argument_based_on_option_typology(:group_id, '_GUID', 1234566) return '_GUID=1000'
108
- def self.merge_option_with_argument_based_on_option_typology(message_from, option, argument)
109
- message_from == :unit ? "#{option} #{argument}" : "#{option}=#{argument}"
157
+ #
158
+ # @param type [String] the type of command to bind
159
+ # @param option [String] the option
160
+ # @param argument [String] the argument
161
+ # @return [String] the formatted option
162
+ # @example return formatted option
163
+ # merge_option_with_argument_based_on_option_typology(:unit, '-u', 'postgresql') #=> '-u postgresql'
164
+ # merge_option_with_argument_based_on_option_typology(:group_id, '_GUID', 1000) #=> '_GUID=1000'
165
+ # merge_option_with_argument_based_on_option_typology(:user_id, '_UID', 1000) #=> '_UID=1000'
166
+ def self.merge_option_with_argument_based_on_option_typology(type, option, argument)
167
+ type == :unit ? "#{option} #{argument}" : "#{option}=#{argument}"
110
168
  end
111
169
 
112
170
  # make the methods below as private
@@ -1,6 +1,9 @@
1
1
  module Systemdy
2
+ # Allows to control a life-cycle of a systemd's service
3
+ # @attr_reader command [String] the default 'systemctl' command
4
+ # @attr_reader name [String] the name of the service
2
5
  class Service
3
-
6
+
4
7
  # extend Forwardable standard's library module for delegate a specified method to a designated object
5
8
  extend Forwardable
6
9
 
@@ -18,104 +21,174 @@ module Systemdy
18
21
 
19
22
  attr_reader :command, :name
20
23
 
21
- # we create a new object that accept 1 argument:
22
- # 1. the name of the Systemdy service to control (postgresql, redis etc..)
23
- # Example:
24
- # my_postgresql_service = Systemdy::Service.new('postgresql')
24
+ # method for create a new Systemdy::Service object
25
+ #
26
+ # @param name [String] the name of the systemd service to control
27
+ # @return [Systemdy::Service] a new Systemdy::Service object
28
+ # @example Create an object
29
+ # my_postgresql_service = Systemdy::Service.new('postgresql')
25
30
  def initialize(name)
26
31
  @command = SYSTEMCTL_COMMAND # constant contained in Systemdy.rb
27
32
  @name = name
28
33
  end
29
34
 
30
- # we delegate return_an_array_from_system_command method to Systemdy::Utility::Formatter class contained in Systemdy/utility/formatter.rb
35
+ # delegate return_an_array_from_system_command method to Systemdy::Utility::Formatter class contained in Systemdy/utility/formatter.rb
31
36
  def_delegator Systemdy::Utility::Formatter, :return_an_array_from_system_command
32
- # we delegate render_message method to Systemdy::Utility::MessageDisplayer class contained in Systemdy/utility/message_displayer.rb
37
+ # delegate render_message method to Systemdy::Utility::MessageDisplayer class contained in Systemdy/utility/message_displayer.rb
33
38
  def_delegator Systemdy::Utility::MessageDisplayer, :render_message
34
- # we delegate check_if_a_service_exist method to Systemdy::Utility::Validator class contained in Systemdy/utility/validator.rb
39
+ # delegate check_if_a_service_exist method to Systemdy::Utility::Validator class contained in Systemdy/utility/validator.rb
35
40
  def_delegator Systemdy::Utility::Validator, :check_if_a_service_exist
36
- # we delegate filter_by_keys method to Systemdy::Utility::KeyValueFilter class contained in Systemdy/utility/key_value.rb
41
+ # delegate filter_by_keys method to Systemdy::Utility::KeyValueFilter class contained in Systemdy/utility/key_value.rb
37
42
  def_delegator Systemdy::Utility::KeyValueFilter, :filter_by_keys
38
43
 
39
- # method for check if a created service exist
40
- # Example:
41
- # my_postgresql_service.exist?
42
- # if the provided service exist this method return
43
- # - true
44
- # otherwise return
45
- # - false
44
+ # method for check if a created service +exist+
45
+ #
46
+ # @return [Boolean] the presence of the service on the system
47
+ # @example Create an object
48
+ # my_postgresql_service.exist? #=> true
46
49
  def exist?
47
50
  check_if_a_service_exist(name) # class method contained in Systemdy/utility/validator.rb
48
51
  end
49
52
 
50
53
  # create dynamically methods based on LIST_OF_ACTIONS constant
51
- # after created a new object we can call the methods:
52
- # my_postgresql_service.start
53
- # my_postgresql_service.restart
54
- # my_postgresql_service.stop
55
- # my_postgresql_service.enable
56
- # my_postgresql_service.disable
57
- # my_postgresql_service.reload
58
- # my_postgresql_service.mask
59
- # my_postgresql_service.unmask
54
+ # @!method start
55
+ # execute action +start+ on the service
56
+ # @example start a service
57
+ # my_postgresql_service.start
58
+ # @note This method is generated with use of metaprogramming techniques
59
+ #
60
+ # @!method restart
61
+ # execute action +restart+ on the service
62
+ # @example restart a service
63
+ # my_postgresql_service.restart
64
+ # @note This method is generated with use of metaprogramming techniques
65
+ #
66
+ # @!method stop
67
+ # execute action +stop+ on the service
68
+ # @example stop a service
69
+ # my_postgresql_service.stop
70
+ # @note This method is generated with use of metaprogramming techniques
71
+ #
72
+ # @!method enable
73
+ # execute action +anable+ on the service
74
+ # @example enable a service
75
+ # my_postgresql_service.enable
76
+ # @note This method is generated with use of metaprogramming techniques
77
+ #
78
+ # @!method disable
79
+ # execute action +disable+ on the service
80
+ # @example disable a service
81
+ # my_postgresql_service.disable
82
+ # @note This method is generated with use of metaprogramming techniques
83
+ #
84
+ # @!method reload
85
+ # execute action +reload+ on the service
86
+ # @example reload a service
87
+ # my_postgresql_service.reload
88
+ # @note This method is generated with use of metaprogramming techniques
89
+ #
90
+ # @!method mask
91
+ # execute action +mask+ on the service
92
+ # @example mask a service
93
+ # my_postgresql_service.mask
94
+ # @note This method is generated with use of metaprogramming techniques
95
+ #
96
+ # @!method unmask
97
+ # execute action +unmask+ on the service
98
+ # @example unmask a service
99
+ # my_postgresql_service.unmask
100
+ # @note This method is generated with use of metaprogramming techniques
101
+ #
60
102
  LIST_OF_ACTIONS.each do |action|
61
103
  define_method action do
62
- sudo_command = Etc.getpwuid(Process.uid).name != 'root' ? 'sudo' : ''
63
- exist? ? `#{sudo_command} #{command} #{action} #{name}` : default_error_message()
104
+ sudo = Etc.getpwuid(Process.uid).name != 'root' ? 'sudo' : ''
105
+ exist? ? `#{sudo} #{command} #{action} #{name}` : default_error_message()
64
106
  end
65
107
  end
66
108
 
67
- # method for return a key/value pair of the provided service's properties
68
- # Example:
69
- # my_postgresql_service.properties
70
- # return a key/value pair of the provided service's properties
71
- # { "Type"=>"oneshot",
72
- # "Restart"=>"no",
73
- # "NotifyAccess"=>"none",
74
- # ....
75
- # }
109
+ # method for return a key/value pair of the service's properties
110
+ #
111
+ # @return [Hash] the service's properties
112
+ # @example display all the properties related to a service
113
+ #
114
+ # my_postgresql_service.properties
115
+ #
116
+ # {
117
+ # "Type"=>"oneshot",
118
+ # "Restart"=>"no",
119
+ # "ExecMainPID"=>"48615",
120
+ # "NotifyAccess"=>"none"
121
+ # }
122
+ #
123
+ # @note For the sake of brevity, all service-related properties are not shown in this example
76
124
  def properties
77
125
  array_of_properties = return_an_array_from_system_command(`#{command} show #{name}`)
78
126
  array_of_properties.collect { |property| { property.split('=')[0] => property.split('=')[1] } }.reduce({}, :merge)
79
127
  end
80
128
 
81
129
  # method for return the current status of the provided service
82
- # Example:
83
- # my_postgresql_service.status
84
- # return a key/value pair of the provided service's status
85
- # { "Id"=>"postgresql.service",
86
- # "Description"=>"PostgreSQL RDBMS",
87
- # "ExecMainPID"=>"48615",
88
- # "LoadState"=>"loaded",
89
- # "ActiveState"=>"active",
90
- # "FragmentPath"=>"/lib/Systemdy/system/postgresql.service",
91
- # "ActiveEnterTimestamp"=>"Thu 2022-09-29 17:13:07 CEST",
92
- # "InactiveEnterTimestamp"=>"Thu 2022-09-29 17:12:44 CEST",
93
- # "ActiveExitTimestamp"=>"Thu 2022-09-29 17:12:44 CEST",
94
- # "InactiveExitTimestamp"=>"Thu 2022-09-29 17:13:07 CEST"
95
- # }
130
+ #
131
+ # @return [Hash] the service's current status
132
+ # @example display the current status of the service
133
+ # my_postgresql_service.status
134
+ #
135
+ # {
136
+ # "Id"=>"postgresql.service",
137
+ # "Description"=>"PostgreSQL RDBMS",
138
+ # "ExecMainPID"=>"48615",
139
+ # "LoadState"=>"loaded",
140
+ # "ActiveState"=>"active",
141
+ # "FragmentPath"=>"/lib/Systemdy/system/postgresql.service",
142
+ # "ActiveEnterTimestamp"=>"Thu 2022-09-29 17:13:07 CEST",
143
+ # "InactiveEnterTimestamp"=>"Thu 2022-09-29 17:12:44 CEST",
144
+ # "ActiveExitTimestamp"=>"Thu 2022-09-29 17:12:44 CEST",
145
+ # "InactiveExitTimestamp"=>"Thu 2022-09-29 17:13:07 CEST"
146
+ # }
147
+ #
96
148
  def status
97
149
  exist? ? filter_by_keys(properties, LIST_OF_STATUS_PROPERTIES) : default_error_message()
98
150
  end
99
151
 
100
152
  # create dynamically methods based on LIST_OF_STATUSES constant
101
- # after created a new object we can call the methods:
102
- # my_postgresql_service.is_enabled?
103
- # my_postgresql_service.is_active?
104
- # if the provided service is active or enabled this method return
105
- # - true
106
- # otherwise return
107
- # - false
153
+ # @!method is_enabled?
154
+ # check if the service is +enabled+
155
+ # @return [Boolean] the service is enabled
156
+ # @example check if a service is enabled
157
+ # my_postgresql_service.is_enabled? #=> true
158
+ # @note This method is generated with use of metaprogramming techniques
159
+ #
160
+ # @!method is_active?
161
+ # check if the service is +active+
162
+ # @return [Boolean] the service is active
163
+ # @example check if a service is active
164
+ # my_postgresql_service.is_active? #=> true
165
+ # @note This method is generated with use of metaprogramming techniques
108
166
  LIST_OF_STATUSES.each do |status|
109
167
  define_method "is_#{status}?" do
110
168
  exist? ? return_an_array_from_system_command(`#{command} is-#{status} #{name}`).include?(status) : default_error_message()
111
169
  end
112
170
  end
113
171
 
114
- # method for display error when a service or unit not exist
172
+ # method to show a message when an action is performed on a service not installed on the system
173
+ # @return [String] the error message
174
+ # @example the action start on a service not installed on the system
175
+ # a_service_not_installed.start #=> "Unit a_service_not_installed.service could not be found."
115
176
  def default_error_message
116
177
  render_message("Unit #{name}.service could not be found.") # class method contained in Systemdy/utility/message_displayer.rb
117
178
  end
118
179
 
180
+ # @!method return_an_array_from_system_command
181
+ # @param system_call [String] system call to convert to an array
182
+ # @return [Array] an array-based list of the values ​​returned by making a system call
183
+ # @note check out more about this method in Systemdy/utility/formatter.rb
184
+ #
185
+ # @!method filter_by_keys
186
+ # @param hash [Hash] the hash to filter
187
+ # @param list_of_keys [Array] the list of keys to extract from the hash
188
+ # @return [Hash] a new hash that contains only the required keys
189
+ # @note check out more about this method in Systemdy/utility/key_value_filter.rb
190
+ #
191
+
119
192
  # make the methods below as private
120
193
  private :render_message, :default_error_message, :return_an_array_from_system_command, :filter_by_keys
121
194
  end
@@ -1,14 +1,19 @@
1
1
  module Systemdy
2
+ # A module that contains a set of useful classes for add utilities to the Systemdy's core
2
3
  module Utility
4
+ # Allows to formatting provided data into another type
3
5
  class Formatter
4
- # method for convert `` system call to array based list
6
+ # method for convert system calls into an array
7
+ #
8
+ # @param system_call [String] system call to convert to an array
9
+ # @return [Array] an array-based list of the values ​​returned by making a system call
10
+ # @example convert a backtick system call into an array
11
+ # list_of_files_in_my_folder = Systemdy::Utility::Formatter.return_an_array_from_system_command(`ls -la`)
12
+ # @todo execute system calls with backtick instead of system() beacuse system() return only true or false and not the expected value
5
13
  def self.return_an_array_from_system_command(system_call)
6
- # remove \n from system call returned value
7
- system_call_without_new_line = system_call.chomp!
8
- # return system error message
9
- return(system_call_without_new_line) if !$?.success?
10
- # convert `` system call to array based list
11
- system_call_without_new_line.split(/\n/)
14
+ system_call_without_new_line = system_call.chomp! # remove \n from system call returned value
15
+ return system_call_without_new_line if !$?.success? # return system error message if the process has non-zero exit status
16
+ system_call_without_new_line.split(/\n/) # convert values returned by `` system call to an array-based list
12
17
  end
13
18
  end
14
19
  end
@@ -1,9 +1,25 @@
1
1
  module Systemdy
2
+ # A module that contains a set of useful classes for add utilities to the Systemdy's core
2
3
  module Utility
4
+ # Allows to filter a key/value dataset
3
5
  class KeyValueFilter
4
- # method for filter an hash with a list of provided keys
6
+ # a method for filter an hash with a list of provided keys
7
+ #
8
+ # @param hash [Hash] the hash to filter
9
+ # @param list_of_keys [Array] the list of keys to extract from the hash
10
+ # @return [Hash] a new hash that contains only the required keys
11
+ # @example a very large hash to filter
12
+ # tasks = { task_one: 'learn ruby', task_two: 'learn rspec', task_three: 'create a good documentation', ... }
13
+ # @example hash filtered with provided keys
14
+ # filtered_hash = Systemdy::Utility::KeyValueFilter.filter_by_keys(tasks, 'task_one', 'task_two')
15
+ # #=> {"task_one"=>"learn ruby", "task_two"=>"learn rspec"}
5
16
  def self.filter_by_keys(hash, *list_of_keys)
6
- filtered_hash = hash.slice(*list_of_keys.flatten)
17
+ # convert all hash keys from :key to "key"
18
+ hash_keys_converted_into_string = Hash[hash.map{ |key, value| [key.to_s, value] }]
19
+ # convert array elements from ":key" to "key"
20
+ array_elements_converted_into_string = list_of_keys.flatten.map { |element| element.start_with?(':') ? element.gsub(':','') : element }
21
+ # return an hash with only provided keys
22
+ hash_keys_converted_into_string.slice(*array_elements_converted_into_string)
7
23
  end
8
24
  end
9
25
  end
@@ -1,9 +1,17 @@
1
1
  module Systemdy
2
+ # A module that contains a set of useful classes for add utilities to the Systemdy's core
2
3
  module Utility
4
+ # Allows to display messages to the user
3
5
  class MessageDisplayer
4
- # method for render custom message tho the user
6
+ # a method for render custom message to the user
7
+ #
8
+ # @param message [String] the message to render
9
+ # @return [String] the content of the message
10
+ # @example a custom message to show to the user
11
+ # custom_message = Systemdy::Utility::MessageDisplayer.render_message('my custom message')
12
+ # #=> "my custom message"
5
13
  def self.render_message(message)
6
- message
14
+ message # the content of the message
7
15
  end
8
16
  end
9
17
  end
@@ -1,12 +1,20 @@
1
1
  module Systemdy
2
+ # A module that contains a set of useful classes for add utilities to the Systemdy's core
2
3
  module Utility
4
+ # Allows to add validation to a class
3
5
  class Validator
4
- # method for check if a service exist
5
- def self.check_if_a_service_exist(service)
6
- `#{SYSTEMCTL_COMMAND} list-unit-files #{service}.service | wc -l`.to_i > 3
6
+ # a method for check if a service is intalled on the system
7
+ #
8
+ # @param name_of_the_service [String] the name of the service
9
+ # @return [Boolean] the presence of the service on the system
10
+ # @example check if a service is intalled on the system
11
+ # postgresql_service = Systemdy::Utility::Validator.check_if_a_service_exist('postgresql')
12
+ # #=> true
13
+ def self.check_if_a_service_exist(name_of_the_service)
14
+ `#{SYSTEMCTL_COMMAND} list-unit-files #{name_of_the_service}.service | wc -l`.to_i > 3
7
15
  # 'systemctl list-unit-files name_of_service.service | wc -l' command output:
8
- # 3 when there are not matching units
9
- # >3 when there are matching units
16
+ # 3 when there are not matching units(the service not exist because isn't installed on the system)
17
+ # >3 when there are matching units(the service exist because is installed on the system)
10
18
  end
11
19
  end
12
20
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Systemdy
4
- VERSION = "0.1.0"
4
+ # the current version of the gem
5
+ VERSION = "0.2.1"
5
6
  end
data/lib/systemdy.rb CHANGED
@@ -13,11 +13,13 @@ require_relative "systemdy/utility/key_value_filter"
13
13
  require_relative "systemdy/service"
14
14
  require_relative "systemdy/journal"
15
15
 
16
+ # Allow to control systemd's services and manage journalctl logs
16
17
  module Systemdy
18
+ # Allows to manange errors
17
19
  class Error < StandardError; end
18
20
 
19
- # systemctl command
21
+ # systemctl default command
20
22
  SYSTEMCTL_COMMAND = 'systemctl'
21
- # journalctl command
23
+ # journalctl default command
22
24
  JOURNALCTL_COMMAND = 'journalctl'
23
25
  end
data/systemdy.png ADDED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: systemdy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - magic4dev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-03 00:00:00.000000000 Z
11
+ date: 2022-10-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email: magic4dev@gmail.com
@@ -33,14 +33,16 @@ files:
33
33
  - lib/systemdy/utility/validator.rb
34
34
  - lib/systemdy/version.rb
35
35
  - sig/systemdy.rbs
36
- homepage: https://github.com/magic4dev/systemd
36
+ - systemdy.png
37
+ homepage: https://github.com/magic4dev/systemdy
37
38
  licenses:
38
39
  - MIT
39
40
  metadata:
40
- homepage_uri: https://github.com/magic4dev/systemd
41
- source_code_uri: https://github.com/magic4dev/systemd
42
- changelog_uri: https://github.com/magic4dev/systemd/blob/master/CHANGELOG.md
43
- code_of_conduct_uri: https://github.com/magic4dev/systemd/blob/master/CODE_OF_CONDUCT.md
41
+ homepage_uri: https://github.com/magic4dev/systemdy
42
+ source_code_uri: https://github.com/magic4dev/systemdy
43
+ documentation_uri: https://www.rubydoc.info/github/magic4dev/systemdy/master
44
+ changelog_uri: https://github.com/magic4dev/systemdy/blob/master/CHANGELOG.md
45
+ code_of_conduct_uri: https://github.com/magic4dev/systemdy/blob/master/CODE_OF_CONDUCT.md
44
46
  post_install_message:
45
47
  rdoc_options: []
46
48
  require_paths: